1'use strict'; 2 3 var ISPREVIEW = false; 4 /* Start variables_LABELS */ 5 var CONSENT_LABEL = 'Aktivierung erforderlich'; 6 var CONSENT_DESCRIPTION = 'Drittanbieter-Inhalte'; 7 var CONSENT_TEXT = 'Wir möchten Sie darauf hinweisen, dass nach der Aktivierung Daten an Drittanbieter übermittelt werden.'; 8 var CONSENT_BUTTON = 'Ich akzeptiere'; 9 10 /* Ende variables_LABELS */ 11 /* Start variables_IMG */ 12 var image_url_mejs_controls = 'https://www.bafin.de/SiteGlobals/Frontend/Images/icons/mediaelement/mejs-controls.svg?__blob=normal&v=1'; 13 var image_url_mejs_a11y_icons = 'https://www.bafin.de/SiteGlobals/Frontend/Images/icons/mediaelement/mejs-a11y-icons.svg?__blob=normal&v=1'; 14 15 /* Ende variables_IMG */ 16 17var json_url_sliderNavigation = 'https://www.bafin.de/DE/hidden_node.html?view=slidernavigation'; 18var hideSecondLevelPrimary = false; 19 20var cms = cms || {}; 21 22cms.jsComponents = { 23 config: {}, 24 definitions: { 25 bundle_animate_number: { 26 scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_animate_number.js?v=1' ] 27 }, 28 bundle_datatables: { 29 scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_datatables.js?v=1' ] 30 }, 31 bundle_multimedia: { 32 scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_multimedia.js?v=1' ] 33 }, 34 bundle_echarts: { 35 scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_echarts.js?v=1' ] 36 }, 37 bundle_slideshow: { 38 scriptList: [ 'https://www.bafin.de/SiteGlobals/Frontend/JavaScript/init/bundle_slideshow.js?v=1' ] 39 }, 40 } 41}; 42 /* Start jquery */ 43 /*! 44 * jQuery JavaScript Library v3.7.1 45 * https://jquery.com/ 46 * 47 * Copyright OpenJS Foundation and other contributors 48 * Released under the MIT license 49 * https://jquery.org/license 50 * 51 * Date: 2023-08-28T13:37Z 52 */"use strict"; 53(function (global, factory) { 54 55 "use strict"; 56 57 if (typeof module === "object" && typeof module.exports === "object") { 58 59 // For CommonJS and CommonJS-like environments where a proper `window` 60 // is present, execute the factory and get jQuery. 61 // For environments that do not have a `window` with a `document` 62 // (such as Node.js), expose a factory as module.exports. 63 // This accentuates the need for the creation of a real `window`. 64 // e.g. var jQuery = require("jquery")(window); 65 // See ticket trac-14549 for more info. 66 module.exports = global.document ? 67 factory(global, true) : 68 function (w) { 69 if (!w.document) { 70 throw new Error("jQuery requires a window with a document"); 71 } 72 return factory(w); 73 }; 74 } else { 75 factory(global); 76 } 77 78 // Pass this if window is not defined yet 79})(typeof window !== "undefined" ? window : void 0, function (window, noGlobal) { 80 81 // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 82 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 83 // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common 84 // enough that all such attempts are guarded in a try block. 85 "use strict"; 86 87 var arr = []; 88 89 var getProto = Object.getPrototypeOf; 90 91 var slice = arr.slice; 92 93 var flat = arr.flat ? function (array) { 94 return arr.flat.call(array); 95 } : function (array) { 96 return arr.concat.apply([], array); 97 }; 98 99 100 var push = arr.push; 101 102 var indexOf = arr.indexOf; 103 104 var class2type = {}; 105 106 var toString = class2type.toString; 107 108 var hasOwn = class2type.hasOwnProperty; 109 110 var fnToString = hasOwn.toString; 111 112 var ObjectFunctionString = fnToString.call(Object); 113 114 var support = {}; 115 116 var isFunction = function isFunction(obj) { 117 118 // Support: Chrome <=57, Firefox <=52 119 // In some browsers, typeof returns "function" for HTML <object> elements 120 // (i.e., `typeof document.createElement( "object" ) === "function"`). 121 // We don't want to classify *any* DOM node as a function.
vendor: 63,123 bytes, lines 122-2131
122 // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 123 // Plus for old WebKit, typeof returns "function" for HTML collections 124 // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) 125 return typeof obj === "function" && typeof obj.nodeType !== "number" && 126 typeof obj.item !== "function"; 127 }; 128 129 130 var isWindow = function isWindow(obj) { 131 return obj != null && obj === obj.window; 132 }; 133 134 135 var document = window.document; 136 137 138 139 var preservedScriptAttributes = { 140 type: true, 141 src: true, 142 nonce: true, 143 noModule: true 144 }; 145 146 function DOMEval(code, node, doc) { 147 doc = doc || document; 148 149 var i,val, 150 script = doc.createElement("script"); 151 152 script.text = code; 153 if (node) { 154 for (i in preservedScriptAttributes) { 155 156 // Support: Firefox 64+, Edge 18+ 157 // Some browsers don't support the "nonce" property on scripts. 158 // On the other hand, just using `getAttribute` is not enough as 159 // the `nonce` attribute is reset to an empty string whenever it 160 // becomes browsing-context connected. 161 // See https://github.com/whatwg/html/issues/2369 162 // See https://html.spec.whatwg.org/#nonce-attributes 163 // The `node.getAttribute` check was added for the sake of 164 // `jQuery.globalEval` so that it can fake a nonce-containing node 165 // via an object. 166 val = node[i] || node.getAttribute && node.getAttribute(i); 167 if (val) { 168 script.setAttribute(i, val); 169 } 170 } 171 } 172 doc.head.appendChild(script).parentNode.removeChild(script); 173 } 174 175 176 function toType(obj) { 177 if (obj == null) { 178 return obj + ""; 179 } 180 181 // Support: Android <=2.3 only (functionish RegExp) 182 return typeof obj === "object" || typeof obj === "function" ? 183 class2type[toString.call(obj)] || "object" : 184 typeof obj; 185 } 186 /* global Symbol */ 187 // Defining this global in .eslintrc.json would create a danger of using the global 188 // unguarded in another place, it seems safer to define global only for this module 189 190 191 192 var version = "3.7.1", 193 194 rhtmlSuffix = /HTML$/i, 195 196 // Define a local copy of jQuery 197 jQuery = function (selector, context) { 198 199 // The jQuery object is actually just the init constructor 'enhanced' 200 // Need init if jQuery is called (just allow error to be thrown if not included) 201 return new jQuery.fn.init(selector, context); 202 }; 203 204 jQuery.fn = jQuery.prototype = { 205 206 // The current version of jQuery being used 207 jquery: version, 208 209 constructor: jQuery, 210 211 // The default length of a jQuery object is 0 212 length: 0, 213 214 toArray: function () { 215 return slice.call(this); 216 }, 217 218 // Get the Nth element in the matched element set OR 219 // Get the whole matched element set as a clean array 220 get: function (num) { 221 222 // Return all the elements in a clean array 223 if (num == null) { 224 return slice.call(this); 225 } 226 227 // Return just the one element from the set 228 return num < 0 ? this[num + this.length] : this[num]; 229 }, 230 231 // Take an array of elements and push it onto the stack 232 // (returning the new matched element set) 233 pushStack: function (elems) { 234 235 // Build a new jQuery matched element set 236 var ret = jQuery.merge(this.constructor(), elems); 237 238 // Add the old object onto the stack (as a reference) 239 ret.prevObject = this; 240 241 // Return the newly-formed element set 242 return ret; 243 }, 244 245 // Execute a callback for every element in the matched set. 246 each: function (callback) { 247 return jQuery.each(this, callback); 248 }, 249 250 map: function (callback) { 251 return this.pushStack(jQuery.map(this, function (elem, i) { 252 return callback.call(elem, i, elem); 253 })); 254 }, 255 256 slice: function () { 257 return this.pushStack(slice.apply(this, arguments)); 258 }, 259 260 first: function () { 261 return this.eq(0); 262 }, 263 264 last: function () { 265 return this.eq(-1); 266 }, 267 268 even: function () { 269 return this.pushStack(jQuery.grep(this, function (_elem, i) { 270 return (i + 1) % 2; 271 })); 272 }, 273 274 odd: function () { 275 return this.pushStack(jQuery.grep(this, function (_elem, i) { 276 return i % 2; 277 })); 278 }, 279 280 eq: function (i) { 281 var len = this.length, 282 j = +i + (i < 0 ? len : 0); 283 return this.pushStack(j >= 0 && j < len ? [this[j]] : []); 284 }, 285 286 end: function () { 287 return this.prevObject || this.constructor(); 288 }, 289 290 // For internal use only. 291 // Behaves like an Array's method, not like a jQuery method. 292 push: push, 293 sort: arr.sort, 294 splice: arr.splice 295 }; 296 297 jQuery.extend = jQuery.fn.extend = function () { 298 var options,name,src,copy,copyIsArray,clone, 299 target = arguments[0] || {}, 300 i = 1, 301 length = arguments.length, 302 deep = false; 303 304 // Handle a deep copy situation 305 if (typeof target === "boolean") { 306 deep = target; 307 308 // Skip the boolean and the target 309 target = arguments[i] || {}; 310 i++; 311 } 312 313 // Handle case when target is a string or something (possible in deep copy) 314 if (typeof target !== "object" && !isFunction(target)) { 315 target = {}; 316 } 317 318 // Extend jQuery itself if only one argument is passed 319 if (i === length) { 320 target = this; 321 i--; 322 } 323 324 for (; i < length; i++) { 325 326 // Only deal with non-null/undefined values 327 if ((options = arguments[i]) != null) { 328 329 // Extend the base object 330 for (name in options) { 331 copy = options[name]; 332 333 // Prevent Object.prototype pollution 334 // Prevent never-ending loop 335 if (name === "__proto__" || target === copy) { 336 continue; 337 } 338 339 // Recurse if we're merging plain objects or arrays 340 if (deep && copy && (jQuery.isPlainObject(copy) || ( 341 copyIsArray = Array.isArray(copy)))) { 342 src = target[name]; 343 344 // Ensure proper type for the source value 345 if (copyIsArray && !Array.isArray(src)) { 346 clone = []; 347 } else if (!copyIsArray && !jQuery.isPlainObject(src)) { 348 clone = {}; 349 } else { 350 clone = src; 351 } 352 copyIsArray = false; 353 354 // Never move original objects, clone them 355 target[name] = jQuery.extend(deep, clone, copy); 356 357 // Don't bring in undefined values 358 } else if (copy !== undefined) { 359 target[name] = copy; 360 } 361 } 362 } 363 } 364 365 // Return the modified object 366 return target; 367 }; 368 369 jQuery.extend({ 370 371 // Unique for each copy of jQuery on the page 372 expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""), 373 374 // Assume jQuery is ready without the ready module 375 isReady: true, 376 377 error: function (msg) { 378 throw new Error(msg); 379 }, 380 381 noop: function () {}, 382 383 isPlainObject: function (obj) { 384 var proto, Ctor; 385 386 // Detect obvious negatives 387 // Use toString instead of jQuery.type to catch host objects 388 if (!obj || toString.call(obj) !== "[object Object]") { 389 return false; 390 } 391 392 proto = getProto(obj); 393 394 // Objects with no prototype (e.g., `Object.create( null )`) are plain 395 if (!proto) { 396 return true; 397 } 398 399 // Objects with prototype are plain iff they were constructed by a global Object function 400 Ctor = hasOwn.call(proto, "constructor") && proto.constructor; 401 return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString; 402 }, 403 404 isEmptyObject: function (obj) { 405 var name; 406 407 for (name in obj) { 408 return false; 409 } 410 return true; 411 }, 412 413 // Evaluates a script in a provided context; falls back to the global one 414 // if not specified. 415 globalEval: function (code, options, doc) { 416 DOMEval(code, { nonce: options && options.nonce }, doc); 417 }, 418 419 each: function (obj, callback) { 420 var length,i = 0; 421 422 if (isArrayLike(obj)) { 423 length = obj.length; 424 for (; i < length; i++) { 425 if (callback.call(obj[i], i, obj[i]) === false) { 426 break; 427 } 428 } 429 } else { 430 for (i in obj) { 431 if (callback.call(obj[i], i, obj[i]) === false) { 432 break; 433 } 434 } 435 } 436 437 return obj; 438 }, 439 440 441 // Retrieve the text value of an array of DOM nodes 442 text: function (elem) { 443 var node, 444 ret = "", 445 i = 0, 446 nodeType = elem.nodeType; 447 448 if (!nodeType) { 449 450 // If no nodeType, this is expected to be an array 451 while (node = elem[i++]) { 452 453 // Do not traverse comment nodes 454 ret += jQuery.text(node); 455 } 456 } 457 if (nodeType === 1 || nodeType === 11) { 458 return elem.textContent; 459 } 460 if (nodeType === 9) { 461 return elem.documentElement.textContent; 462 } 463 if (nodeType === 3 || nodeType === 4) { 464 return elem.nodeValue; 465 } 466 467 // Do not include comment or processing instruction nodes 468 469 return ret; 470 }, 471 472 // results is for internal usage only 473 makeArray: function (arr, results) { 474 var ret = results || []; 475 476 if (arr != null) { 477 if (isArrayLike(Object(arr))) { 478 jQuery.merge(ret, 479 typeof arr === "string" ? 480 [arr] : arr 481 ); 482 } else { 483 push.call(ret, arr); 484 } 485 } 486 487 return ret; 488 }, 489 490 inArray: function (elem, arr, i) { 491 return arr == null ? -1 : indexOf.call(arr, elem, i); 492 }, 493 494 isXMLDoc: function (elem) { 495 var namespace = elem && elem.namespaceURI, 496 docElem = elem && (elem.ownerDocument || elem).documentElement; 497 498 // Assume HTML when documentElement doesn't yet exist, such as inside 499 // document fragments. 500 return !rhtmlSuffix.test(namespace || docElem && docElem.nodeName || "HTML"); 501 }, 502 503 // Support: Android <=4.0 only, PhantomJS 1 only 504 // push.apply(_, arraylike) throws on ancient WebKit 505 merge: function (first, second) { 506 var len = +second.length, 507 j = 0, 508 i = first.length; 509 510 for (; j < len; j++) { 511 first[i++] = second[j]; 512 } 513 514 first.length = i; 515 516 return first; 517 }, 518 519 grep: function (elems, callback, invert) { 520 var callbackInverse, 521 matches = [], 522 i = 0, 523 length = elems.length, 524 callbackExpect = !invert; 525 526 // Go through the array, only saving the items 527 // that pass the validator function 528 for (; i < length; i++) { 529 callbackInverse = !callback(elems[i], i); 530 if (callbackInverse !== callbackExpect) { 531 matches.push(elems[i]); 532 } 533 } 534 535 return matches; 536 }, 537 538 // arg is for internal usage only 539 map: function (elems, callback, arg) { 540 var length,value, 541 i = 0, 542 ret = []; 543 544 // Go through the array, translating each of the items to their new values 545 if (isArrayLike(elems)) { 546 length = elems.length; 547 for (; i < length; i++) { 548 value = callback(elems[i], i, arg); 549 550 if (value != null) { 551 ret.push(value); 552 } 553 } 554 555 // Go through every key on the object, 556 } else { 557 for (i in elems) { 558 value = callback(elems[i], i, arg); 559 560 if (value != null) { 561 ret.push(value); 562 } 563 } 564 } 565 566 // Flatten any nested arrays 567 return flat(ret); 568 }, 569 570 // A global GUID counter for objects 571 guid: 1, 572 573 // jQuery.support is not used in Core but other projects attach their 574 // properties to it so it needs to exist. 575 support: support 576 }); 577 578 if (typeof Symbol === "function") { 579 jQuery.fn[Symbol.iterator] = arr[Symbol.iterator]; 580 } 581 582 // Populate the class2type map 583 jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), 584 function (_i, name) { 585 class2type["[object " + name + "]"] = name.toLowerCase(); 586 }); 587 588 function isArrayLike(obj) { 589 590 // Support: real iOS 8.2 only (not reproducible in simulator) 591 // `in` check used to prevent JIT error (gh-2145) 592 // hasOwn isn't used here due to false negatives 593 // regarding Nodelist length in IE 594 var length = !!obj && "length" in obj && obj.length, 595 type = toType(obj); 596 597 if (isFunction(obj) || isWindow(obj)) { 598 return false; 599 } 600 601 return type === "array" || length === 0 || 602 typeof length === "number" && length > 0 && length - 1 in obj; 603 } 604 605 606 function nodeName(elem, name) { 607 608 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 609 610 } 611 var pop = arr.pop; 612 613 614 var sort = arr.sort; 615 616 617 var splice = arr.splice; 618 619 620 var whitespace = "[\\x20\\t\\r\\n\\f]"; 621 622 623 var rtrimCSS = new RegExp( 624 "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", 625 "g" 626 ); 627 628 629 630 631 // Note: an element does not contain itself 632 jQuery.contains = function (a, b) { 633 var bup = b && b.parentNode; 634 635 return a === bup || !!(bup && bup.nodeType === 1 && ( 636 637 // Support: IE 9 - 11+ 638 // IE doesn't have `contains` on SVG. 639 a.contains ? 640 a.contains(bup) : 641 a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16)); 642 643 }; 644 645 646 647 648 // CSS string/identifier serialization 649 // https://drafts.csswg.org/cssom/#common-serializing-idioms 650 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 651 652 function fcssescape(ch, asCodePoint) { 653 if (asCodePoint) { 654 655 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 656 if (ch === "\0") { 657 return "\uFFFD"; 658 } 659 660 // Control characters and (dependent upon position) numbers get escaped as code points 661 return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " "; 662 } 663 664 // Other potentially-special ASCII characters get backslash-escaped 665 return "\\" + ch; 666 } 667 668 jQuery.escapeSelector = function (sel) { 669 return (sel + "").replace(rcssescape, fcssescape); 670 }; 671 672 673 674 675 var preferredDoc = document, 676 pushNative = push; 677 678 (function () { 679 680 var i, 681 Expr, 682 outermostContext, 683 sortInput, 684 hasDuplicate, 685 push = pushNative, 686 687 // Local document vars 688 document, 689 documentElement, 690 documentIsHTML, 691 rbuggyQSA, 692 matches, 693 694 // Instance-specific data 695 expando = jQuery.expando, 696 dirruns = 0, 697 done = 0, 698 classCache = createCache(), 699 tokenCache = createCache(), 700 compilerCache = createCache(), 701 nonnativeSelectorCache = createCache(), 702 sortOrder = function (a, b) { 703 if (a === b) { 704 hasDuplicate = true; 705 } 706 return 0; 707 }, 708 709 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" + 710 "loop|multiple|open|readonly|required|scoped", 711 712 // Regular expressions 713 714 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 715 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 716 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 717 718 // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors 719 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 720 721 // Operator (capture 2) 722 "*([*^$|!~]?=)" + whitespace + 723 724 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 725 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 726 whitespace + "*\\]", 727 728 pseudos = ":(" + identifier + ")(?:\\((" + 729 730 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 731 // 1. quoted (capture 3; capture 4 or capture 5) 732 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 733 734 // 2. simple (capture 6) 735 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 736 737 // 3. anything else (capture 2) 738 ".*" + 739 ")\\)|)", 740 741 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 742 rwhitespace = new RegExp(whitespace + "+", "g"), 743 744 rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"), 745 rleadingCombinator = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + 746 whitespace + "*"), 747 rdescend = new RegExp(whitespace + "|>"), 748 749 rpseudo = new RegExp(pseudos), 750 ridentifier = new RegExp("^" + identifier + "$"), 751 752 matchExpr = { 753 ID: new RegExp("^#(" + identifier + ")"), 754 CLASS: new RegExp("^\\.(" + identifier + ")"), 755 TAG: new RegExp("^(" + identifier + "|[*])"), 756 ATTR: new RegExp("^" + attributes), 757 PSEUDO: new RegExp("^" + pseudos), 758 CHILD: new RegExp( 759 "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 760 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 761 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"), 762 bool: new RegExp("^(?:" + booleans + ")$", "i"), 763 764 // For use in libraries implementing .is() 765 // We use this for POS matching in `select` 766 needsContext: new RegExp("^" + whitespace + 767 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 768 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i") 769 }, 770 771 rinputs = /^(?:input|select|textarea|button)$/i, 772 rheader = /^h\d$/i, 773 774 // Easily-parseable/retrievable ID or TAG or CLASS selectors 775 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 776 777 rsibling = /[+~]/, 778 779 // CSS escapes 780 // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters 781 runescape = new RegExp("\\\\[\\da-fA-F]{1,6}" + whitespace + 782 "?|\\\\([^\\r\\n\\f])", "g"), 783 funescape = function (escape, nonHex) { 784 var high = "0x" + escape.slice(1) - 0x10000; 785 786 if (nonHex) { 787 788 // Strip the backslash prefix from a non-hex escape sequence 789 return nonHex; 790 } 791 792 // Replace a hexadecimal escape sequence with the encoded Unicode code point 793 // Support: IE <=11+ 794 // For values outside the Basic Multilingual Plane (BMP), manually construct a 795 // surrogate pair 796 return high < 0 ? 797 String.fromCharCode(high + 0x10000) : 798 String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00); 799 }, 800 801 // Used for iframes; see `setDocument`. 802 // Support: IE 9 - 11+, Edge 12 - 18+ 803 // Removing the function wrapper causes a "Permission Denied" 804 // error in IE/Edge. 805 unloadHandler = function () { 806 setDocument(); 807 }, 808 809 inDisabledFieldset = addCombinator( 810 function (elem) { 811 return elem.disabled === true && nodeName(elem, "fieldset"); 812 }, 813 { dir: "parentNode", next: "legend" } 814 ); 815 816 // Support: IE <=9 only 817 // Accessing document.activeElement can throw unexpectedly 818 // https://bugs.jquery.com/ticket/13393 819 function safeActiveElement() { 820 try { 821 return document.activeElement; 822 } catch (err) {} 823 } 824 825 // Optimize for push.apply( _, NodeList ) 826 try { 827 push.apply( 828 arr = slice.call(preferredDoc.childNodes), 829 preferredDoc.childNodes 830 ); 831 832 // Support: Android <=4.0 833 // Detect silently failing push.apply 834 // eslint-disable-next-line no-unused-expressions 835 arr[preferredDoc.childNodes.length].nodeType; 836 } catch (e) { 837 push = { 838 apply: function (target, els) { 839 pushNative.apply(target, slice.call(els)); 840 }, 841 call: function (target) { 842 pushNative.apply(target, slice.call(arguments, 1)); 843 } 844 }; 845 } 846 847 function find(selector, context, results, seed) { 848 var m,i,elem,nid,match,groups,newSelector, 849 newContext = context && context.ownerDocument, 850 851 // nodeType defaults to 9, since context defaults to document 852 nodeType = context ? context.nodeType : 9; 853 854 results = results || []; 855 856 // Return early from calls with invalid selector or context 857 if (typeof selector !== "string" || !selector || 858 nodeType !== 1 && nodeType !== 9 && nodeType !== 11) { 859 860 return results; 861 } 862 863 // Try to shortcut find operations (as opposed to filters) in HTML documents 864 if (!seed) { 865 setDocument(context); 866 context = context || document; 867 868 if (documentIsHTML) { 869 870 // If the selector is sufficiently simple, try using a "get*By*" DOM method 871 // (excepting DocumentFragment context, where the methods don't exist) 872 if (nodeType !== 11 && (match = rquickExpr.exec(selector))) { 873 874 // ID selector 875 if (m = match[1]) { 876 877 // Document context 878 if (nodeType === 9) { 879 if (elem = context.getElementById(m)) { 880 881 // Support: IE 9 only 882 // getElementById can match elements by name instead of ID 883 if (elem.id === m) { 884 push.call(results, elem); 885 return results; 886 } 887 } else { 888 return results; 889 } 890 891 // Element context 892 } else { 893 894 // Support: IE 9 only 895 // getElementById can match elements by name instead of ID 896 if (newContext && (elem = newContext.getElementById(m)) && 897 find.contains(context, elem) && 898 elem.id === m) { 899 900 push.call(results, elem); 901 return results; 902 } 903 } 904 905 // Type selector 906 } else if (match[2]) { 907 push.apply(results, context.getElementsByTagName(selector)); 908 return results; 909 910 // Class selector 911 } else if ((m = match[3]) && context.getElementsByClassName) { 912 push.apply(results, context.getElementsByClassName(m)); 913 return results; 914 } 915 } 916 917 // Take advantage of querySelectorAll 918 if (!nonnativeSelectorCache[selector + " "] && ( 919 !rbuggyQSA || !rbuggyQSA.test(selector))) { 920 921 newSelector = selector; 922 newContext = context; 923 924 // qSA considers elements outside a scoping root when evaluating child or 925 // descendant combinators, which is not what we want. 926 // In such cases, we work around the behavior by prefixing every selector in the 927 // list with an ID selector referencing the scope context. 928 // The technique has to be used as well when a leading combinator is used 929 // as such selectors are not recognized by querySelectorAll. 930 // Thanks to Andrew Dupont for this technique. 931 if (nodeType === 1 && ( 932 rdescend.test(selector) || rleadingCombinator.test(selector))) { 933 934 // Expand context for sibling selectors 935 newContext = rsibling.test(selector) && testContext(context.parentNode) || 936 context; 937 938 // We can use :scope instead of the ID hack if the browser 939 // supports it & if we're not changing the context. 940 // Support: IE 11+, Edge 17 - 18+ 941 // IE/Edge sometimes throw a "Permission denied" error when 942 // strict-comparing two documents; shallow comparisons work. 943 // eslint-disable-next-line eqeqeq 944 if (newContext != context || !support.scope) { 945 946 // Capture the context ID, setting it first if necessary 947 if (nid = context.getAttribute("id")) { 948 nid = jQuery.escapeSelector(nid); 949 } else { 950 context.setAttribute("id", nid = expando); 951 } 952 } 953 954 // Prefix every selector in the list 955 groups = tokenize(selector); 956 i = groups.length; 957 while (i--) { 958 groups[i] = (nid ? "#" + nid : ":scope") + " " + 959 toSelector(groups[i]); 960 } 961 newSelector = groups.join(","); 962 } 963 964 try { 965 push.apply(results, 966 newContext.querySelectorAll(newSelector) 967 ); 968 return results; 969 } catch (qsaError) { 970 nonnativeSelectorCache(selector, true); 971 } finally { 972 if (nid === expando) { 973 context.removeAttribute("id"); 974 } 975 } 976 } 977 } 978 } 979 980 // All others 981 return select(selector.replace(rtrimCSS, "$1"), context, results, seed); 982 } 983 984 /** 985 * Create key-value caches of limited size 986 * @returns {function(string, object)} Returns the Object data after storing it on itself with 987 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 988 * deleting the oldest entry 989 */ 990 function createCache() { 991 var keys = []; 992 993 function cache(key, value) { 994 995 // Use (key + " ") to avoid collision with native prototype properties 996 // (see https://github.com/jquery/sizzle/issues/157) 997 if (keys.push(key + " ") > Expr.cacheLength) { 998 999 // Only keep the most recent entries 1000 delete cache[keys.shift()]; 1001 } 1002 return cache[key + " "] = value; 1003 } 1004 return cache; 1005 } 1006 1007 /** 1008 * Mark a function for special use by jQuery selector module 1009 * @param {Function} fn The function to mark 1010 */ 1011 function markFunction(fn) { 1012 fn[expando] = true; 1013 return fn; 1014 } 1015 1016 /** 1017 * Support testing using an element 1018 * @param {Function} fn Passed the created element and returns a boolean result 1019 */ 1020 function assert(fn) { 1021 var el = document.createElement("fieldset"); 1022 1023 try { 1024 return !!fn(el); 1025 } catch (e) { 1026 return false; 1027 } finally { 1028 1029 // Remove from its parent by default 1030 if (el.parentNode) { 1031 el.parentNode.removeChild(el); 1032 } 1033 1034 // release memory in IE 1035 el = null; 1036 } 1037 } 1038 1039 /** 1040 * Returns a function to use in pseudos for input types 1041 * @param {String} type 1042 */ 1043 function createInputPseudo(type) { 1044 return function (elem) { 1045 return nodeName(elem, "input") && elem.type === type; 1046 }; 1047 } 1048 1049 /** 1050 * Returns a function to use in pseudos for buttons 1051 * @param {String} type 1052 */ 1053 function createButtonPseudo(type) { 1054 return function (elem) { 1055 return (nodeName(elem, "input") || nodeName(elem, "button")) && 1056 elem.type === type; 1057 }; 1058 } 1059 1060 /** 1061 * Returns a function to use in pseudos for :enabled/:disabled 1062 * @param {Boolean} disabled true for :disabled; false for :enabled 1063 */ 1064 function createDisabledPseudo(disabled) { 1065 1066 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 1067 return function (elem) { 1068 1069 // Only certain elements can match :enabled or :disabled 1070 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 1071 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 1072 if ("form" in elem) { 1073 1074 // Check for inherited disabledness on relevant non-disabled elements: 1075 // * listed form-associated elements in a disabled fieldset 1076 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 1077 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 1078 // * option elements in a disabled optgroup 1079 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 1080 // All such elements have a "form" property. 1081 if (elem.parentNode && elem.disabled === false) { 1082 1083 // Option elements defer to a parent optgroup if present 1084 if ("label" in elem) { 1085 if ("label" in elem.parentNode) { 1086 return elem.parentNode.disabled === disabled; 1087 } else { 1088 return elem.disabled === disabled; 1089 } 1090 } 1091 1092 // Support: IE 6 - 11+ 1093 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 1094 return elem.isDisabled === disabled || 1095 1096 // Where there is no isDisabled, check manually 1097 elem.isDisabled !== !disabled && 1098 inDisabledFieldset(elem) === disabled; 1099 } 1100 1101 return elem.disabled === disabled; 1102 1103 // Try to winnow out elements that can't be disabled before trusting the disabled property. 1104 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 1105 // even exist on them, let alone have a boolean value. 1106 } else if ("label" in elem) { 1107 return elem.disabled === disabled; 1108 } 1109 1110 // Remaining elements are neither :enabled nor :disabled 1111 return false; 1112 }; 1113 } 1114 1115 /** 1116 * Returns a function to use in pseudos for positionals 1117 * @param {Function} fn 1118 */ 1119 function createPositionalPseudo(fn) { 1120 return markFunction(function (argument) { 1121 argument = +argument; 1122 return markFunction(function (seed, matches) { 1123 var j, 1124 matchIndexes = fn([], seed.length, argument), 1125 i = matchIndexes.length; 1126 1127 // Match elements found at the specified indexes 1128 while (i--) { 1129 if (seed[j = matchIndexes[i]]) { 1130 seed[j] = !(matches[j] = seed[j]); 1131 } 1132 } 1133 }); 1134 }); 1135 } 1136 1137 /** 1138 * Checks a node for validity as a jQuery selector context 1139 * @param {Element|Object=} context 1140 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 1141 */ 1142 function testContext(context) { 1143 return context && typeof context.getElementsByTagName !== "undefined" && context; 1144 } 1145 1146 /** 1147 * Sets document-related variables once based on the current document 1148 * @param {Element|Object} [node] An element or document object to use to set the document 1149 * @returns {Object} Returns the current document 1150 */ 1151 function setDocument(node) { 1152 var subWindow, 1153 doc = node ? node.ownerDocument || node : preferredDoc; 1154 1155 // Return early if doc is invalid or already selected 1156 // Support: IE 11+, Edge 17 - 18+ 1157 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1158 // two documents; shallow comparisons work. 1159 // eslint-disable-next-line eqeqeq 1160 if (doc == document || doc.nodeType !== 9 || !doc.documentElement) { 1161 return document; 1162 } 1163 1164 // Update global variables 1165 document = doc; 1166 documentElement = document.documentElement; 1167 documentIsHTML = !jQuery.isXMLDoc(document); 1168 1169 // Support: iOS 7 only, IE 9 - 11+ 1170 // Older browsers didn't support unprefixed `matches`. 1171 matches = documentElement.matches || 1172 documentElement.webkitMatchesSelector || 1173 documentElement.msMatchesSelector; 1174 1175 // Support: IE 9 - 11+, Edge 12 - 18+ 1176 // Accessing iframe documents after unload throws "permission denied" errors 1177 // (see trac-13936). 1178 // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`, 1179 // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well. 1180 if (documentElement.msMatchesSelector && 1181 1182 // Support: IE 11+, Edge 17 - 18+ 1183 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1184 // two documents; shallow comparisons work. 1185 // eslint-disable-next-line eqeqeq 1186 preferredDoc != document && ( 1187 subWindow = document.defaultView) && subWindow.top !== subWindow) { 1188 1189 // Support: IE 9 - 11+, Edge 12 - 18+ 1190 subWindow.addEventListener("unload", unloadHandler); 1191 } 1192 1193 // Support: IE <10 1194 // Check if getElementById returns elements by name 1195 // The broken getElementById methods don't pick up programmatically-set names, 1196 // so use a roundabout getElementsByName test 1197 support.getById = assert(function (el) { 1198 documentElement.appendChild(el).id = jQuery.expando; 1199 return !document.getElementsByName || 1200 !document.getElementsByName(jQuery.expando).length; 1201 }); 1202 1203 // Support: IE 9 only 1204 // Check to see if it's possible to do matchesSelector 1205 // on a disconnected node. 1206 support.disconnectedMatch = assert(function (el) { 1207 return matches.call(el, "*"); 1208 }); 1209 1210 // Support: IE 9 - 11+, Edge 12 - 18+ 1211 // IE/Edge don't support the :scope pseudo-class. 1212 support.scope = assert(function () { 1213 return document.querySelectorAll(":scope"); 1214 }); 1215 1216 // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only 1217 // Make sure the `:has()` argument is parsed unforgivingly. 1218 // We include `*` in the test to detect buggy implementations that are 1219 // _selectively_ forgiving (specifically when the list includes at least 1220 // one valid selector). 1221 // Note that we treat complete lack of support for `:has()` as if it were 1222 // spec-compliant support, which is fine because use of `:has()` in such 1223 // environments will fail in the qSA path and fall back to jQuery traversal 1224 // anyway. 1225 support.cssHas = assert(function () { 1226 try { 1227 document.querySelector(":has(*,:jqfake)"); 1228 return false; 1229 } catch (e) { 1230 return true; 1231 } 1232 }); 1233 1234 // ID filter and find 1235 if (support.getById) { 1236 Expr.filter.ID = function (id) { 1237 var attrId = id.replace(runescape, funescape); 1238 return function (elem) { 1239 return elem.getAttribute("id") === attrId; 1240 }; 1241 }; 1242 Expr.find.ID = function (id, context) { 1243 if (typeof context.getElementById !== "undefined" && documentIsHTML) { 1244 var elem = context.getElementById(id); 1245 return elem ? [elem] : []; 1246 } 1247 }; 1248 } else { 1249 Expr.filter.ID = function (id) { 1250 var attrId = id.replace(runescape, funescape); 1251 return function (elem) { 1252 var node = typeof elem.getAttributeNode !== "undefined" && 1253 elem.getAttributeNode("id"); 1254 return node && node.value === attrId; 1255 }; 1256 }; 1257 1258 // Support: IE 6 - 7 only 1259 // getElementById is not reliable as a find shortcut 1260 Expr.find.ID = function (id, context) { 1261 if (typeof context.getElementById !== "undefined" && documentIsHTML) { 1262 var node,i,elems, 1263 elem = context.getElementById(id); 1264 1265 if (elem) { 1266 1267 // Verify the id attribute 1268 node = elem.getAttributeNode("id"); 1269 if (node && node.value === id) { 1270 return [elem]; 1271 } 1272 1273 // Fall back on getElementsByName 1274 elems = context.getElementsByName(id); 1275 i = 0; 1276 while (elem = elems[i++]) { 1277 node = elem.getAttributeNode("id"); 1278 if (node && node.value === id) { 1279 return [elem]; 1280 } 1281 } 1282 } 1283 1284 return []; 1285 } 1286 }; 1287 } 1288 1289 // Tag 1290 Expr.find.TAG = function (tag, context) { 1291 if (typeof context.getElementsByTagName !== "undefined") { 1292 return context.getElementsByTagName(tag); 1293 1294 // DocumentFragment nodes don't have gEBTN 1295 } else { 1296 return context.querySelectorAll(tag); 1297 } 1298 }; 1299 1300 // Class 1301 Expr.find.CLASS = function (className, context) { 1302 if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) { 1303 return context.getElementsByClassName(className); 1304 } 1305 }; 1306 1307 /* QSA/matchesSelector 1308 ---------------------------------------------------------------------- */ 1309 1310 // QSA and matchesSelector support 1311 1312 rbuggyQSA = []; 1313 1314 // Build QSA regex 1315 // Regex strategy adopted from Diego Perini 1316 assert(function (el) { 1317 1318 var input; 1319 1320 documentElement.appendChild(el).innerHTML = 1321 "<a id='" + expando + "' href='' disabled='disabled'></a>" + 1322 "<select id='" + expando + "-\r\\' disabled='disabled'>" + 1323 "<option selected=''></option></select>"; 1324 1325 // Support: iOS <=7 - 8 only 1326 // Boolean attributes and "value" are not treated correctly in some XML documents 1327 if (!el.querySelectorAll("[selected]").length) { 1328 rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")"); 1329 } 1330 1331 // Support: iOS <=7 - 8 only 1332 if (!el.querySelectorAll("[id~=" + expando + "-]").length) { 1333 rbuggyQSA.push("~="); 1334 } 1335 1336 // Support: iOS 8 only 1337 // https://bugs.webkit.org/show_bug.cgi?id=136851 1338 // In-page `selector#id sibling-combinator selector` fails 1339 if (!el.querySelectorAll("a#" + expando + "+*").length) { 1340 rbuggyQSA.push(".#.+[+~]"); 1341 } 1342 1343 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 1344 // In some of the document kinds, these selectors wouldn't work natively. 1345 // This is probably OK but for backwards compatibility we want to maintain 1346 // handling them through jQuery traversal in jQuery 3.x. 1347 if (!el.querySelectorAll(":checked").length) { 1348 rbuggyQSA.push(":checked"); 1349 } 1350 1351 // Support: Windows 8 Native Apps 1352 // The type and name attributes are restricted during .innerHTML assignment 1353 input = document.createElement("input"); 1354 input.setAttribute("type", "hidden"); 1355 el.appendChild(input).setAttribute("name", "D"); 1356 1357 // Support: IE 9 - 11+ 1358 // IE's :disabled selector does not pick up the children of disabled fieldsets 1359 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 1360 // In some of the document kinds, these selectors wouldn't work natively. 1361 // This is probably OK but for backwards compatibility we want to maintain 1362 // handling them through jQuery traversal in jQuery 3.x. 1363 documentElement.appendChild(el).disabled = true; 1364 if (el.querySelectorAll(":disabled").length !== 2) { 1365 rbuggyQSA.push(":enabled", ":disabled"); 1366 } 1367 1368 // Support: IE 11+, Edge 15 - 18+ 1369 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 1370 // Adding a temporary attribute to the document before the selection works 1371 // around the issue. 1372 // Interestingly, IE 10 & older don't seem to have the issue. 1373 input = document.createElement("input"); 1374 input.setAttribute("name", ""); 1375 el.appendChild(input); 1376 if (!el.querySelectorAll("[name='']").length) { 1377 rbuggyQSA.push("\\[" + whitespace + "*name" + whitespace + "*=" + 1378 whitespace + "*(?:''|\"\")"); 1379 } 1380 }); 1381 1382 if (!support.cssHas) { 1383 1384 // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ 1385 // Our regular `try-catch` mechanism fails to detect natively-unsupported 1386 // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) 1387 // in browsers that parse the `:has()` argument as a forgiving selector list. 1388 // https://drafts.csswg.org/selectors/#relational now requires the argument 1389 // to be parsed unforgivingly, but browsers have not yet fully adjusted. 1390 rbuggyQSA.push(":has"); 1391 } 1392 1393 rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|")); 1394 1395 /* Sorting 1396 ---------------------------------------------------------------------- */ 1397 1398 // Document order sorting 1399 sortOrder = function (a, b) { 1400 1401 // Flag for duplicate removal 1402 if (a === b) { 1403 hasDuplicate = true; 1404 return 0; 1405 } 1406 1407 // Sort on method existence if only one input has compareDocumentPosition 1408 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 1409 if (compare) { 1410 return compare; 1411 } 1412 1413 // Calculate position if both inputs belong to the same document 1414 // Support: IE 11+, Edge 17 - 18+ 1415 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1416 // two documents; shallow comparisons work. 1417 // eslint-disable-next-line eqeqeq 1418 compare = (a.ownerDocument || a) == (b.ownerDocument || b) ? 1419 a.compareDocumentPosition(b) : 1420 1421 // Otherwise we know they are disconnected 1422 1; 1423 1424 // Disconnected nodes 1425 if (compare & 1 || 1426 !support.sortDetached && b.compareDocumentPosition(a) === compare) { 1427 1428 // Choose the first element that is related to our preferred document 1429 // Support: IE 11+, Edge 17 - 18+ 1430 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1431 // two documents; shallow comparisons work. 1432 // eslint-disable-next-line eqeqeq 1433 if (a === document || a.ownerDocument == preferredDoc && 1434 find.contains(preferredDoc, a)) { 1435 return -1; 1436 } 1437 1438 // Support: IE 11+, Edge 17 - 18+ 1439 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1440 // two documents; shallow comparisons work. 1441 // eslint-disable-next-line eqeqeq 1442 if (b === document || b.ownerDocument == preferredDoc && 1443 find.contains(preferredDoc, b)) { 1444 return 1; 1445 } 1446 1447 // Maintain original order 1448 return sortInput ? 1449 indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 1450 0; 1451 } 1452 1453 return compare & 4 ? -1 : 1; 1454 }; 1455 1456 return document; 1457 } 1458 1459 find.matches = function (expr, elements) { 1460 return find(expr, null, null, elements); 1461 }; 1462 1463 find.matchesSelector = function (elem, expr) { 1464 setDocument(elem); 1465 1466 if (documentIsHTML && 1467 !nonnativeSelectorCache[expr + " "] && ( 1468 !rbuggyQSA || !rbuggyQSA.test(expr))) { 1469 1470 try { 1471 var ret = matches.call(elem, expr); 1472 1473 // IE 9's matchesSelector returns false on disconnected nodes 1474 if (ret || support.disconnectedMatch || 1475 1476 // As well, disconnected nodes are said to be in a document 1477 // fragment in IE 9 1478 elem.document && elem.document.nodeType !== 11) { 1479 return ret; 1480 } 1481 } catch (e) { 1482 nonnativeSelectorCache(expr, true); 1483 } 1484 } 1485 1486 return find(expr, document, null, [elem]).length > 0; 1487 }; 1488 1489 find.contains = function (context, elem) { 1490 1491 // Set document vars if needed 1492 // Support: IE 11+, Edge 17 - 18+ 1493 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1494 // two documents; shallow comparisons work. 1495 // eslint-disable-next-line eqeqeq 1496 if ((context.ownerDocument || context) != document) { 1497 setDocument(context); 1498 } 1499 return jQuery.contains(context, elem); 1500 }; 1501 1502 1503 find.attr = function (elem, name) { 1504 1505 // Set document vars if needed 1506 // Support: IE 11+, Edge 17 - 18+ 1507 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1508 // two documents; shallow comparisons work. 1509 // eslint-disable-next-line eqeqeq 1510 if ((elem.ownerDocument || elem) != document) { 1511 setDocument(elem); 1512 } 1513 1514 var fn = Expr.attrHandle[name.toLowerCase()], 1515 1516 // Don't get fooled by Object.prototype properties (see trac-13807) 1517 val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? 1518 fn(elem, name, !documentIsHTML) : 1519 undefined; 1520 1521 if (val !== undefined) { 1522 return val; 1523 } 1524 1525 return elem.getAttribute(name); 1526 }; 1527 1528 find.error = function (msg) { 1529 throw new Error("Syntax error, unrecognized expression: " + msg); 1530 }; 1531 1532 /** 1533 * Document sorting and removing duplicates 1534 * @param {ArrayLike} results 1535 */ 1536 jQuery.uniqueSort = function (results) { 1537 var elem, 1538 duplicates = [], 1539 j = 0, 1540 i = 0; 1541 1542 // Unless we *know* we can detect duplicates, assume their presence 1543 // 1544 // Support: Android <=4.0+ 1545 // Testing for detecting duplicates is unpredictable so instead assume we can't 1546 // depend on duplicate detection in all browsers without a stable sort. 1547 hasDuplicate = !support.sortStable; 1548 sortInput = !support.sortStable && slice.call(results, 0); 1549 sort.call(results, sortOrder); 1550 1551 if (hasDuplicate) { 1552 while (elem = results[i++]) { 1553 if (elem === results[i]) { 1554 j = duplicates.push(i); 1555 } 1556 } 1557 while (j--) { 1558 splice.call(results, duplicates[j], 1); 1559 } 1560 } 1561 1562 // Clear input after sorting to release objects 1563 // See https://github.com/jquery/sizzle/pull/225 1564 sortInput = null; 1565 1566 return results; 1567 }; 1568 1569 jQuery.fn.uniqueSort = function () { 1570 return this.pushStack(jQuery.uniqueSort(slice.apply(this))); 1571 }; 1572 1573 Expr = jQuery.expr = { 1574 1575 // Can be adjusted by the user 1576 cacheLength: 50, 1577 1578 createPseudo: markFunction, 1579 1580 match: matchExpr, 1581 1582 attrHandle: {}, 1583 1584 find: {}, 1585 1586 relative: { 1587 ">": { dir: "parentNode", first: true }, 1588 " ": { dir: "parentNode" }, 1589 "+": { dir: "previousSibling", first: true }, 1590 "~": { dir: "previousSibling" } 1591 }, 1592 1593 preFilter: { 1594 ATTR: function (match) { 1595 match[1] = match[1].replace(runescape, funescape); 1596 1597 // Move the given value to match[3] whether quoted or unquoted 1598 match[3] = (match[3] || match[4] || match[5] || ""). 1599 replace(runescape, funescape); 1600 1601 if (match[2] === "~=") { 1602 match[3] = " " + match[3] + " "; 1603 } 1604 1605 return match.slice(0, 4); 1606 }, 1607 1608 CHILD: function (match) { 1609 1610 /* matches from matchExpr["CHILD"] 1611 1 type (only|nth|...) 1612 2 what (child|of-type) 1613 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 1614 4 xn-component of xn+y argument ([+-]?\d*n|) 1615 5 sign of xn-component 1616 6 x of xn-component 1617 7 sign of y-component 1618 8 y of y-component 1619 */ 1620 match[1] = match[1].toLowerCase(); 1621 1622 if (match[1].slice(0, 3) === "nth") { 1623 1624 // nth-* requires argument 1625 if (!match[3]) { 1626 find.error(match[0]); 1627 } 1628 1629 // numeric x and y parameters for Expr.filter.CHILD 1630 // remember that false/true cast respectively to 0/1 1631 match[4] = +(match[4] ? 1632 match[5] + (match[6] || 1) : 1633 2 * (match[3] === "even" || match[3] === "odd")); 1634 1635 match[5] = +(match[7] + match[8] || match[3] === "odd"); 1636 1637 // other types prohibit arguments 1638 } else if (match[3]) { 1639 find.error(match[0]); 1640 } 1641 1642 return match; 1643 }, 1644 1645 PSEUDO: function (match) { 1646 var excess, 1647 unquoted = !match[6] && match[2]; 1648 1649 if (matchExpr.CHILD.test(match[0])) { 1650 return null; 1651 } 1652 1653 // Accept quoted arguments as-is 1654 if (match[3]) { 1655 match[2] = match[4] || match[5] || ""; 1656 1657 // Strip excess characters from unquoted arguments 1658 } else if (unquoted && rpseudo.test(unquoted) && ( 1659 1660 // Get excess from tokenize (recursively) 1661 excess = tokenize(unquoted, true)) && ( 1662 1663 // advance to the next closing parenthesis 1664 excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) { 1665 1666 // excess is a negative index 1667 match[0] = match[0].slice(0, excess); 1668 match[2] = unquoted.slice(0, excess); 1669 } 1670 1671 // Return only captures needed by the pseudo filter method (type and argument) 1672 return match.slice(0, 3); 1673 } 1674 }, 1675 1676 filter: { 1677 1678 TAG: function (nodeNameSelector) { 1679 var expectedNodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); 1680 return nodeNameSelector === "*" ? 1681 function () { 1682 return true; 1683 } : 1684 function (elem) { 1685 return nodeName(elem, expectedNodeName); 1686 }; 1687 }, 1688 1689 CLASS: function (className) { 1690 var pattern = classCache[className + " "]; 1691 1692 return pattern || 1693 (pattern = new RegExp("(^|" + whitespace + ")" + className + 1694 "(" + whitespace + "|$)")) && 1695 classCache(className, function (elem) { 1696 return pattern.test( 1697 typeof elem.className === "string" && elem.className || 1698 typeof elem.getAttribute !== "undefined" && 1699 elem.getAttribute("class") || 1700 "" 1701 ); 1702 }); 1703 }, 1704 1705 ATTR: function (name, operator, check) { 1706 return function (elem) { 1707 var result = find.attr(elem, name); 1708 1709 if (result == null) { 1710 return operator === "!="; 1711 } 1712 if (!operator) { 1713 return true; 1714 } 1715 1716 result += ""; 1717 1718 if (operator === "=") { 1719 return result === check; 1720 } 1721 if (operator === "!=") { 1722 return result !== check; 1723 } 1724 if (operator === "^=") { 1725 return check && result.indexOf(check) === 0; 1726 } 1727 if (operator === "*=") { 1728 return check && result.indexOf(check) > -1; 1729 } 1730 if (operator === "$=") { 1731 return check && result.slice(-check.length) === check; 1732 } 1733 if (operator === "~=") { 1734 return (" " + result.replace(rwhitespace, " ") + " "). 1735 indexOf(check) > -1; 1736 } 1737 if (operator === "|=") { 1738 return result === check || result.slice(0, check.length + 1) === check + "-"; 1739 } 1740 1741 return false; 1742 }; 1743 }, 1744 1745 CHILD: function (type, what, _argument, first, last) { 1746 var simple = type.slice(0, 3) !== "nth", 1747 forward = type.slice(-4) !== "last", 1748 ofType = what === "of-type"; 1749 1750 return first === 1 && last === 0 ? 1751 1752 // Shortcut for :nth-*(n) 1753 function (elem) { 1754 return !!elem.parentNode; 1755 } : 1756 1757 function (elem, _context, xml) { 1758 var cache,outerCache,node,nodeIndex,start, 1759 dir = simple !== forward ? "nextSibling" : "previousSibling", 1760 parent = elem.parentNode, 1761 name = ofType && elem.nodeName.toLowerCase(), 1762 useCache = !xml && !ofType, 1763 diff = false; 1764 1765 if (parent) { 1766 1767 // :(first|last|only)-(child|of-type) 1768 if (simple) { 1769 while (dir) { 1770 node = elem; 1771 while (node = node[dir]) { 1772 if (ofType ? 1773 nodeName(node, name) : 1774 node.nodeType === 1) { 1775 1776 return false; 1777 } 1778 } 1779 1780 // Reverse direction for :only-* (if we haven't yet done so) 1781 start = dir = type === "only" && !start && "nextSibling"; 1782 } 1783 return true; 1784 } 1785 1786 start = [forward ? parent.firstChild : parent.lastChild]; 1787 1788 // non-xml :nth-child(...) stores cache data on `parent` 1789 if (forward && useCache) { 1790 1791 // Seek `elem` from a previously-cached index 1792 outerCache = parent[expando] || (parent[expando] = {}); 1793 cache = outerCache[type] || []; 1794 nodeIndex = cache[0] === dirruns && cache[1]; 1795 diff = nodeIndex && cache[2]; 1796 node = nodeIndex && parent.childNodes[nodeIndex]; 1797 1798 while (node = ++nodeIndex && node && node[dir] || ( 1799 1800 // Fallback to seeking `elem` from the start 1801 diff = nodeIndex = 0) || start.pop()) { 1802 1803 // When found, cache indexes on `parent` and break 1804 if (node.nodeType === 1 && ++diff && node === elem) { 1805 outerCache[type] = [dirruns, nodeIndex, diff]; 1806 break; 1807 } 1808 } 1809 1810 } else { 1811 1812 // Use previously-cached element index if available 1813 if (useCache) { 1814 outerCache = elem[expando] || (elem[expando] = {}); 1815 cache = outerCache[type] || []; 1816 nodeIndex = cache[0] === dirruns && cache[1]; 1817 diff = nodeIndex; 1818 } 1819 1820 // xml :nth-child(...) 1821 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 1822 if (diff === false) { 1823 1824 // Use the same loop as above to seek `elem` from the start 1825 while (node = ++nodeIndex && node && node[dir] || ( 1826 diff = nodeIndex = 0) || start.pop()) { 1827 1828 if ((ofType ? 1829 nodeName(node, name) : 1830 node.nodeType === 1) && 1831 ++diff) { 1832 1833 // Cache the index of each encountered element 1834 if (useCache) { 1835 outerCache = node[expando] || ( 1836 node[expando] = {}); 1837 outerCache[type] = [dirruns, diff]; 1838 } 1839 1840 if (node === elem) { 1841 break; 1842 } 1843 } 1844 } 1845 } 1846 } 1847 1848 // Incorporate the offset, then check against cycle size 1849 diff -= last; 1850 return diff === first || diff % first === 0 && diff / first >= 0; 1851 } 1852 }; 1853 }, 1854 1855 PSEUDO: function (pseudo, argument) { 1856 1857 // pseudo-class names are case-insensitive 1858 // https://www.w3.org/TR/selectors/#pseudo-classes 1859 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 1860 // Remember that setFilters inherits from pseudos 1861 var args, 1862 fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || 1863 find.error("unsupported pseudo: " + pseudo); 1864 1865 // The user may use createPseudo to indicate that 1866 // arguments are needed to create the filter function 1867 // just as jQuery does 1868 if (fn[expando]) { 1869 return fn(argument); 1870 } 1871 1872 // But maintain support for old signatures 1873 if (fn.length > 1) { 1874 args = [pseudo, pseudo, "", argument]; 1875 return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? 1876 markFunction(function (seed, matches) { 1877 var idx, 1878 matched = fn(seed, argument), 1879 i = matched.length; 1880 while (i--) { 1881 idx = indexOf.call(seed, matched[i]); 1882 seed[idx] = !(matches[idx] = matched[i]); 1883 } 1884 }) : 1885 function (elem) { 1886 return fn(elem, 0, args); 1887 }; 1888 } 1889 1890 return fn; 1891 } 1892 }, 1893 1894 pseudos: { 1895 1896 // Potentially complex pseudos 1897 not: markFunction(function (selector) { 1898 1899 // Trim the selector passed to compile 1900 // to avoid treating leading and trailing 1901 // spaces as combinators 1902 var input = [], 1903 results = [], 1904 matcher = compile(selector.replace(rtrimCSS, "$1")); 1905 1906 return matcher[expando] ? 1907 markFunction(function (seed, matches, _context, xml) { 1908 var elem, 1909 unmatched = matcher(seed, null, xml, []), 1910 i = seed.length; 1911 1912 // Match elements unmatched by `matcher` 1913 while (i--) { 1914 if (elem = unmatched[i]) { 1915 seed[i] = !(matches[i] = elem); 1916 } 1917 } 1918 }) : 1919 function (elem, _context, xml) { 1920 input[0] = elem; 1921 matcher(input, null, xml, results); 1922 1923 // Don't keep the element 1924 // (see https://github.com/jquery/sizzle/issues/299) 1925 input[0] = null; 1926 return !results.pop(); 1927 }; 1928 }), 1929 1930 has: markFunction(function (selector) { 1931 return function (elem) { 1932 return find(selector, elem).length > 0; 1933 }; 1934 }), 1935 1936 contains: markFunction(function (text) { 1937 text = text.replace(runescape, funescape); 1938 return function (elem) { 1939 return (elem.textContent || jQuery.text(elem)).indexOf(text) > -1; 1940 }; 1941 }), 1942 1943 // "Whether an element is represented by a :lang() selector 1944 // is based solely on the element's language value 1945 // being equal to the identifier C, 1946 // or beginning with the identifier C immediately followed by "-". 1947 // The matching of C against the element's language value is performed case-insensitively. 1948 // The identifier C does not have to be a valid language name." 1949 // https://www.w3.org/TR/selectors/#lang-pseudo 1950 lang: markFunction(function (lang) { 1951 1952 // lang value must be a valid identifier 1953 if (!ridentifier.test(lang || "")) { 1954 find.error("unsupported lang: " + lang); 1955 } 1956 lang = lang.replace(runescape, funescape).toLowerCase(); 1957 return function (elem) { 1958 var elemLang; 1959 do { 1960 if (elemLang = documentIsHTML ? 1961 elem.lang : 1962 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) { 1963 1964 elemLang = elemLang.toLowerCase(); 1965 return elemLang === lang || elemLang.indexOf(lang + "-") === 0; 1966 } 1967 } while ((elem = elem.parentNode) && elem.nodeType === 1); 1968 return false; 1969 }; 1970 }), 1971 1972 // Miscellaneous 1973 target: function (elem) { 1974 var hash = window.location && window.location.hash; 1975 return hash && hash.slice(1) === elem.id; 1976 }, 1977 1978 root: function (elem) { 1979 return elem === documentElement; 1980 }, 1981 1982 focus: function (elem) { 1983 return elem === safeActiveElement() && 1984 document.hasFocus() && 1985 !!(elem.type || elem.href || ~elem.tabIndex); 1986 }, 1987 1988 // Boolean properties 1989 enabled: createDisabledPseudo(false), 1990 disabled: createDisabledPseudo(true), 1991 1992 checked: function (elem) { 1993 1994 // In CSS3, :checked should return both checked and selected elements 1995 // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1996 return nodeName(elem, "input") && !!elem.checked || 1997 nodeName(elem, "option") && !!elem.selected; 1998 }, 1999 2000 selected: function (elem) { 2001 2002 // Support: IE <=11+ 2003 // Accessing the selectedIndex property 2004 // forces the browser to treat the default option as 2005 // selected when in an optgroup. 2006 if (elem.parentNode) { 2007 // eslint-disable-next-line no-unused-expressions 2008 elem.parentNode.selectedIndex; 2009 } 2010 2011 return elem.selected === true; 2012 }, 2013 2014 // Contents 2015 empty: function (elem) { 2016 2017 // https://www.w3.org/TR/selectors/#empty-pseudo 2018 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 2019 // but not by others (comment: 8; processing instruction: 7; etc.) 2020 // nodeType < 6 works because attributes (2) do not appear as children 2021 for (elem = elem.firstChild; elem; elem = elem.nextSibling) { 2022 if (elem.nodeType < 6) { 2023 return false; 2024 } 2025 } 2026 return true; 2027 }, 2028 2029 parent: function (elem) { 2030 return !Expr.pseudos.empty(elem); 2031 }, 2032 2033 // Element/input types 2034 header: function (elem) { 2035 return rheader.test(elem.nodeName); 2036 }, 2037 2038 input: function (elem) { 2039 return rinputs.test(elem.nodeName); 2040 }, 2041 2042 button: function (elem) { 2043 return nodeName(elem, "input") && elem.type === "button" || 2044 nodeName(elem, "button"); 2045 }, 2046 2047 text: function (elem) { 2048 var attr; 2049 return nodeName(elem, "input") && elem.type === "text" && ( 2050 2051 // Support: IE <10 only 2052 // New HTML5 attribute values (e.g., "search") appear 2053 // with elem.type === "text" 2054 (attr = elem.getAttribute("type")) == null || 2055 attr.toLowerCase() === "text"); 2056 }, 2057 2058 // Position-in-collection 2059 first: createPositionalPseudo(function () { 2060 return [0]; 2061 }), 2062 2063 last: createPositionalPseudo(function (_matchIndexes, length) { 2064 return [length - 1]; 2065 }), 2066 2067 eq: createPositionalPseudo(function (_matchIndexes, length, argument) { 2068 return [argument < 0 ? argument + length : argument]; 2069 }), 2070 2071 even: createPositionalPseudo(function (matchIndexes, length) { 2072 var i = 0; 2073 for (; i < length; i += 2) { 2074 matchIndexes.push(i); 2075 } 2076 return matchIndexes; 2077 }), 2078 2079 odd: createPositionalPseudo(function (matchIndexes, length) { 2080 var i = 1; 2081 for (; i < length; i += 2) { 2082 matchIndexes.push(i); 2083 } 2084 return matchIndexes; 2085 }), 2086 2087 lt: createPositionalPseudo(function (matchIndexes, length, argument) { 2088 var i; 2089 2090 if (argument < 0) { 2091 i = argument + length; 2092 } else if (argument > length) { 2093 i = length; 2094 } else { 2095 i = argument; 2096 } 2097 2098 for (; --i >= 0;) { 2099 matchIndexes.push(i); 2100 } 2101 return matchIndexes; 2102 }), 2103 2104 gt: createPositionalPseudo(function (matchIndexes, length, argument) { 2105 var i = argument < 0 ? argument + length : argument; 2106 for (; ++i < length;) { 2107 matchIndexes.push(i); 2108 } 2109 return matchIndexes; 2110 }) 2111 } 2112 }; 2113 2114 Expr.pseudos.nth = Expr.pseudos.eq; 2115 2116 // Add button/input type pseudos 2117 for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) { 2118 Expr.pseudos[i] = createInputPseudo(i); 2119 } 2120 for (i in { submit: true, reset: true }) { 2121 Expr.pseudos[i] = createButtonPseudo(i); 2122 } 2123 2124 // Easy API for creating new setFilters 2125 function setFilters() {} 2126 setFilters.prototype = Expr.filters = Expr.pseudos; 2127 Expr.setFilters = new setFilters(); 2128 2129 function tokenize(selector, parseOnly) { 2130 var matched,match,tokens,type, 2131 soFar,groups,preFilters,
2132 cached = tokenCache[selector + " "]; 2133 2134 if (cached) { 2135 return parseOnly ? 0 : cached.slice(0); 2136 } 2137 2138 soFar = selector; 2139 groups = []; 2140 preFilters = Expr.preFilter; 2141 2142 while (soFar) { 2143 2144 // Comma and first run 2145 if (!matched || (match = rcomma.exec(soFar))) { 2146 if (match) { 2147 2148 // Don't consume trailing commas as valid 2149 soFar = soFar.slice(match[0].length) || soFar; 2150 } 2151 groups.push(tokens = []); 2152 } 2153 2154 matched = false; 2155 2156 // Combinators 2157 if (match = rleadingCombinator.exec(soFar)) { 2158 matched = match.shift(); 2159 tokens.push({ 2160 value: matched, 2161 2162 // Cast descendant combinators to space 2163 type: match[0].replace(rtrimCSS, " ") 2164 }); 2165 soFar = soFar.slice(matched.length); 2166 } 2167 2168 // Filters 2169 for (type in Expr.filter) { 2170 if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || ( 2171 match = preFilters[type](match)))) { 2172 matched = match.shift(); 2173 tokens.push({ 2174 value: matched, 2175 type: type, 2176 matches: match 2177 }); 2178 soFar = soFar.slice(matched.length); 2179 } 2180 } 2181 2182 if (!matched) { 2183 break; 2184 } 2185 } 2186 2187 // Return the length of the invalid excess 2188 // if we're just parsing 2189 // Otherwise, throw an error or return tokens 2190 if (parseOnly) { 2191 return soFar.length; 2192 } 2193 2194 return soFar ? 2195 find.error(selector) : 2196 2197 // Cache the tokens 2198 tokenCache(selector, groups).slice(0); 2199 } 2200 2201 function toSelector(tokens) { 2202 var i = 0, 2203 len = tokens.length, 2204 selector = ""; 2205 for (; i < len; i++) { 2206 selector += tokens[i].value; 2207 } 2208 return selector; 2209 } 2210 2211 function addCombinator(matcher, combinator, base) { 2212 var dir = combinator.dir, 2213 skip = combinator.next, 2214 key = skip || dir, 2215 checkNonElements = base && key === "parentNode", 2216 doneName = done++; 2217 2218 return combinator.first ? 2219 2220 // Check against closest ancestor/preceding element 2221 function (elem, context, xml) { 2222 while (elem = elem[dir]) { 2223 if (elem.nodeType === 1 || checkNonElements) { 2224 return matcher(elem, context, xml); 2225 } 2226 } 2227 return false; 2228 } : 2229 2230 // Check against all ancestor/preceding elements 2231 function (elem, context, xml) { 2232 var oldCache,outerCache, 2233 newCache = [dirruns, doneName]; 2234 2235 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 2236 if (xml) { 2237 while (elem = elem[dir]) { 2238 if (elem.nodeType === 1 || checkNonElements) { 2239 if (matcher(elem, context, xml)) { 2240 return true; 2241 } 2242 } 2243 } 2244 } else { 2245 while (elem = elem[dir]) { 2246 if (elem.nodeType === 1 || checkNonElements) { 2247 outerCache = elem[expando] || (elem[expando] = {}); 2248 2249 if (skip && nodeName(elem, skip)) { 2250 elem = elem[dir] || elem; 2251 } else if ((oldCache = outerCache[key]) && 2252 oldCache[0] === dirruns && oldCache[1] === doneName) { 2253 2254 // Assign to newCache so results back-propagate to previous elements 2255 return newCache[2] = oldCache[2]; 2256 } else { 2257 2258 // Reuse newcache so results back-propagate to previous elements 2259 outerCache[key] = newCache; 2260 2261 // A match means we're done; a fail means we have to keep checking 2262 if (newCache[2] = matcher(elem, context, xml)) { 2263 return true; 2264 } 2265 } 2266 } 2267 } 2268 } 2269 return false; 2270 }; 2271 } 2272 2273 function elementMatcher(matchers) { 2274 return matchers.length > 1 ? 2275 function (elem, context, xml) { 2276 var i = matchers.length; 2277 while (i--) { 2278 if (!matchers[i](elem, context, xml)) { 2279 return false;
vendor: 4,211 bytes, lines 2280-2420
2280 } 2281 } 2282 return true; 2283 } : 2284 matchers[0]; 2285 } 2286 2287 function multipleContexts(selector, contexts, results) { 2288 var i = 0, 2289 len = contexts.length; 2290 for (; i < len; i++) { 2291 find(selector, contexts[i], results); 2292 } 2293 return results; 2294 } 2295 2296 function condense(unmatched, map, filter, context, xml) { 2297 var elem, 2298 newUnmatched = [], 2299 i = 0, 2300 len = unmatched.length, 2301 mapped = map != null; 2302 2303 for (; i < len; i++) { 2304 if (elem = unmatched[i]) { 2305 if (!filter || filter(elem, context, xml)) { 2306 newUnmatched.push(elem); 2307 if (mapped) { 2308 map.push(i); 2309 } 2310 } 2311 } 2312 } 2313 2314 return newUnmatched; 2315 } 2316 2317 function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { 2318 if (postFilter && !postFilter[expando]) { 2319 postFilter = setMatcher(postFilter); 2320 } 2321 if (postFinder && !postFinder[expando]) { 2322 postFinder = setMatcher(postFinder, postSelector); 2323 } 2324 return markFunction(function (seed, results, context, xml) { 2325 var temp,i,elem,matcherOut, 2326 preMap = [], 2327 postMap = [], 2328 preexisting = results.length, 2329 2330 // Get initial elements from seed or context 2331 elems = seed || 2332 multipleContexts(selector || "*", 2333 context.nodeType ? [context] : context, []), 2334 2335 // Prefilter to get matcher input, preserving a map for seed-results synchronization 2336 matcherIn = preFilter && (seed || !selector) ? 2337 condense(elems, preMap, preFilter, context, xml) : 2338 elems; 2339 2340 if (matcher) { 2341 2342 // If we have a postFinder, or filtered seed, or non-seed postFilter 2343 // or preexisting results, 2344 matcherOut = postFinder || (seed ? preFilter : preexisting || postFilter) ? 2345 2346 // ...intermediate processing is necessary 2347 [] : 2348 2349 // ...otherwise use results directly 2350 results; 2351 2352 // Find primary matches 2353 matcher(matcherIn, matcherOut, context, xml); 2354 } else { 2355 matcherOut = matcherIn; 2356 } 2357 2358 // Apply postFilter 2359 if (postFilter) { 2360 temp = condense(matcherOut, postMap); 2361 postFilter(temp, [], context, xml); 2362 2363 // Un-match failing elements by moving them back to matcherIn 2364 i = temp.length; 2365 while (i--) { 2366 if (elem = temp[i]) { 2367 matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); 2368 } 2369 } 2370 } 2371 2372 if (seed) { 2373 if (postFinder || preFilter) { 2374 if (postFinder) { 2375 2376 // Get the final matcherOut by condensing this intermediate into postFinder contexts 2377 temp = []; 2378 i = matcherOut.length; 2379 while (i--) { 2380 if (elem = matcherOut[i]) { 2381 2382 // Restore matcherIn since elem is not yet a final match 2383 temp.push(matcherIn[i] = elem); 2384 } 2385 } 2386 postFinder(null, matcherOut = [], temp, xml); 2387 } 2388 2389 // Move matched elements from seed to results to keep them synchronized 2390 i = matcherOut.length; 2391 while (i--) { 2392 if ((elem = matcherOut[i]) && 2393 (temp = postFinder ? indexOf.call(seed, elem) : preMap[i]) > -1) { 2394 2395 seed[temp] = !(results[temp] = elem); 2396 } 2397 } 2398 } 2399 2400 // Add elements to results, through postFinder if defined 2401 } else { 2402 matcherOut = condense( 2403 matcherOut === results ? 2404 matcherOut.splice(preexisting, matcherOut.length) : 2405 matcherOut 2406 ); 2407 if (postFinder) { 2408 postFinder(null, results, matcherOut, xml); 2409 } else { 2410 push.apply(results, matcherOut); 2411 } 2412 } 2413 }); 2414 } 2415 2416 function matcherFromTokens(tokens) { 2417 var checkContext,matcher,j, 2418 len = tokens.length, 2419 leadingRelative = Expr.relative[tokens[0].type], 2420 implicitRelative = leadingRelative || Expr.relative[" "],
vendor: 9,994 bytes, lines 2421-2696
2421 i = leadingRelative ? 1 : 0, 2422 2423 // The foundational matcher ensures that elements are reachable from top-level context(s) 2424 matchContext = addCombinator(function (elem) { 2425 return elem === checkContext; 2426 }, implicitRelative, true), 2427 matchAnyContext = addCombinator(function (elem) { 2428 return indexOf.call(checkContext, elem) > -1; 2429 }, implicitRelative, true), 2430 matchers = [function (elem, context, xml) { 2431 2432 // Support: IE 11+, Edge 17 - 18+ 2433 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2434 // two documents; shallow comparisons work. 2435 // eslint-disable-next-line eqeqeq 2436 var ret = !leadingRelative && (xml || context != outermostContext) || ( 2437 (checkContext = context).nodeType ? 2438 matchContext(elem, context, xml) : 2439 matchAnyContext(elem, context, xml)); 2440 2441 // Avoid hanging onto element 2442 // (see https://github.com/jquery/sizzle/issues/299) 2443 checkContext = null; 2444 return ret; 2445 }]; 2446 2447 for (; i < len; i++) { 2448 if (matcher = Expr.relative[tokens[i].type]) { 2449 matchers = [addCombinator(elementMatcher(matchers), matcher)]; 2450 } else { 2451 matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); 2452 2453 // Return special upon seeing a positional matcher 2454 if (matcher[expando]) { 2455 2456 // Find the next relative operator (if any) for proper handling 2457 j = ++i; 2458 for (; j < len; j++) { 2459 if (Expr.relative[tokens[j].type]) { 2460 break; 2461 } 2462 } 2463 return setMatcher( 2464 i > 1 && elementMatcher(matchers), 2465 i > 1 && toSelector( 2466 2467 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 2468 tokens.slice(0, i - 1). 2469 concat({ value: tokens[i - 2].type === " " ? "*" : "" }) 2470 ).replace(rtrimCSS, "$1"), 2471 matcher, 2472 i < j && matcherFromTokens(tokens.slice(i, j)), 2473 j < len && matcherFromTokens(tokens = tokens.slice(j)), 2474 j < len && toSelector(tokens) 2475 ); 2476 } 2477 matchers.push(matcher); 2478 } 2479 } 2480 2481 return elementMatcher(matchers); 2482 } 2483 2484 function matcherFromGroupMatchers(elementMatchers, setMatchers) { 2485 var bySet = setMatchers.length > 0, 2486 byElement = elementMatchers.length > 0, 2487 superMatcher = function (seed, context, xml, results, outermost) { 2488 var elem,j,matcher, 2489 matchedCount = 0, 2490 i = "0", 2491 unmatched = seed && [], 2492 setMatched = [], 2493 contextBackup = outermostContext, 2494 2495 // We must always have either seed elements or outermost context 2496 elems = seed || byElement && Expr.find.TAG("*", outermost), 2497 2498 // Use integer dirruns iff this is the outermost matcher 2499 dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, 2500 len = elems.length; 2501 2502 if (outermost) { 2503 2504 // Support: IE 11+, Edge 17 - 18+ 2505 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2506 // two documents; shallow comparisons work. 2507 // eslint-disable-next-line eqeqeq 2508 outermostContext = context == document || context || outermost; 2509 } 2510 2511 // Add elements passing elementMatchers directly to results 2512 // Support: iOS <=7 - 9 only 2513 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching 2514 // elements by id. (see trac-14142) 2515 for (; i !== len && (elem = elems[i]) != null; i++) { 2516 if (byElement && elem) { 2517 j = 0; 2518 2519 // Support: IE 11+, Edge 17 - 18+ 2520 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2521 // two documents; shallow comparisons work. 2522 // eslint-disable-next-line eqeqeq 2523 if (!context && elem.ownerDocument != document) { 2524 setDocument(elem); 2525 xml = !documentIsHTML; 2526 } 2527 while (matcher = elementMatchers[j++]) { 2528 if (matcher(elem, context || document, xml)) { 2529 push.call(results, elem); 2530 break; 2531 } 2532 } 2533 if (outermost) { 2534 dirruns = dirrunsUnique; 2535 } 2536 } 2537 2538 // Track unmatched elements for set filters 2539 if (bySet) { 2540 2541 // They will have gone through all possible matchers 2542 if (elem = !matcher && elem) { 2543 matchedCount--; 2544 } 2545 2546 // Lengthen the array for every element, matched or not 2547 if (seed) { 2548 unmatched.push(elem); 2549 } 2550 } 2551 } 2552 2553 // `i` is now the count of elements visited above, and adding it to `matchedCount` 2554 // makes the latter nonnegative. 2555 matchedCount += i; 2556 2557 // Apply set filters to unmatched elements 2558 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 2559 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 2560 // no element matchers and no seed. 2561 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 2562 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 2563 // numerically zero. 2564 if (bySet && i !== matchedCount) { 2565 j = 0; 2566 while (matcher = setMatchers[j++]) { 2567 matcher(unmatched, setMatched, context, xml); 2568 } 2569 2570 if (seed) { 2571 2572 // Reintegrate element matches to eliminate the need for sorting 2573 if (matchedCount > 0) { 2574 while (i--) { 2575 if (!(unmatched[i] || setMatched[i])) { 2576 setMatched[i] = pop.call(results); 2577 } 2578 } 2579 } 2580 2581 // Discard index placeholder values to get only actual matches 2582 setMatched = condense(setMatched); 2583 } 2584 2585 // Add matches to results 2586 push.apply(results, setMatched); 2587 2588 // Seedless set matches succeeding multiple successful matchers stipulate sorting 2589 if (outermost && !seed && setMatched.length > 0 && 2590 matchedCount + setMatchers.length > 1) { 2591 2592 jQuery.uniqueSort(results); 2593 } 2594 } 2595 2596 // Override manipulation of globals by nested matchers 2597 if (outermost) { 2598 dirruns = dirrunsUnique; 2599 outermostContext = contextBackup; 2600 } 2601 2602 return unmatched; 2603 }; 2604 2605 return bySet ? 2606 markFunction(superMatcher) : 2607 superMatcher; 2608 } 2609 2610 function compile(selector, match /* Internal Use Only */) { 2611 var i, 2612 setMatchers = [], 2613 elementMatchers = [], 2614 cached = compilerCache[selector + " "]; 2615 2616 if (!cached) { 2617 2618 // Generate a function of recursive functions that can be used to check each element 2619 if (!match) { 2620 match = tokenize(selector); 2621 } 2622 i = match.length; 2623 while (i--) { 2624 cached = matcherFromTokens(match[i]); 2625 if (cached[expando]) { 2626 setMatchers.push(cached); 2627 } else { 2628 elementMatchers.push(cached); 2629 } 2630 } 2631 2632 // Cache the compiled function 2633 cached = compilerCache(selector, 2634 matcherFromGroupMatchers(elementMatchers, setMatchers)); 2635 2636 // Save selector and tokenization 2637 cached.selector = selector; 2638 } 2639 return cached; 2640 } 2641 2642 /** 2643 * A low-level selection function that works with jQuery's compiled 2644 * selector functions 2645 * @param {String|Function} selector A selector or a pre-compiled 2646 * selector function built with jQuery selector compile 2647 * @param {Element} context 2648 * @param {Array} [results] 2649 * @param {Array} [seed] A set of elements to match against 2650 */ 2651 function select(selector, context, results, seed) { 2652 var i,tokens,token,type,find, 2653 compiled = typeof selector === "function" && selector, 2654 match = !seed && tokenize(selector = compiled.selector || selector); 2655 2656 results = results || []; 2657 2658 // Try to minimize operations if there is only one selector in the list and no seed 2659 // (the latter of which guarantees us context) 2660 if (match.length === 1) { 2661 2662 // Reduce context if the leading compound selector is an ID 2663 tokens = match[0] = match[0].slice(0); 2664 if (tokens.length > 2 && (token = tokens[0]).type === "ID" && 2665 context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { 2666 2667 context = (Expr.find.ID( 2668 token.matches[0].replace(runescape, funescape), 2669 context 2670 ) || [])[0]; 2671 if (!context) { 2672 return results; 2673 2674 // Precompiled matchers will still verify ancestry, so step up a level 2675 } else if (compiled) { 2676 context = context.parentNode; 2677 } 2678 2679 selector = selector.slice(tokens.shift().value.length); 2680 } 2681 2682 // Fetch a seed set for right-to-left matching 2683 i = matchExpr.needsContext.test(selector) ? 0 : tokens.length; 2684 while (i--) { 2685 token = tokens[i]; 2686 2687 // Abort if we hit a combinator 2688 if (Expr.relative[type = token.type]) { 2689 break; 2690 } 2691 if (find = Expr.find[type]) { 2692 2693 // Search, expanding context for leading sibling combinators 2694 if (seed = find( 2695 token.matches[0].replace(runescape, funescape), 2696 rsibling.test(tokens[0].type) &&
vendor: 41,994 bytes, lines 2697-4145
2697 testContext(context.parentNode) || context 2698 )) { 2699 2700 // If seed is empty or no tokens remain, we can return early 2701 tokens.splice(i, 1); 2702 selector = seed.length && toSelector(tokens); 2703 if (!selector) { 2704 push.apply(results, seed); 2705 return results; 2706 } 2707 2708 break; 2709 } 2710 } 2711 } 2712 } 2713 2714 // Compile and execute a filtering function if one is not provided 2715 // Provide `match` to avoid retokenization if we modified the selector above 2716 (compiled || compile(selector, match))( 2717 seed, 2718 context, 2719 !documentIsHTML, 2720 results, 2721 !context || rsibling.test(selector) && testContext(context.parentNode) || context 2722 ); 2723 return results; 2724 } 2725 2726 // One-time assignments 2727 2728 // Support: Android <=4.0 - 4.1+ 2729 // Sort stability 2730 support.sortStable = expando.split("").sort(sortOrder).join("") === expando; 2731 2732 // Initialize against the default document 2733 setDocument(); 2734 2735 // Support: Android <=4.0 - 4.1+ 2736 // Detached nodes confoundingly follow *each other* 2737 support.sortDetached = assert(function (el) { 2738 2739 // Should return 1, but returns 4 (following) 2740 return el.compareDocumentPosition(document.createElement("fieldset")) & 1; 2741 }); 2742 2743 jQuery.find = find; 2744 2745 // Deprecated 2746 jQuery.expr[":"] = jQuery.expr.pseudos; 2747 jQuery.unique = jQuery.uniqueSort; 2748 2749 // These have always been private, but they used to be documented as part of 2750 // Sizzle so let's maintain them for now for backwards compatibility purposes. 2751 find.compile = compile; 2752 find.select = select; 2753 find.setDocument = setDocument; 2754 find.tokenize = tokenize; 2755 2756 find.escape = jQuery.escapeSelector; 2757 find.getText = jQuery.text; 2758 find.isXML = jQuery.isXMLDoc; 2759 find.selectors = jQuery.expr; 2760 find.support = jQuery.support; 2761 find.uniqueSort = jQuery.uniqueSort; 2762 2763 /* eslint-enable */ 2764 2765 })(); 2766 2767 2768 var dir = function (elem, dir, until) { 2769 var matched = [], 2770 truncate = until !== undefined; 2771 2772 while ((elem = elem[dir]) && elem.nodeType !== 9) { 2773 if (elem.nodeType === 1) { 2774 if (truncate && jQuery(elem).is(until)) { 2775 break; 2776 } 2777 matched.push(elem); 2778 } 2779 } 2780 return matched; 2781 }; 2782 2783 2784 var siblings = function (n, elem) { 2785 var matched = []; 2786 2787 for (; n; n = n.nextSibling) { 2788 if (n.nodeType === 1 && n !== elem) { 2789 matched.push(n); 2790 } 2791 } 2792 2793 return matched; 2794 }; 2795 2796 2797 var rneedsContext = jQuery.expr.match.needsContext; 2798 2799 var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; 2800 2801 2802 2803 // Implement the identical functionality for filter and not 2804 function winnow(elements, qualifier, not) { 2805 if (isFunction(qualifier)) { 2806 return jQuery.grep(elements, function (elem, i) { 2807 return !!qualifier.call(elem, i, elem) !== not; 2808 }); 2809 } 2810 2811 // Single element 2812 if (qualifier.nodeType) { 2813 return jQuery.grep(elements, function (elem) { 2814 return elem === qualifier !== not; 2815 }); 2816 } 2817 2818 // Arraylike of elements (jQuery, arguments, Array) 2819 if (typeof qualifier !== "string") { 2820 return jQuery.grep(elements, function (elem) { 2821 return indexOf.call(qualifier, elem) > -1 !== not; 2822 }); 2823 } 2824 2825 // Filtered directly for both simple and complex selectors 2826 return jQuery.filter(qualifier, elements, not); 2827 } 2828 2829 jQuery.filter = function (expr, elems, not) { 2830 var elem = elems[0]; 2831 2832 if (not) { 2833 expr = ":not(" + expr + ")"; 2834 } 2835 2836 if (elems.length === 1 && elem.nodeType === 1) { 2837 return jQuery.find.matchesSelector(elem, expr) ? [elem] : []; 2838 } 2839 2840 return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) { 2841 return elem.nodeType === 1; 2842 })); 2843 }; 2844 2845 jQuery.fn.extend({ 2846 find: function (selector) { 2847 var i,ret, 2848 len = this.length, 2849 self = this; 2850 2851 if (typeof selector !== "string") { 2852 return this.pushStack(jQuery(selector).filter(function () { 2853 for (i = 0; i < len; i++) { 2854 if (jQuery.contains(self[i], this)) { 2855 return true; 2856 } 2857 } 2858 })); 2859 } 2860 2861 ret = this.pushStack([]); 2862 2863 for (i = 0; i < len; i++) { 2864 jQuery.find(selector, self[i], ret); 2865 } 2866 2867 return len > 1 ? jQuery.uniqueSort(ret) : ret; 2868 }, 2869 filter: function (selector) { 2870 return this.pushStack(winnow(this, selector || [], false)); 2871 }, 2872 not: function (selector) { 2873 return this.pushStack(winnow(this, selector || [], true)); 2874 }, 2875 is: function (selector) { 2876 return !!winnow( 2877 this, 2878 2879 // If this is a positional/relative selector, check membership in the returned set 2880 // so $("p:first").is("p:last") won't return true for a doc with two "p". 2881 typeof selector === "string" && rneedsContext.test(selector) ? 2882 jQuery(selector) : 2883 selector || [], 2884 false 2885 ).length; 2886 } 2887 }); 2888 2889 2890 // Initialize a jQuery object 2891 2892 2893 // A central reference to the root jQuery(document) 2894 var rootjQuery, 2895 2896 // A simple way to check for HTML strings 2897 // Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521) 2898 // Strict HTML recognition (trac-11290: must start with <) 2899 // Shortcut simple #id case for speed 2900 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 2901 2902 init = jQuery.fn.init = function (selector, context, root) { 2903 var match, elem; 2904 2905 // HANDLE: $(""), $(null), $(undefined), $(false) 2906 if (!selector) { 2907 return this; 2908 } 2909 2910 // Method init() accepts an alternate rootjQuery 2911 // so migrate can support jQuery.sub (gh-2101) 2912 root = root || rootjQuery; 2913 2914 // Handle HTML strings 2915 if (typeof selector === "string") { 2916 if (selector[0] === "<" && 2917 selector[selector.length - 1] === ">" && 2918 selector.length >= 3) { 2919 2920 // Assume that strings that start and end with <> are HTML and skip the regex check 2921 match = [null, selector, null]; 2922 2923 } else { 2924 match = rquickExpr.exec(selector); 2925 } 2926 2927 // Match html or make sure no context is specified for #id 2928 if (match && (match[1] || !context)) { 2929 2930 // HANDLE: $(html) -> $(array) 2931 if (match[1]) { 2932 context = context instanceof jQuery ? context[0] : context; 2933 2934 // Option to run scripts is true for back-compat 2935 // Intentionally let the error be thrown if parseHTML is not present 2936 jQuery.merge(this, jQuery.parseHTML( 2937 match[1], 2938 context && context.nodeType ? context.ownerDocument || context : document, 2939 true 2940 )); 2941 2942 // HANDLE: $(html, props) 2943 if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { 2944 for (match in context) { 2945 2946 // Properties of context are called as methods if possible 2947 if (isFunction(this[match])) { 2948 this[match](context[match]); 2949 2950 // ...and otherwise set as attributes 2951 } else { 2952 this.attr(match, context[match]); 2953 } 2954 } 2955 } 2956 2957 return this; 2958 2959 // HANDLE: $(#id) 2960 } else { 2961 elem = document.getElementById(match[2]); 2962 2963 if (elem) { 2964 2965 // Inject the element directly into the jQuery object 2966 this[0] = elem; 2967 this.length = 1; 2968 } 2969 return this; 2970 } 2971 2972 // HANDLE: $(expr, $(...)) 2973 } else if (!context || context.jquery) { 2974 return (context || root).find(selector); 2975 2976 // HANDLE: $(expr, context) 2977 // (which is just equivalent to: $(context).find(expr) 2978 } else { 2979 return this.constructor(context).find(selector); 2980 } 2981 2982 // HANDLE: $(DOMElement) 2983 } else if (selector.nodeType) { 2984 this[0] = selector; 2985 this.length = 1; 2986 return this; 2987 2988 // HANDLE: $(function) 2989 // Shortcut for document ready 2990 } else if (isFunction(selector)) { 2991 return root.ready !== undefined ? 2992 root.ready(selector) : 2993 2994 // Execute immediately if ready is not present 2995 selector(jQuery); 2996 } 2997 2998 return jQuery.makeArray(selector, this); 2999 }; 3000 3001 // Give the init function the jQuery prototype for later instantiation 3002 init.prototype = jQuery.fn; 3003 3004 // Initialize central reference 3005 rootjQuery = jQuery(document); 3006 3007 3008 var rparentsprev = /^(?:parents|prev(?:Until|All))/, 3009 3010 // Methods guaranteed to produce a unique set when starting from a unique set 3011 guaranteedUnique = { 3012 children: true, 3013 contents: true, 3014 next: true, 3015 prev: true 3016 }; 3017 3018 jQuery.fn.extend({ 3019 has: function (target) { 3020 var targets = jQuery(target, this), 3021 l = targets.length; 3022 3023 return this.filter(function () { 3024 var i = 0; 3025 for (; i < l; i++) { 3026 if (jQuery.contains(this, targets[i])) { 3027 return true; 3028 } 3029 } 3030 }); 3031 }, 3032 3033 closest: function (selectors, context) { 3034 var cur, 3035 i = 0, 3036 l = this.length, 3037 matched = [], 3038 targets = typeof selectors !== "string" && jQuery(selectors); 3039 3040 // Positional selectors never match, since there's no _selection_ context 3041 if (!rneedsContext.test(selectors)) { 3042 for (; i < l; i++) { 3043 for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { 3044 3045 // Always skip document fragments 3046 if (cur.nodeType < 11 && (targets ? 3047 targets.index(cur) > -1 : 3048 3049 // Don't pass non-elements to jQuery#find 3050 cur.nodeType === 1 && 3051 jQuery.find.matchesSelector(cur, selectors))) { 3052 3053 matched.push(cur); 3054 break; 3055 } 3056 } 3057 } 3058 } 3059 3060 return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched); 3061 }, 3062 3063 // Determine the position of an element within the set 3064 index: function (elem) { 3065 3066 // No argument, return index in parent 3067 if (!elem) { 3068 return this[0] && this[0].parentNode ? this.first().prevAll().length : -1; 3069 } 3070 3071 // Index in selector 3072 if (typeof elem === "string") { 3073 return indexOf.call(jQuery(elem), this[0]); 3074 } 3075 3076 // Locate the position of the desired element 3077 return indexOf.call(this, 3078 3079 // If it receives a jQuery object, the first element is used 3080 elem.jquery ? elem[0] : elem 3081 ); 3082 }, 3083 3084 add: function (selector, context) { 3085 return this.pushStack( 3086 jQuery.uniqueSort( 3087 jQuery.merge(this.get(), jQuery(selector, context)) 3088 ) 3089 ); 3090 }, 3091 3092 addBack: function (selector) { 3093 return this.add(selector == null ? 3094 this.prevObject : this.prevObject.filter(selector) 3095 ); 3096 } 3097 }); 3098 3099 function sibling(cur, dir) { 3100 while ((cur = cur[dir]) && cur.nodeType !== 1) {} 3101 return cur; 3102 } 3103 3104 jQuery.each({ 3105 parent: function (elem) { 3106 var parent = elem.parentNode; 3107 return parent && parent.nodeType !== 11 ? parent : null; 3108 }, 3109 parents: function (elem) { 3110 return dir(elem, "parentNode"); 3111 }, 3112 parentsUntil: function (elem, _i, until) { 3113 return dir(elem, "parentNode", until); 3114 }, 3115 next: function (elem) { 3116 return sibling(elem, "nextSibling"); 3117 }, 3118 prev: function (elem) { 3119 return sibling(elem, "previousSibling"); 3120 }, 3121 nextAll: function (elem) { 3122 return dir(elem, "nextSibling"); 3123 }, 3124 prevAll: function (elem) { 3125 return dir(elem, "previousSibling"); 3126 }, 3127 nextUntil: function (elem, _i, until) { 3128 return dir(elem, "nextSibling", until); 3129 }, 3130 prevUntil: function (elem, _i, until) { 3131 return dir(elem, "previousSibling", until); 3132 }, 3133 siblings: function (elem) { 3134 return siblings((elem.parentNode || {}).firstChild, elem); 3135 }, 3136 children: function (elem) { 3137 return siblings(elem.firstChild); 3138 }, 3139 contents: function (elem) { 3140 if (elem.contentDocument != null && 3141 3142 // Support: IE 11+ 3143 // <object> elements with no `data` attribute has an object 3144 // `contentDocument` with a `null` prototype. 3145 getProto(elem.contentDocument)) { 3146 3147 return elem.contentDocument; 3148 } 3149 3150 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 3151 // Treat the template element as a regular one in browsers that 3152 // don't support it. 3153 if (nodeName(elem, "template")) { 3154 elem = elem.content || elem; 3155 } 3156 3157 return jQuery.merge([], elem.childNodes); 3158 } 3159 }, function (name, fn) { 3160 jQuery.fn[name] = function (until, selector) { 3161 var matched = jQuery.map(this, fn, until); 3162 3163 if (name.slice(-5) !== "Until") { 3164 selector = until; 3165 } 3166 3167 if (selector && typeof selector === "string") { 3168 matched = jQuery.filter(selector, matched); 3169 } 3170 3171 if (this.length > 1) { 3172 3173 // Remove duplicates 3174 if (!guaranteedUnique[name]) { 3175 jQuery.uniqueSort(matched); 3176 } 3177 3178 // Reverse order for parents* and prev-derivatives 3179 if (rparentsprev.test(name)) { 3180 matched.reverse(); 3181 } 3182 } 3183 3184 return this.pushStack(matched); 3185 }; 3186 }); 3187 var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; 3188 3189 3190 3191 // Convert String-formatted options into Object-formatted ones 3192 function createOptions(options) { 3193 var object = {}; 3194 jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) { 3195 object[flag] = true; 3196 }); 3197 return object; 3198 } 3199 3200 /* 3201 * Create a callback list using the following parameters: 3202 * 3203 * options: an optional list of space-separated options that will change how 3204 * the callback list behaves or a more traditional option object 3205 * 3206 * By default a callback list will act like an event callback list and can be 3207 * "fired" multiple times. 3208 * 3209 * Possible options: 3210 * 3211 * once: will ensure the callback list can only be fired once (like a Deferred) 3212 * 3213 * memory: will keep track of previous values and will call any callback added 3214 * after the list has been fired right away with the latest "memorized" 3215 * values (like a Deferred) 3216 * 3217 * unique: will ensure a callback can only be added once (no duplicate in the list) 3218 * 3219 * stopOnFalse: interrupt callings when a callback returns false 3220 * 3221 */ 3222 jQuery.Callbacks = function (options) { 3223 3224 // Convert options from String-formatted to Object-formatted if needed 3225 // (we check in cache first) 3226 options = typeof options === "string" ? 3227 createOptions(options) : 3228 jQuery.extend({}, options); 3229 3230 var // Flag to know if list is currently firing 3231 firing, 3232 3233 // Last fire value for non-forgettable lists 3234 memory, 3235 3236 // Flag to know if list was already fired 3237 fired, 3238 3239 // Flag to prevent firing 3240 locked, 3241 3242 // Actual callback list 3243 list = [], 3244 3245 // Queue of execution data for repeatable lists 3246 queue = [], 3247 3248 // Index of currently firing callback (modified by add/remove as needed) 3249 firingIndex = -1, 3250 3251 // Fire callbacks 3252 fire = function () { 3253 3254 // Enforce single-firing 3255 locked = locked || options.once; 3256 3257 // Execute callbacks for all pending executions, 3258 // respecting firingIndex overrides and runtime changes 3259 fired = firing = true; 3260 for (; queue.length; firingIndex = -1) { 3261 memory = queue.shift(); 3262 while (++firingIndex < list.length) { 3263 3264 // Run callback and check for early termination 3265 if (list[firingIndex].apply(memory[0], memory[1]) === false && 3266 options.stopOnFalse) { 3267 3268 // Jump to end and forget the data so .add doesn't re-fire 3269 firingIndex = list.length; 3270 memory = false; 3271 } 3272 } 3273 } 3274 3275 // Forget the data if we're done with it 3276 if (!options.memory) { 3277 memory = false; 3278 } 3279 3280 firing = false; 3281 3282 // Clean up if we're done firing for good 3283 if (locked) { 3284 3285 // Keep an empty list if we have data for future add calls 3286 if (memory) { 3287 list = []; 3288 3289 // Otherwise, this object is spent 3290 } else { 3291 list = ""; 3292 } 3293 } 3294 }, 3295 3296 // Actual Callbacks object 3297 self = { 3298 3299 // Add a callback or a collection of callbacks to the list 3300 add: function () { 3301 if (list) { 3302 3303 // If we have memory from a past run, we should fire after adding 3304 if (memory && !firing) { 3305 firingIndex = list.length - 1; 3306 queue.push(memory); 3307 } 3308 3309 (function add(args) { 3310 jQuery.each(args, function (_, arg) { 3311 if (isFunction(arg)) { 3312 if (!options.unique || !self.has(arg)) { 3313 list.push(arg); 3314 } 3315 } else if (arg && arg.length && toType(arg) !== "string") { 3316 3317 // Inspect recursively 3318 add(arg); 3319 } 3320 }); 3321 })(arguments); 3322 3323 if (memory && !firing) { 3324 fire(); 3325 } 3326 } 3327 return this; 3328 }, 3329 3330 // Remove a callback from the list 3331 remove: function () { 3332 jQuery.each(arguments, function (_, arg) { 3333 var index; 3334 while ((index = jQuery.inArray(arg, list, index)) > -1) { 3335 list.splice(index, 1); 3336 3337 // Handle firing indexes 3338 if (index <= firingIndex) { 3339 firingIndex--; 3340 } 3341 } 3342 }); 3343 return this; 3344 }, 3345 3346 // Check if a given callback is in the list. 3347 // If no argument is given, return whether or not list has callbacks attached. 3348 has: function (fn) { 3349 return fn ? 3350 jQuery.inArray(fn, list) > -1 : 3351 list.length > 0; 3352 }, 3353 3354 // Remove all callbacks from the list 3355 empty: function () { 3356 if (list) { 3357 list = []; 3358 } 3359 return this; 3360 }, 3361 3362 // Disable .fire and .add 3363 // Abort any current/pending executions 3364 // Clear all callbacks and values 3365 disable: function () { 3366 locked = queue = []; 3367 list = memory = ""; 3368 return this; 3369 }, 3370 disabled: function () { 3371 return !list; 3372 }, 3373 3374 // Disable .fire 3375 // Also disable .add unless we have memory (since it would have no effect) 3376 // Abort any pending executions 3377 lock: function () { 3378 locked = queue = []; 3379 if (!memory && !firing) { 3380 list = memory = ""; 3381 } 3382 return this; 3383 }, 3384 locked: function () { 3385 return !!locked; 3386 }, 3387 3388 // Call all callbacks with the given context and arguments 3389 fireWith: function (context, args) { 3390 if (!locked) { 3391 args = args || []; 3392 args = [context, args.slice ? args.slice() : args]; 3393 queue.push(args); 3394 if (!firing) { 3395 fire(); 3396 } 3397 } 3398 return this; 3399 }, 3400 3401 // Call all the callbacks with the given arguments 3402 fire: function () { 3403 self.fireWith(this, arguments); 3404 return this; 3405 }, 3406 3407 // To know if the callbacks have already been called at least once 3408 fired: function () { 3409 return !!fired; 3410 } 3411 }; 3412 3413 return self; 3414 }; 3415 3416 3417 function Identity(v) { 3418 return v; 3419 } 3420 function Thrower(ex) { 3421 throw ex; 3422 } 3423 3424 function adoptValue(value, resolve, reject, noValue) { 3425 var method; 3426 3427 try { 3428 3429 // Check for promise aspect first to privilege synchronous behavior 3430 if (value && isFunction(method = value.promise)) { 3431 method.call(value).done(resolve).fail(reject); 3432 3433 // Other thenables 3434 } else if (value && isFunction(method = value.then)) { 3435 method.call(value, resolve, reject); 3436 3437 // Other non-thenables 3438 } else { 3439 3440 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 3441 // * false: [ value ].slice( 0 ) => resolve( value ) 3442 // * true: [ value ].slice( 1 ) => resolve() 3443 resolve.apply(undefined, [value].slice(noValue)); 3444 } 3445 3446 // For Promises/A+, convert exceptions into rejections 3447 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 3448 // Deferred#then to conditionally suppress rejection. 3449 } catch (value) { 3450 3451 // Support: Android 4.0 only 3452 // Strict mode functions invoked without .call/.apply get global-object context 3453 reject.apply(undefined, [value]); 3454 } 3455 } 3456 3457 jQuery.extend({ 3458 3459 Deferred: function (func) { 3460 var tuples = [ 3461 3462 // action, add listener, callbacks, 3463 // ... .then handlers, argument index, [final state] 3464 ["notify", "progress", jQuery.Callbacks("memory"), 3465 jQuery.Callbacks("memory"), 2], 3466 ["resolve", "done", jQuery.Callbacks("once memory"), 3467 jQuery.Callbacks("once memory"), 0, "resolved"], 3468 ["reject", "fail", jQuery.Callbacks("once memory"), 3469 jQuery.Callbacks("once memory"), 1, "rejected"]], 3470 3471 state = "pending", 3472 promise = { 3473 state: function () { 3474 return state; 3475 }, 3476 always: function () { 3477 deferred.done(arguments).fail(arguments); 3478 return this; 3479 }, 3480 "catch": function (fn) { 3481 return promise.then(null, fn); 3482 }, 3483 3484 // Keep pipe for back-compat 3485 pipe: function /* fnDone, fnFail, fnProgress */ () { 3486 var fns = arguments; 3487 3488 return jQuery.Deferred(function (newDefer) { 3489 jQuery.each(tuples, function (_i, tuple) { 3490 3491 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 3492 var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; 3493 3494 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 3495 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 3496 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 3497 deferred[tuple[1]](function () { 3498 var returned = fn && fn.apply(this, arguments); 3499 if (returned && isFunction(returned.promise)) { 3500 returned.promise(). 3501 progress(newDefer.notify). 3502 done(newDefer.resolve). 3503 fail(newDefer.reject); 3504 } else { 3505 newDefer[tuple[0] + "With"]( 3506 this, 3507 fn ? [returned] : arguments 3508 ); 3509 } 3510 }); 3511 }); 3512 fns = null; 3513 }).promise(); 3514 }, 3515 then: function (onFulfilled, onRejected, onProgress) { 3516 var maxDepth = 0; 3517 function resolve(depth, deferred, handler, special) { 3518 return function () { 3519 var that = this, 3520 args = arguments, 3521 mightThrow = function () { 3522 var returned, then; 3523 3524 // Support: Promises/A+ section 2.3.3.3.3 3525 // https://promisesaplus.com/#point-59 3526 // Ignore double-resolution attempts 3527 if (depth < maxDepth) { 3528 return; 3529 } 3530 3531 returned = handler.apply(that, args); 3532 3533 // Support: Promises/A+ section 2.3.1 3534 // https://promisesaplus.com/#point-48 3535 if (returned === deferred.promise()) { 3536 throw new TypeError("Thenable self-resolution"); 3537 } 3538 3539 // Support: Promises/A+ sections 2.3.3.1, 3.5 3540 // https://promisesaplus.com/#point-54 3541 // https://promisesaplus.com/#point-75 3542 // Retrieve `then` only once 3543 then = returned && ( 3544 3545 // Support: Promises/A+ section 2.3.4 3546 // https://promisesaplus.com/#point-64 3547 // Only check objects and functions for thenability 3548 typeof returned === "object" || 3549 typeof returned === "function") && 3550 returned.then; 3551 3552 // Handle a returned thenable 3553 if (isFunction(then)) { 3554 3555 // Special processors (notify) just wait for resolution 3556 if (special) { 3557 then.call( 3558 returned, 3559 resolve(maxDepth, deferred, Identity, special), 3560 resolve(maxDepth, deferred, Thrower, special) 3561 ); 3562 3563 // Normal processors (resolve) also hook into progress 3564 } else { 3565 3566 // ...and disregard older resolution values 3567 maxDepth++; 3568 3569 then.call( 3570 returned, 3571 resolve(maxDepth, deferred, Identity, special), 3572 resolve(maxDepth, deferred, Thrower, special), 3573 resolve(maxDepth, deferred, Identity, 3574 deferred.notifyWith) 3575 ); 3576 } 3577 3578 // Handle all other returned values 3579 } else { 3580 3581 // Only substitute handlers pass on context 3582 // and multiple values (non-spec behavior) 3583 if (handler !== Identity) { 3584 that = undefined; 3585 args = [returned]; 3586 } 3587 3588 // Process the value(s) 3589 // Default process is resolve 3590 (special || deferred.resolveWith)(that, args); 3591 } 3592 }, 3593 3594 // Only normal processors (resolve) catch and reject exceptions 3595 process = special ? 3596 mightThrow : 3597 function () { 3598 try { 3599 mightThrow(); 3600 } catch (e) { 3601 3602 if (jQuery.Deferred.exceptionHook) { 3603 jQuery.Deferred.exceptionHook(e, 3604 process.error); 3605 } 3606 3607 // Support: Promises/A+ section 2.3.3.3.4.1 3608 // https://promisesaplus.com/#point-61 3609 // Ignore post-resolution exceptions 3610 if (depth + 1 >= maxDepth) { 3611 3612 // Only substitute handlers pass on context 3613 // and multiple values (non-spec behavior) 3614 if (handler !== Thrower) { 3615 that = undefined; 3616 args = [e]; 3617 } 3618 3619 deferred.rejectWith(that, args); 3620 } 3621 } 3622 }; 3623 3624 // Support: Promises/A+ section 2.3.3.3.1 3625 // https://promisesaplus.com/#point-57 3626 // Re-resolve promises immediately to dodge false rejection from 3627 // subsequent errors 3628 if (depth) { 3629 process(); 3630 } else { 3631 3632 // Call an optional hook to record the error, in case of exception 3633 // since it's otherwise lost when execution goes async 3634 if (jQuery.Deferred.getErrorHook) { 3635 process.error = jQuery.Deferred.getErrorHook(); 3636 3637 // The deprecated alias of the above. While the name suggests 3638 // returning the stack, not an error instance, jQuery just passes 3639 // it directly to `console.warn` so both will work; an instance 3640 // just better cooperates with source maps. 3641 } else if (jQuery.Deferred.getStackHook) { 3642 process.error = jQuery.Deferred.getStackHook(); 3643 } 3644 window.setTimeout(process); 3645 } 3646 }; 3647 } 3648 3649 return jQuery.Deferred(function (newDefer) { 3650 3651 // progress_handlers.add( ... ) 3652 tuples[0][3].add( 3653 resolve( 3654 0, 3655 newDefer, 3656 isFunction(onProgress) ? 3657 onProgress : 3658 Identity, 3659 newDefer.notifyWith 3660 ) 3661 ); 3662 3663 // fulfilled_handlers.add( ... ) 3664 tuples[1][3].add( 3665 resolve( 3666 0, 3667 newDefer, 3668 isFunction(onFulfilled) ? 3669 onFulfilled : 3670 Identity 3671 ) 3672 ); 3673 3674 // rejected_handlers.add( ... ) 3675 tuples[2][3].add( 3676 resolve( 3677 0, 3678 newDefer, 3679 isFunction(onRejected) ? 3680 onRejected : 3681 Thrower 3682 ) 3683 ); 3684 }).promise(); 3685 }, 3686 3687 // Get a promise for this deferred 3688 // If obj is provided, the promise aspect is added to the object 3689 promise: function (obj) { 3690 return obj != null ? jQuery.extend(obj, promise) : promise; 3691 } 3692 }, 3693 deferred = {}; 3694 3695 // Add list-specific methods 3696 jQuery.each(tuples, function (i, tuple) { 3697 var list = tuple[2], 3698 stateString = tuple[5]; 3699 3700 // promise.progress = list.add 3701 // promise.done = list.add 3702 // promise.fail = list.add 3703 promise[tuple[1]] = list.add; 3704 3705 // Handle state 3706 if (stateString) { 3707 list.add( 3708 function () { 3709 3710 // state = "resolved" (i.e., fulfilled) 3711 // state = "rejected" 3712 state = stateString; 3713 }, 3714 3715 // rejected_callbacks.disable 3716 // fulfilled_callbacks.disable 3717 tuples[3 - i][2].disable, 3718 3719 // rejected_handlers.disable 3720 // fulfilled_handlers.disable 3721 tuples[3 - i][3].disable, 3722 3723 // progress_callbacks.lock 3724 tuples[0][2].lock, 3725 3726 // progress_handlers.lock 3727 tuples[0][3].lock 3728 ); 3729 } 3730 3731 // progress_handlers.fire 3732 // fulfilled_handlers.fire 3733 // rejected_handlers.fire 3734 list.add(tuple[3].fire); 3735 3736 // deferred.notify = function() { deferred.notifyWith(...) } 3737 // deferred.resolve = function() { deferred.resolveWith(...) } 3738 // deferred.reject = function() { deferred.rejectWith(...) } 3739 deferred[tuple[0]] = function () { 3740 deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments); 3741 return this; 3742 }; 3743 3744 // deferred.notifyWith = list.fireWith 3745 // deferred.resolveWith = list.fireWith 3746 // deferred.rejectWith = list.fireWith 3747 deferred[tuple[0] + "With"] = list.fireWith; 3748 }); 3749 3750 // Make the deferred a promise 3751 promise.promise(deferred); 3752 3753 // Call given func if any 3754 if (func) { 3755 func.call(deferred, deferred); 3756 } 3757 3758 // All done! 3759 return deferred; 3760 }, 3761 3762 // Deferred helper 3763 when: function (singleValue) { 3764 var 3765 3766 // count of uncompleted subordinates 3767 remaining = arguments.length, 3768 3769 // count of unprocessed arguments 3770 i = remaining, 3771 3772 // subordinate fulfillment data 3773 resolveContexts = Array(i), 3774 resolveValues = slice.call(arguments), 3775 3776 // the primary Deferred 3777 primary = jQuery.Deferred(), 3778 3779 // subordinate callback factory 3780 updateFunc = function (i) { 3781 return function (value) { 3782 resolveContexts[i] = this; 3783 resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value; 3784 if (! --remaining) { 3785 primary.resolveWith(resolveContexts, resolveValues); 3786 } 3787 }; 3788 }; 3789 3790 // Single- and empty arguments are adopted like Promise.resolve 3791 if (remaining <= 1) { 3792 adoptValue(singleValue, primary.done(updateFunc(i)).resolve, primary.reject, 3793 !remaining); 3794 3795 // Use .then() to unwrap secondary thenables (cf. gh-3000) 3796 if (primary.state() === "pending" || 3797 isFunction(resolveValues[i] && resolveValues[i].then)) { 3798 3799 return primary.then(); 3800 } 3801 } 3802 3803 // Multiple arguments are aggregated like Promise.all array elements 3804 while (i--) { 3805 adoptValue(resolveValues[i], updateFunc(i), primary.reject); 3806 } 3807 3808 return primary.promise(); 3809 } 3810 }); 3811 3812 3813 // These usually indicate a programmer mistake during development, 3814 // warn about them ASAP rather than swallowing them by default. 3815 var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 3816 3817 // If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error 3818 // captured before the async barrier to get the original error cause 3819 // which may otherwise be hidden. 3820 jQuery.Deferred.exceptionHook = function (error, asyncError) { 3821 3822 // Support: IE 8 - 9 only 3823 // Console exists when dev tools are open, which can happen at any time 3824 if (window.console && window.console.warn && error && rerrorNames.test(error.name)) { 3825 window.console.warn("jQuery.Deferred exception: " + error.message, 3826 error.stack, asyncError); 3827 } 3828 }; 3829 3830 3831 3832 3833 jQuery.readyException = function (error) { 3834 window.setTimeout(function () { 3835 throw error; 3836 }); 3837 }; 3838 3839 3840 3841 3842 // The deferred used on DOM ready 3843 var readyList = jQuery.Deferred(); 3844 3845 jQuery.fn.ready = function (fn) { 3846 3847 readyList. 3848 then(fn) 3849 3850 // Wrap jQuery.readyException in a function so that the lookup 3851 // happens at the time of error handling instead of callback 3852 // registration. 3853 .catch(function (error) { 3854 jQuery.readyException(error); 3855 }); 3856 3857 return this; 3858 }; 3859 3860 jQuery.extend({ 3861 3862 // Is the DOM ready to be used? Set to true once it occurs. 3863 isReady: false, 3864 3865 // A counter to track how many items to wait for before 3866 // the ready event fires. See trac-6781 3867 readyWait: 1, 3868 3869 // Handle when the DOM is ready 3870 ready: function (wait) { 3871 3872 // Abort if there are pending holds or we're already ready 3873 if (wait === true ? --jQuery.readyWait : jQuery.isReady) { 3874 return; 3875 } 3876 3877 // Remember that the DOM is ready 3878 jQuery.isReady = true; 3879 3880 // If a normal DOM Ready event fired, decrement, and wait if need be 3881 if (wait !== true && --jQuery.readyWait > 0) { 3882 return; 3883 } 3884 3885 // If there are functions bound, to execute 3886 readyList.resolveWith(document, [jQuery]); 3887 } 3888 }); 3889 3890 jQuery.ready.then = readyList.then; 3891 3892 // The ready event handler and self cleanup method 3893 function completed() { 3894 document.removeEventListener("DOMContentLoaded", completed); 3895 window.removeEventListener("load", completed); 3896 jQuery.ready(); 3897 } 3898 3899 // Catch cases where $(document).ready() is called 3900 // after the browser event has already occurred. 3901 // Support: IE <=9 - 10 only 3902 // Older IE sometimes signals "interactive" too soon 3903 if (document.readyState === "complete" || 3904 document.readyState !== "loading" && !document.documentElement.doScroll) { 3905 3906 // Handle it asynchronously to allow scripts the opportunity to delay ready 3907 window.setTimeout(jQuery.ready); 3908 3909 } else { 3910 3911 // Use the handy event callback 3912 document.addEventListener("DOMContentLoaded", completed); 3913 3914 // A fallback to window.onload, that will always work 3915 window.addEventListener("load", completed); 3916 } 3917 3918 3919 3920 3921 // Multifunctional method to get and set values of a collection 3922 // The value/s can optionally be executed if it's a function 3923 var access = function (elems, fn, key, value, chainable, emptyGet, raw) { 3924 var i = 0, 3925 len = elems.length, 3926 bulk = key == null; 3927 3928 // Sets many values 3929 if (toType(key) === "object") { 3930 chainable = true; 3931 for (i in key) { 3932 access(elems, fn, i, key[i], true, emptyGet, raw); 3933 } 3934 3935 // Sets one value 3936 } else if (value !== undefined) { 3937 chainable = true; 3938 3939 if (!isFunction(value)) { 3940 raw = true; 3941 } 3942 3943 if (bulk) { 3944 3945 // Bulk operations run against the entire set 3946 if (raw) { 3947 fn.call(elems, value); 3948 fn = null; 3949 3950 // ...except when executing function values 3951 } else { 3952 bulk = fn; 3953 fn = function (elem, _key, value) { 3954 return bulk.call(jQuery(elem), value); 3955 }; 3956 } 3957 } 3958 3959 if (fn) { 3960 for (; i < len; i++) { 3961 fn( 3962 elems[i], key, raw ? 3963 value : 3964 value.call(elems[i], i, fn(elems[i], key)) 3965 ); 3966 } 3967 } 3968 } 3969 3970 if (chainable) { 3971 return elems; 3972 } 3973 3974 // Gets 3975 if (bulk) { 3976 return fn.call(elems); 3977 } 3978 3979 return len ? fn(elems[0], key) : emptyGet; 3980 }; 3981 3982 3983 // Matches dashed string for camelizing 3984 var rmsPrefix = /^-ms-/, 3985 rdashAlpha = /-([a-z])/g; 3986 3987 // Used by camelCase as callback to replace() 3988 function fcamelCase(_all, letter) { 3989 return letter.toUpperCase(); 3990 } 3991 3992 // Convert dashed to camelCase; used by the css and data modules 3993 // Support: IE <=9 - 11, Edge 12 - 15 3994 // Microsoft forgot to hump their vendor prefix (trac-9572) 3995 function camelCase(string) { 3996 return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase); 3997 } 3998 var acceptData = function (owner) { 3999 4000 // Accepts only: 4001 // - Node 4002 // - Node.ELEMENT_NODE 4003 // - Node.DOCUMENT_NODE 4004 // - Object 4005 // - Any 4006 return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType; 4007 }; 4008 4009 4010 4011 4012 function Data() { 4013 this.expando = jQuery.expando + Data.uid++; 4014 } 4015 4016 Data.uid = 1; 4017 4018 Data.prototype = { 4019 4020 cache: function (owner) { 4021 4022 // Check if the owner object already has a cache 4023 var value = owner[this.expando]; 4024 4025 // If not, create one 4026 if (!value) { 4027 value = {}; 4028 4029 // We can accept data for non-element nodes in modern browsers, 4030 // but we should not, see trac-8335. 4031 // Always return an empty object. 4032 if (acceptData(owner)) { 4033 4034 // If it is a node unlikely to be stringify-ed or looped over 4035 // use plain assignment 4036 if (owner.nodeType) { 4037 owner[this.expando] = value; 4038 4039 // Otherwise secure it in a non-enumerable property 4040 // configurable must be true to allow the property to be 4041 // deleted when data is removed 4042 } else { 4043 Object.defineProperty(owner, this.expando, { 4044 value: value, 4045 configurable: true 4046 }); 4047 } 4048 } 4049 } 4050 4051 return value; 4052 }, 4053 set: function (owner, data, value) { 4054 var prop, 4055 cache = this.cache(owner); 4056 4057 // Handle: [ owner, key, value ] args 4058 // Always use camelCase key (gh-2257) 4059 if (typeof data === "string") { 4060 cache[camelCase(data)] = value; 4061 4062 // Handle: [ owner, { properties } ] args 4063 } else { 4064 4065 // Copy the properties one-by-one to the cache object 4066 for (prop in data) { 4067 cache[camelCase(prop)] = data[prop]; 4068 } 4069 } 4070 return cache; 4071 }, 4072 get: function (owner, key) { 4073 return key === undefined ? 4074 this.cache(owner) : 4075 4076 // Always use camelCase key (gh-2257) 4077 owner[this.expando] && owner[this.expando][camelCase(key)]; 4078 }, 4079 access: function (owner, key, value) { 4080 4081 // In cases where either: 4082 // 4083 // 1. No key was specified 4084 // 2. A string key was specified, but no value provided 4085 // 4086 // Take the "read" path and allow the get method to determine 4087 // which value to return, respectively either: 4088 // 4089 // 1. The entire cache object 4090 // 2. The data stored at the key 4091 // 4092 if (key === undefined || 4093 key && typeof key === "string" && value === undefined) { 4094 4095 return this.get(owner, key); 4096 } 4097 4098 // When the key is not a string, or both a key and value 4099 // are specified, set or extend (existing objects) with either: 4100 // 4101 // 1. An object of properties 4102 // 2. A key and value 4103 // 4104 this.set(owner, key, value); 4105 4106 // Since the "set" path can have two possible entry points 4107 // return the expected data based on which path was taken[*] 4108 return value !== undefined ? value : key; 4109 }, 4110 remove: function (owner, key) { 4111 var i, 4112 cache = owner[this.expando]; 4113 4114 if (cache === undefined) { 4115 return; 4116 } 4117 4118 if (key !== undefined) { 4119 4120 // Support array or space separated string of keys 4121 if (Array.isArray(key)) { 4122 4123 // If key is an array of keys... 4124 // We always set camelCase keys, so remove that. 4125 key = key.map(camelCase); 4126 } else { 4127 key = camelCase(key); 4128 4129 // If a key with the spaces exists, use it. 4130 // Otherwise, create an array by matching non-whitespace 4131 key = key in cache ? 4132 [key] : 4133 key.match(rnothtmlwhite) || []; 4134 } 4135 4136 i = key.length; 4137 4138 while (i--) { 4139 delete cache[key[i]]; 4140 } 4141 } 4142 4143 // Remove the expando if there's no more data 4144 if (key === undefined || jQuery.isEmptyObject(cache)) { 4145
vendor: 8,628 bytes, lines 4146-4471
4146 // Support: Chrome <=35 - 45 4147 // Webkit & Blink performance suffers when deleting properties 4148 // from DOM nodes, so set to undefined instead 4149 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 4150 if (owner.nodeType) { 4151 owner[this.expando] = undefined; 4152 } else { 4153 delete owner[this.expando]; 4154 } 4155 } 4156 }, 4157 hasData: function (owner) { 4158 var cache = owner[this.expando]; 4159 return cache !== undefined && !jQuery.isEmptyObject(cache); 4160 } 4161 }; 4162 var dataPriv = new Data(); 4163 4164 var dataUser = new Data(); 4165 4166 4167 4168 // Implementation Summary 4169 // 4170 // 1. Enforce API surface and semantic compatibility with 1.9.x branch 4171 // 2. Improve the module's maintainability by reducing the storage 4172 // paths to a single mechanism. 4173 // 3. Use the same single mechanism to support "private" and "user" data. 4174 // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 4175 // 5. Avoid exposing implementation details on user objects (eg. expando properties) 4176 // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 4177 4178 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 4179 rmultiDash = /[A-Z]/g; 4180 4181 function getData(data) { 4182 if (data === "true") { 4183 return true; 4184 } 4185 4186 if (data === "false") { 4187 return false; 4188 } 4189 4190 if (data === "null") { 4191 return null; 4192 } 4193 4194 // Only convert to a number if it doesn't change the string 4195 if (data === +data + "") { 4196 return +data; 4197 } 4198 4199 if (rbrace.test(data)) { 4200 return JSON.parse(data); 4201 } 4202 4203 return data; 4204 } 4205 4206 function dataAttr(elem, key, data) { 4207 var name; 4208 4209 // If nothing was found internally, try to fetch any 4210 // data from the HTML5 data-* attribute 4211 if (data === undefined && elem.nodeType === 1) { 4212 name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase(); 4213 data = elem.getAttribute(name); 4214 4215 if (typeof data === "string") { 4216 try { 4217 data = getData(data); 4218 } catch (e) {} 4219 4220 // Make sure we set the data so it isn't changed later 4221 dataUser.set(elem, key, data); 4222 } else { 4223 data = undefined; 4224 } 4225 } 4226 return data; 4227 } 4228 4229 jQuery.extend({ 4230 hasData: function (elem) { 4231 return dataUser.hasData(elem) || dataPriv.hasData(elem); 4232 }, 4233 4234 data: function (elem, name, data) { 4235 return dataUser.access(elem, name, data); 4236 }, 4237 4238 removeData: function (elem, name) { 4239 dataUser.remove(elem, name); 4240 }, 4241 4242 // TODO: Now that all calls to _data and _removeData have been replaced 4243 // with direct calls to dataPriv methods, these can be deprecated. 4244 _data: function (elem, name, data) { 4245 return dataPriv.access(elem, name, data); 4246 }, 4247 4248 _removeData: function (elem, name) { 4249 dataPriv.remove(elem, name); 4250 } 4251 }); 4252 4253 jQuery.fn.extend({ 4254 data: function (key, value) { 4255 var i,name,data, 4256 elem = this[0], 4257 attrs = elem && elem.attributes; 4258 4259 // Gets all values 4260 if (key === undefined) { 4261 if (this.length) { 4262 data = dataUser.get(elem); 4263 4264 if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) { 4265 i = attrs.length; 4266 while (i--) { 4267 4268 // Support: IE 11 only 4269 // The attrs elements can be null (trac-14894) 4270 if (attrs[i]) { 4271 name = attrs[i].name; 4272 if (name.indexOf("data-") === 0) { 4273 name = camelCase(name.slice(5)); 4274 dataAttr(elem, name, data[name]); 4275 } 4276 } 4277 } 4278 dataPriv.set(elem, "hasDataAttrs", true); 4279 } 4280 } 4281 4282 return data; 4283 } 4284 4285 // Sets multiple values 4286 if (typeof key === "object") { 4287 return this.each(function () { 4288 dataUser.set(this, key); 4289 }); 4290 } 4291 4292 return access(this, function (value) { 4293 var data; 4294 4295 // The calling jQuery object (element matches) is not empty 4296 // (and therefore has an element appears at this[ 0 ]) and the 4297 // `value` parameter was not undefined. An empty jQuery object 4298 // will result in `undefined` for elem = this[ 0 ] which will 4299 // throw an exception if an attempt to read a data cache is made. 4300 if (elem && value === undefined) { 4301 4302 // Attempt to get data from the cache 4303 // The key will always be camelCased in Data 4304 data = dataUser.get(elem, key); 4305 if (data !== undefined) { 4306 return data; 4307 } 4308 4309 // Attempt to "discover" the data in 4310 // HTML5 custom data-* attrs 4311 data = dataAttr(elem, key); 4312 if (data !== undefined) { 4313 return data; 4314 } 4315 4316 // We tried really hard, but the data doesn't exist. 4317 return; 4318 } 4319 4320 // Set the data... 4321 this.each(function () { 4322 4323 // We always store the camelCased key 4324 dataUser.set(this, key, value); 4325 }); 4326 }, null, value, arguments.length > 1, null, true); 4327 }, 4328 4329 removeData: function (key) { 4330 return this.each(function () { 4331 dataUser.remove(this, key); 4332 }); 4333 } 4334 }); 4335 4336 4337 jQuery.extend({ 4338 queue: function (elem, type, data) { 4339 var queue; 4340 4341 if (elem) { 4342 type = (type || "fx") + "queue"; 4343 queue = dataPriv.get(elem, type); 4344 4345 // Speed up dequeue by getting out quickly if this is just a lookup 4346 if (data) { 4347 if (!queue || Array.isArray(data)) { 4348 queue = dataPriv.access(elem, type, jQuery.makeArray(data)); 4349 } else { 4350 queue.push(data); 4351 } 4352 } 4353 return queue || []; 4354 } 4355 }, 4356 4357 dequeue: function (elem, type) { 4358 type = type || "fx"; 4359 4360 var queue = jQuery.queue(elem, type), 4361 startLength = queue.length, 4362 fn = queue.shift(), 4363 hooks = jQuery._queueHooks(elem, type), 4364 next = function () { 4365 jQuery.dequeue(elem, type); 4366 }; 4367 4368 // If the fx queue is dequeued, always remove the progress sentinel 4369 if (fn === "inprogress") { 4370 fn = queue.shift(); 4371 startLength--; 4372 } 4373 4374 if (fn) { 4375 4376 // Add a progress sentinel to prevent the fx queue from being 4377 // automatically dequeued 4378 if (type === "fx") { 4379 queue.unshift("inprogress"); 4380 } 4381 4382 // Clear up the last queue stop function 4383 delete hooks.stop; 4384 fn.call(elem, next, hooks); 4385 } 4386 4387 if (!startLength && hooks) { 4388 hooks.empty.fire(); 4389 } 4390 }, 4391 4392 // Not public - generate a queueHooks object, or return the current one 4393 _queueHooks: function (elem, type) { 4394 var key = type + "queueHooks"; 4395 return dataPriv.get(elem, key) || dataPriv.access(elem, key, { 4396 empty: jQuery.Callbacks("once memory").add(function () { 4397 dataPriv.remove(elem, [type + "queue", key]); 4398 }) 4399 }); 4400 } 4401 }); 4402 4403 jQuery.fn.extend({ 4404 queue: function (type, data) { 4405 var setter = 2; 4406 4407 if (typeof type !== "string") { 4408 data = type; 4409 type = "fx"; 4410 setter--; 4411 } 4412 4413 if (arguments.length < setter) { 4414 return jQuery.queue(this[0], type); 4415 } 4416 4417 return data === undefined ? 4418 this : 4419 this.each(function () { 4420 var queue = jQuery.queue(this, type, data); 4421 4422 // Ensure a hooks for this queue 4423 jQuery._queueHooks(this, type); 4424 4425 if (type === "fx" && queue[0] !== "inprogress") { 4426 jQuery.dequeue(this, type); 4427 } 4428 }); 4429 }, 4430 dequeue: function (type) { 4431 return this.each(function () { 4432 jQuery.dequeue(this, type); 4433 }); 4434 }, 4435 clearQueue: function (type) { 4436 return this.queue(type || "fx", []); 4437 }, 4438 4439 // Get a promise resolved when queues of a certain type 4440 // are emptied (fx is the type by default) 4441 promise: function (type, obj) { 4442 var tmp, 4443 count = 1, 4444 defer = jQuery.Deferred(), 4445 elements = this, 4446 i = this.length, 4447 resolve = function () { 4448 if (! --count) { 4449 defer.resolveWith(elements, [elements]); 4450 } 4451 }; 4452 4453 if (typeof type !== "string") { 4454 obj = type; 4455 type = undefined; 4456 } 4457 type = type || "fx"; 4458 4459 while (i--) { 4460 tmp = dataPriv.get(elements[i], type + "queueHooks"); 4461 if (tmp && tmp.empty) { 4462 count++; 4463 tmp.empty.add(resolve); 4464 } 4465 } 4466 resolve(); 4467 return defer.promise(obj); 4468 } 4469 }); 4470 var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; 4471
vendor: 4,324 bytes, lines 4472-4624
4472 var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i"); 4473 4474 4475 var cssExpand = ["Top", "Right", "Bottom", "Left"]; 4476 4477 var documentElement = document.documentElement; 4478 4479 4480 4481 var isAttached = function (elem) { 4482 return jQuery.contains(elem.ownerDocument, elem); 4483 }, 4484 composed = { composed: true }; 4485 4486 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 4487 // Check attachment across shadow DOM boundaries when possible (gh-3504) 4488 // Support: iOS 10.0-10.2 only 4489 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 4490 // leading to errors. We need to check for `getRootNode`. 4491 if (documentElement.getRootNode) { 4492 isAttached = function (elem) { 4493 return jQuery.contains(elem.ownerDocument, elem) || 4494 elem.getRootNode(composed) === elem.ownerDocument; 4495 }; 4496 } 4497 var isHiddenWithinTree = function (elem, el) { 4498 4499 // isHiddenWithinTree might be called from jQuery#filter function; 4500 // in that case, element will be second argument 4501 elem = el || elem; 4502 4503 // Inline style trumps all 4504 return elem.style.display === "none" || 4505 elem.style.display === "" && 4506 4507 // Otherwise, check computed style 4508 // Support: Firefox <=43 - 45 4509 // Disconnected elements can have computed display: none, so first confirm that elem is 4510 // in the document. 4511 isAttached(elem) && 4512 4513 jQuery.css(elem, "display") === "none"; 4514 }; 4515 4516 4517 4518 function adjustCSS(elem, prop, valueParts, tween) { 4519 var adjusted,scale, 4520 maxIterations = 20, 4521 currentValue = tween ? 4522 function () { 4523 return tween.cur(); 4524 } : 4525 function () { 4526 return jQuery.css(elem, prop, ""); 4527 }, 4528 initial = currentValue(), 4529 unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"), 4530 4531 // Starting value computation is required for potential unit mismatches 4532 initialInUnit = elem.nodeType && ( 4533 jQuery.cssNumber[prop] || unit !== "px" && +initial) && 4534 rcssNum.exec(jQuery.css(elem, prop)); 4535 4536 if (initialInUnit && initialInUnit[3] !== unit) { 4537 4538 // Support: Firefox <=54 4539 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 4540 initial = initial / 2; 4541 4542 // Trust units reported by jQuery.css 4543 unit = unit || initialInUnit[3]; 4544 4545 // Iteratively approximate from a nonzero starting point 4546 initialInUnit = +initial || 1; 4547 4548 while (maxIterations--) { 4549 4550 // Evaluate and update our best guess (doubling guesses that zero out). 4551 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 4552 jQuery.style(elem, prop, initialInUnit + unit); 4553 if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) { 4554 maxIterations = 0; 4555 } 4556 initialInUnit = initialInUnit / scale; 4557 4558 } 4559 4560 initialInUnit = initialInUnit * 2; 4561 jQuery.style(elem, prop, initialInUnit + unit); 4562 4563 // Make sure we update the tween properties later on 4564 valueParts = valueParts || []; 4565 } 4566 4567 if (valueParts) { 4568 initialInUnit = +initialInUnit || +initial || 0; 4569 4570 // Apply relative offset (+=/-=) if specified 4571 adjusted = valueParts[1] ? 4572 initialInUnit + (valueParts[1] + 1) * valueParts[2] : 4573 +valueParts[2]; 4574 if (tween) { 4575 tween.unit = unit; 4576 tween.start = initialInUnit; 4577 tween.end = adjusted; 4578 } 4579 } 4580 return adjusted; 4581 } 4582 4583 4584 var defaultDisplayMap = {}; 4585 4586 function getDefaultDisplay(elem) { 4587 var temp, 4588 doc = elem.ownerDocument, 4589 nodeName = elem.nodeName, 4590 display = defaultDisplayMap[nodeName]; 4591 4592 if (display) { 4593 return display; 4594 } 4595 4596 temp = doc.body.appendChild(doc.createElement(nodeName)); 4597 display = jQuery.css(temp, "display"); 4598 4599 temp.parentNode.removeChild(temp); 4600 4601 if (display === "none") { 4602 display = "block"; 4603 } 4604 defaultDisplayMap[nodeName] = display; 4605 4606 return display; 4607 } 4608 4609 function showHide(elements, show) { 4610 var display,elem, 4611 values = [], 4612 index = 0, 4613 length = elements.length; 4614 4615 // Determine new display value for elements that need to change 4616 for (; index < length; index++) { 4617 elem = elements[index]; 4618 if (!elem.style) { 4619 continue; 4620 } 4621 4622 display = elem.style.display; 4623 if (show) { 4624
vendor: 2,216 bytes, lines 4625-4701
4625 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 4626 // check is required in this first loop unless we have a nonempty display value (either 4627 // inline or about-to-be-restored) 4628 if (display === "none") { 4629 values[index] = dataPriv.get(elem, "display") || null; 4630 if (!values[index]) { 4631 elem.style.display = ""; 4632 } 4633 } 4634 if (elem.style.display === "" && isHiddenWithinTree(elem)) { 4635 values[index] = getDefaultDisplay(elem); 4636 } 4637 } else { 4638 if (display !== "none") { 4639 values[index] = "none"; 4640 4641 // Remember what we're overwriting 4642 dataPriv.set(elem, "display", display); 4643 } 4644 } 4645 } 4646 4647 // Set the display of the elements in a second loop to avoid constant reflow 4648 for (index = 0; index < length; index++) { 4649 if (values[index] != null) { 4650 elements[index].style.display = values[index]; 4651 } 4652 } 4653 4654 return elements; 4655 } 4656 4657 jQuery.fn.extend({ 4658 show: function () { 4659 return showHide(this, true); 4660 }, 4661 hide: function () { 4662 return showHide(this); 4663 }, 4664 toggle: function (state) { 4665 if (typeof state === "boolean") { 4666 return state ? this.show() : this.hide(); 4667 } 4668 4669 return this.each(function () { 4670 if (isHiddenWithinTree(this)) { 4671 jQuery(this).show(); 4672 } else { 4673 jQuery(this).hide(); 4674 } 4675 }); 4676 } 4677 }); 4678 var rcheckableType = /^(?:checkbox|radio)$/i; 4679 4680 var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i; 4681 4682 var rscriptType = /^$|^module$|\/(?:java|ecma)script/i; 4683 4684 4685 4686 (function () { 4687 var fragment = document.createDocumentFragment(), 4688 div = fragment.appendChild(document.createElement("div")), 4689 input = document.createElement("input"); 4690 4691 // Support: Android 4.0 - 4.3 only 4692 // Check state lost if the name is set (trac-11217) 4693 // Support: Windows Web Apps (WWA) 4694 // `name` and `type` must use .setAttribute for WWA (trac-14901) 4695 input.setAttribute("type", "radio"); 4696 input.setAttribute("checked", "checked"); 4697 input.setAttribute("name", "t"); 4698 4699 div.appendChild(input); 4700 4701 // Support: Android <=4.1 only
vendor: 10,689 bytes, lines 4702-5076
4702 // Older WebKit doesn't clone checked state correctly in fragments 4703 support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; 4704 4705 // Support: IE <=11 only 4706 // Make sure textarea (and checkbox) defaultValue is properly cloned 4707 div.innerHTML = "<textarea>x</textarea>"; 4708 support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; 4709 4710 // Support: IE <=9 only 4711 // IE <=9 replaces <option> tags with their contents when inserted outside of 4712 // the select element. 4713 div.innerHTML = "<option></option>"; 4714 support.option = !!div.lastChild; 4715 })(); 4716 4717 4718 // We have to close these tags to support XHTML (trac-13200) 4719 var wrapMap = { 4720 4721 // XHTML parsers do not magically insert elements in the 4722 // same way that tag soup parsers do. So we cannot shorten 4723 // this by omitting <tbody> or other required elements. 4724 thead: [1, "<table>", "</table>"], 4725 col: [2, "<table><colgroup>", "</colgroup></table>"], 4726 tr: [2, "<table><tbody>", "</tbody></table>"], 4727 td: [3, "<table><tbody><tr>", "</tr></tbody></table>"], 4728 4729 _default: [0, "", ""] 4730 }; 4731 4732 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 4733 wrapMap.th = wrapMap.td; 4734 4735 // Support: IE <=9 only 4736 if (!support.option) { 4737 wrapMap.optgroup = wrapMap.option = [1, "<select multiple='multiple'>", "</select>"]; 4738 } 4739 4740 4741 function getAll(context, tag) { 4742 4743 // Support: IE <=9 - 11 only 4744 // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) 4745 var ret; 4746 4747 if (typeof context.getElementsByTagName !== "undefined") { 4748 ret = context.getElementsByTagName(tag || "*"); 4749 4750 } else if (typeof context.querySelectorAll !== "undefined") { 4751 ret = context.querySelectorAll(tag || "*"); 4752 4753 } else { 4754 ret = []; 4755 } 4756 4757 if (tag === undefined || tag && nodeName(context, tag)) { 4758 return jQuery.merge([context], ret); 4759 } 4760 4761 return ret; 4762 } 4763 4764 4765 // Mark scripts as having already been evaluated 4766 function setGlobalEval(elems, refElements) { 4767 var i = 0, 4768 l = elems.length; 4769 4770 for (; i < l; i++) { 4771 dataPriv.set( 4772 elems[i], 4773 "globalEval", 4774 !refElements || dataPriv.get(refElements[i], "globalEval") 4775 ); 4776 } 4777 } 4778 4779 4780 var rhtml = /<|&#?\w+;/; 4781 4782 function buildFragment(elems, context, scripts, selection, ignored) { 4783 var elem,tmp,tag,wrap,attached,j, 4784 fragment = context.createDocumentFragment(), 4785 nodes = [], 4786 i = 0, 4787 l = elems.length; 4788 4789 for (; i < l; i++) { 4790 elem = elems[i]; 4791 4792 if (elem || elem === 0) { 4793 4794 // Add nodes directly 4795 if (toType(elem) === "object") { 4796 4797 // Support: Android <=4.0 only, PhantomJS 1 only 4798 // push.apply(_, arraylike) throws on ancient WebKit 4799 jQuery.merge(nodes, elem.nodeType ? [elem] : elem); 4800 4801 // Convert non-html into a text node 4802 } else if (!rhtml.test(elem)) { 4803 nodes.push(context.createTextNode(elem)); 4804 4805 // Convert html into DOM nodes 4806 } else { 4807 tmp = tmp || fragment.appendChild(context.createElement("div")); 4808 4809 // Deserialize a standard representation 4810 tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase(); 4811 wrap = wrapMap[tag] || wrapMap._default; 4812 tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; 4813 4814 // Descend through wrappers to the right content 4815 j = wrap[0]; 4816 while (j--) { 4817 tmp = tmp.lastChild; 4818 } 4819 4820 // Support: Android <=4.0 only, PhantomJS 1 only 4821 // push.apply(_, arraylike) throws on ancient WebKit 4822 jQuery.merge(nodes, tmp.childNodes); 4823 4824 // Remember the top-level container 4825 tmp = fragment.firstChild; 4826 4827 // Ensure the created nodes are orphaned (trac-12392) 4828 tmp.textContent = ""; 4829 } 4830 } 4831 } 4832 4833 // Remove wrapper from fragment 4834 fragment.textContent = ""; 4835 4836 i = 0; 4837 while (elem = nodes[i++]) { 4838 4839 // Skip elements already in the context collection (trac-4087) 4840 if (selection && jQuery.inArray(elem, selection) > -1) { 4841 if (ignored) { 4842 ignored.push(elem); 4843 } 4844 continue; 4845 } 4846 4847 attached = isAttached(elem); 4848 4849 // Append to fragment 4850 tmp = getAll(fragment.appendChild(elem), "script"); 4851 4852 // Preserve script evaluation history 4853 if (attached) { 4854 setGlobalEval(tmp); 4855 } 4856 4857 // Capture executables 4858 if (scripts) { 4859 j = 0; 4860 while (elem = tmp[j++]) { 4861 if (rscriptType.test(elem.type || "")) { 4862 scripts.push(elem); 4863 } 4864 } 4865 } 4866 } 4867 4868 return fragment; 4869 } 4870 4871 4872 var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 4873 4874 function returnTrue() { 4875 return true; 4876 } 4877 4878 function returnFalse() { 4879 return false; 4880 } 4881 4882 function on(elem, types, selector, data, fn, one) { 4883 var origFn, type; 4884 4885 // Types can be a map of types/handlers 4886 if (typeof types === "object") { 4887 4888 // ( types-Object, selector, data ) 4889 if (typeof selector !== "string") { 4890 4891 // ( types-Object, data ) 4892 data = data || selector; 4893 selector = undefined; 4894 } 4895 for (type in types) { 4896 on(elem, type, selector, data, types[type], one); 4897 } 4898 return elem; 4899 } 4900 4901 if (data == null && fn == null) { 4902 4903 // ( types, fn ) 4904 fn = selector; 4905 data = selector = undefined; 4906 } else if (fn == null) { 4907 if (typeof selector === "string") { 4908 4909 // ( types, selector, fn ) 4910 fn = data; 4911 data = undefined; 4912 } else { 4913 4914 // ( types, data, fn ) 4915 fn = data; 4916 data = selector; 4917 selector = undefined; 4918 } 4919 } 4920 if (fn === false) { 4921 fn = returnFalse; 4922 } else if (!fn) { 4923 return elem; 4924 } 4925 4926 if (one === 1) { 4927 origFn = fn; 4928 fn = function (event) { 4929 4930 // Can use an empty set, since event contains the info 4931 jQuery().off(event); 4932 return origFn.apply(this, arguments); 4933 }; 4934 4935 // Use same guid so caller can remove using origFn 4936 fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); 4937 } 4938 return elem.each(function () { 4939 jQuery.event.add(this, types, fn, data, selector); 4940 }); 4941 } 4942 4943 /* 4944 * Helper functions for managing events -- not part of the public interface. 4945 * Props to Dean Edwards' addEvent library for many of the ideas. 4946 */ 4947 jQuery.event = { 4948 4949 global: {}, 4950 4951 add: function (elem, types, handler, data, selector) { 4952 4953 var handleObjIn,eventHandle,tmp, 4954 events,t,handleObj, 4955 special,handlers,type,namespaces,origType, 4956 elemData = dataPriv.get(elem); 4957 4958 // Only attach events to objects that accept data 4959 if (!acceptData(elem)) { 4960 return; 4961 } 4962 4963 // Caller can pass in an object of custom data in lieu of the handler 4964 if (handler.handler) { 4965 handleObjIn = handler; 4966 handler = handleObjIn.handler; 4967 selector = handleObjIn.selector; 4968 } 4969 4970 // Ensure that invalid selectors throw exceptions at attach time 4971 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 4972 if (selector) { 4973 jQuery.find.matchesSelector(documentElement, selector); 4974 } 4975 4976 // Make sure that the handler has a unique ID, used to find/remove it later 4977 if (!handler.guid) { 4978 handler.guid = jQuery.guid++; 4979 } 4980 4981 // Init the element's event structure and main handler, if this is the first 4982 if (!(events = elemData.events)) { 4983 events = elemData.events = Object.create(null); 4984 } 4985 if (!(eventHandle = elemData.handle)) { 4986 eventHandle = elemData.handle = function (e) { 4987 4988 // Discard the second event of a jQuery.event.trigger() and 4989 // when an event is called after a page has unloaded 4990 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 4991 jQuery.event.dispatch.apply(elem, arguments) : undefined; 4992 }; 4993 } 4994 4995 // Handle multiple events separated by a space 4996 types = (types || "").match(rnothtmlwhite) || [""]; 4997 t = types.length; 4998 while (t--) { 4999 tmp = rtypenamespace.exec(types[t]) || []; 5000 type = origType = tmp[1]; 5001 namespaces = (tmp[2] || "").split(".").sort(); 5002 5003 // There *must* be a type, no attaching namespace-only handlers 5004 if (!type) { 5005 continue; 5006 } 5007 5008 // If event changes its type, use the special event handlers for the changed type 5009 special = jQuery.event.special[type] || {}; 5010 5011 // If selector defined, determine special event api type, otherwise given type 5012 type = (selector ? special.delegateType : special.bindType) || type; 5013 5014 // Update special based on newly reset type 5015 special = jQuery.event.special[type] || {}; 5016 5017 // handleObj is passed to all event handlers 5018 handleObj = jQuery.extend({ 5019 type: type, 5020 origType: origType, 5021 data: data, 5022 handler: handler, 5023 guid: handler.guid, 5024 selector: selector, 5025 needsContext: selector && jQuery.expr.match.needsContext.test(selector), 5026 namespace: namespaces.join(".") 5027 }, handleObjIn); 5028 5029 // Init the event handler queue if we're the first 5030 if (!(handlers = events[type])) { 5031 handlers = events[type] = []; 5032 handlers.delegateCount = 0; 5033 5034 // Only use addEventListener if the special events handler returns false 5035 if (!special.setup || 5036 special.setup.call(elem, data, namespaces, eventHandle) === false) { 5037 5038 if (elem.addEventListener) { 5039 elem.addEventListener(type, eventHandle); 5040 } 5041 } 5042 } 5043 5044 if (special.add) { 5045 special.add.call(elem, handleObj); 5046 5047 if (!handleObj.handler.guid) { 5048 handleObj.handler.guid = handler.guid; 5049 } 5050 } 5051 5052 // Add to the element's handler list, delegates in front 5053 if (selector) { 5054 handlers.splice(handlers.delegateCount++, 0, handleObj); 5055 } else { 5056 handlers.push(handleObj); 5057 } 5058 5059 // Keep track of which events have ever been used, for event optimization 5060 jQuery.event.global[type] = true; 5061 } 5062 5063 }, 5064 5065 // Detach an event or set of events from an element 5066 remove: function (elem, types, handler, selector, mappedTypes) { 5067 5068 var j,origCount,tmp, 5069 events,t,handleObj, 5070 special,handlers,type,namespaces,origType, 5071 elemData = dataPriv.hasData(elem) && dataPriv.get(elem); 5072 5073 if (!elemData || !(events = elemData.events)) { 5074 return; 5075 } 5076
vendor: 4,614 bytes, lines 5077-5215
5077 // Once for each type.namespace in types; type may be omitted 5078 types = (types || "").match(rnothtmlwhite) || [""]; 5079 t = types.length; 5080 while (t--) { 5081 tmp = rtypenamespace.exec(types[t]) || []; 5082 type = origType = tmp[1]; 5083 namespaces = (tmp[2] || "").split(".").sort(); 5084 5085 // Unbind all events (on this namespace, if provided) for the element 5086 if (!type) { 5087 for (type in events) { 5088 jQuery.event.remove(elem, type + types[t], handler, selector, true); 5089 } 5090 continue; 5091 } 5092 5093 special = jQuery.event.special[type] || {}; 5094 type = (selector ? special.delegateType : special.bindType) || type; 5095 handlers = events[type] || []; 5096 tmp = tmp[2] && 5097 new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); 5098 5099 // Remove matching events 5100 origCount = j = handlers.length; 5101 while (j--) { 5102 handleObj = handlers[j]; 5103 5104 if ((mappedTypes || origType === handleObj.origType) && ( 5105 !handler || handler.guid === handleObj.guid) && ( 5106 !tmp || tmp.test(handleObj.namespace)) && ( 5107 !selector || selector === handleObj.selector || 5108 selector === "**" && handleObj.selector)) { 5109 handlers.splice(j, 1); 5110 5111 if (handleObj.selector) { 5112 handlers.delegateCount--; 5113 } 5114 if (special.remove) { 5115 special.remove.call(elem, handleObj); 5116 } 5117 } 5118 } 5119 5120 // Remove generic event handler if we removed something and no more handlers exist 5121 // (avoids potential for endless recursion during removal of special event handlers) 5122 if (origCount && !handlers.length) { 5123 if (!special.teardown || 5124 special.teardown.call(elem, namespaces, elemData.handle) === false) { 5125 5126 jQuery.removeEvent(elem, type, elemData.handle); 5127 } 5128 5129 delete events[type]; 5130 } 5131 } 5132 5133 // Remove data and the expando if it's no longer used 5134 if (jQuery.isEmptyObject(events)) { 5135 dataPriv.remove(elem, "handle events"); 5136 } 5137 }, 5138 5139 dispatch: function (nativeEvent) { 5140 5141 var i,j,ret,matched,handleObj,handlerQueue, 5142 args = new Array(arguments.length), 5143 5144 // Make a writable jQuery.Event from the native event object 5145 event = jQuery.event.fix(nativeEvent), 5146 5147 handlers = ( 5148 dataPriv.get(this, "events") || Object.create(null))[ 5149 event.type] || [], 5150 special = jQuery.event.special[event.type] || {}; 5151 5152 // Use the fix-ed jQuery.Event rather than the (read-only) native event 5153 args[0] = event; 5154 5155 for (i = 1; i < arguments.length; i++) { 5156 args[i] = arguments[i]; 5157 } 5158 5159 event.delegateTarget = this; 5160 5161 // Call the preDispatch hook for the mapped type, and let it bail if desired 5162 if (special.preDispatch && special.preDispatch.call(this, event) === false) { 5163 return; 5164 } 5165 5166 // Determine handlers 5167 handlerQueue = jQuery.event.handlers.call(this, event, handlers); 5168 5169 // Run delegates first; they may want to stop propagation beneath us 5170 i = 0; 5171 while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { 5172 event.currentTarget = matched.elem; 5173 5174 j = 0; 5175 while ((handleObj = matched.handlers[j++]) && 5176 !event.isImmediatePropagationStopped()) { 5177 5178 // If the event is namespaced, then each handler is only invoked if it is 5179 // specially universal or its namespaces are a superset of the event's. 5180 if (!event.rnamespace || handleObj.namespace === false || 5181 event.rnamespace.test(handleObj.namespace)) { 5182 5183 event.handleObj = handleObj; 5184 event.data = handleObj.data; 5185 5186 ret = ((jQuery.event.special[handleObj.origType] || {}).handle || 5187 handleObj.handler).apply(matched.elem, args); 5188 5189 if (ret !== undefined) { 5190 if ((event.result = ret) === false) { 5191 event.preventDefault(); 5192 event.stopPropagation(); 5193 } 5194 } 5195 } 5196 } 5197 } 5198 5199 // Call the postDispatch hook for the mapped type 5200 if (special.postDispatch) { 5201 special.postDispatch.call(this, event); 5202 } 5203 5204 return event.result; 5205 }, 5206 5207 handlers: function (event, handlers) { 5208 var i,handleObj,sel,matchedHandlers,matchedSelectors, 5209 handlerQueue = [], 5210 delegateCount = handlers.delegateCount, 5211 cur = event.target; 5212 5213 // Find delegate handlers 5214 if (delegateCount && 5215
vendor: 66,008 bytes, lines 5216-7320
5216 // Support: IE <=9 5217 // Black-hole SVG <use> instance trees (trac-13180) 5218 cur.nodeType && 5219 5220 // Support: Firefox <=42 5221 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 5222 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 5223 // Support: IE 11 only 5224 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 5225 !(event.type === "click" && event.button >= 1)) { 5226 5227 for (; cur !== this; cur = cur.parentNode || this) { 5228 5229 // Don't check non-elements (trac-13208) 5230 // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) 5231 if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) { 5232 matchedHandlers = []; 5233 matchedSelectors = {}; 5234 for (i = 0; i < delegateCount; i++) { 5235 handleObj = handlers[i]; 5236 5237 // Don't conflict with Object.prototype properties (trac-13203) 5238 sel = handleObj.selector + " "; 5239 5240 if (matchedSelectors[sel] === undefined) { 5241 matchedSelectors[sel] = handleObj.needsContext ? 5242 jQuery(sel, this).index(cur) > -1 : 5243 jQuery.find(sel, this, null, [cur]).length; 5244 } 5245 if (matchedSelectors[sel]) { 5246 matchedHandlers.push(handleObj); 5247 } 5248 } 5249 if (matchedHandlers.length) { 5250 handlerQueue.push({ elem: cur, handlers: matchedHandlers }); 5251 } 5252 } 5253 } 5254 } 5255 5256 // Add the remaining (directly-bound) handlers 5257 cur = this; 5258 if (delegateCount < handlers.length) { 5259 handlerQueue.push({ elem: cur, handlers: handlers.slice(delegateCount) }); 5260 } 5261 5262 return handlerQueue; 5263 }, 5264 5265 addProp: function (name, hook) { 5266 Object.defineProperty(jQuery.Event.prototype, name, { 5267 enumerable: true, 5268 configurable: true, 5269 5270 get: isFunction(hook) ? 5271 function () { 5272 if (this.originalEvent) { 5273 return hook(this.originalEvent); 5274 } 5275 } : 5276 function () { 5277 if (this.originalEvent) { 5278 return this.originalEvent[name]; 5279 } 5280 }, 5281 5282 set: function (value) { 5283 Object.defineProperty(this, name, { 5284 enumerable: true, 5285 configurable: true, 5286 writable: true, 5287 value: value 5288 }); 5289 } 5290 }); 5291 }, 5292 5293 fix: function (originalEvent) { 5294 return originalEvent[jQuery.expando] ? 5295 originalEvent : 5296 new jQuery.Event(originalEvent); 5297 }, 5298 5299 special: { 5300 load: { 5301 5302 // Prevent triggered image.load events from bubbling to window.load 5303 noBubble: true 5304 }, 5305 click: { 5306 5307 // Utilize native event to ensure correct state for checkable inputs 5308 setup: function (data) { 5309 5310 // For mutual compressibility with _default, replace `this` access with a local var. 5311 // `|| data` is dead code meant only to preserve the variable through minification. 5312 var el = this || data; 5313 5314 // Claim the first handler 5315 if (rcheckableType.test(el.type) && 5316 el.click && nodeName(el, "input")) { 5317 5318 // dataPriv.set( el, "click", ... ) 5319 leverageNative(el, "click", true); 5320 } 5321 5322 // Return false to allow normal processing in the caller 5323 return false; 5324 }, 5325 trigger: function (data) { 5326 5327 // For mutual compressibility with _default, replace `this` access with a local var. 5328 // `|| data` is dead code meant only to preserve the variable through minification. 5329 var el = this || data; 5330 5331 // Force setup before triggering a click 5332 if (rcheckableType.test(el.type) && 5333 el.click && nodeName(el, "input")) { 5334 5335 leverageNative(el, "click"); 5336 } 5337 5338 // Return non-false to allow normal event-path propagation 5339 return true; 5340 }, 5341 5342 // For cross-browser consistency, suppress native .click() on links 5343 // Also prevent it if we're currently inside a leveraged native-event stack 5344 _default: function (event) { 5345 var target = event.target; 5346 return rcheckableType.test(target.type) && 5347 target.click && nodeName(target, "input") && 5348 dataPriv.get(target, "click") || 5349 nodeName(target, "a"); 5350 } 5351 }, 5352 5353 beforeunload: { 5354 postDispatch: function (event) { 5355 5356 // Support: Firefox 20+ 5357 // Firefox doesn't alert if the returnValue field is not set. 5358 if (event.result !== undefined && event.originalEvent) { 5359 event.originalEvent.returnValue = event.result; 5360 } 5361 } 5362 } 5363 } 5364 }; 5365 5366 // Ensure the presence of an event listener that handles manually-triggered 5367 // synthetic events by interrupting progress until reinvoked in response to 5368 // *native* events that it fires directly, ensuring that state changes have 5369 // already occurred before other listeners are invoked. 5370 function leverageNative(el, type, isSetup) { 5371 5372 // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add 5373 if (!isSetup) { 5374 if (dataPriv.get(el, type) === undefined) { 5375 jQuery.event.add(el, type, returnTrue); 5376 } 5377 return; 5378 } 5379 5380 // Register the controller as a special universal handler for all event namespaces 5381 dataPriv.set(el, type, false); 5382 jQuery.event.add(el, type, { 5383 namespace: false, 5384 handler: function (event) { 5385 var result, 5386 saved = dataPriv.get(this, type); 5387 5388 if (event.isTrigger & 1 && this[type]) { 5389 5390 // Interrupt processing of the outer synthetic .trigger()ed event 5391 if (!saved) { 5392 5393 // Store arguments for use when handling the inner native event 5394 // There will always be at least one argument (an event object), so this array 5395 // will not be confused with a leftover capture object. 5396 saved = slice.call(arguments); 5397 dataPriv.set(this, type, saved); 5398 5399 // Trigger the native event and capture its result 5400 this[type](); 5401 result = dataPriv.get(this, type); 5402 dataPriv.set(this, type, false); 5403 5404 if (saved !== result) { 5405 5406 // Cancel the outer synthetic event 5407 event.stopImmediatePropagation(); 5408 event.preventDefault(); 5409 5410 return result; 5411 } 5412 5413 // If this is an inner synthetic event for an event with a bubbling surrogate 5414 // (focus or blur), assume that the surrogate already propagated from triggering 5415 // the native event and prevent that from happening again here. 5416 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 5417 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 5418 // less bad than duplication. 5419 } else if ((jQuery.event.special[type] || {}).delegateType) { 5420 event.stopPropagation(); 5421 } 5422 5423 // If this is a native event triggered above, everything is now in order 5424 // Fire an inner synthetic event with the original arguments 5425 } else if (saved) { 5426 5427 // ...and capture the result 5428 dataPriv.set(this, type, jQuery.event.trigger( 5429 saved[0], 5430 saved.slice(1), 5431 this 5432 )); 5433 5434 // Abort handling of the native event by all jQuery handlers while allowing 5435 // native handlers on the same element to run. On target, this is achieved 5436 // by stopping immediate propagation just on the jQuery event. However, 5437 // the native event is re-wrapped by a jQuery one on each level of the 5438 // propagation so the only way to stop it for jQuery is to stop it for 5439 // everyone via native `stopPropagation()`. This is not a problem for 5440 // focus/blur which don't bubble, but it does also stop click on checkboxes 5441 // and radios. We accept this limitation. 5442 event.stopPropagation(); 5443 event.isImmediatePropagationStopped = returnTrue; 5444 } 5445 } 5446 }); 5447 } 5448 5449 jQuery.removeEvent = function (elem, type, handle) { 5450 5451 // This "if" is needed for plain objects 5452 if (elem.removeEventListener) { 5453 elem.removeEventListener(type, handle); 5454 } 5455 }; 5456 5457 jQuery.Event = function (src, props) { 5458 5459 // Allow instantiation without the 'new' keyword 5460 if (!(this instanceof jQuery.Event)) { 5461 return new jQuery.Event(src, props); 5462 } 5463 5464 // Event object 5465 if (src && src.type) { 5466 this.originalEvent = src; 5467 this.type = src.type; 5468 5469 // Events bubbling up the document may have been marked as prevented 5470 // by a handler lower down the tree; reflect the correct value. 5471 this.isDefaultPrevented = src.defaultPrevented || 5472 src.defaultPrevented === undefined && 5473 5474 // Support: Android <=2.3 only 5475 src.returnValue === false ? 5476 returnTrue : 5477 returnFalse; 5478 5479 // Create target properties 5480 // Support: Safari <=6 - 7 only 5481 // Target should not be a text node (trac-504, trac-13143) 5482 this.target = src.target && src.target.nodeType === 3 ? 5483 src.target.parentNode : 5484 src.target; 5485 5486 this.currentTarget = src.currentTarget; 5487 this.relatedTarget = src.relatedTarget; 5488 5489 // Event type 5490 } else { 5491 this.type = src; 5492 } 5493 5494 // Put explicitly provided properties onto the event object 5495 if (props) { 5496 jQuery.extend(this, props); 5497 } 5498 5499 // Create a timestamp if incoming event doesn't have one 5500 this.timeStamp = src && src.timeStamp || Date.now(); 5501 5502 // Mark it as fixed 5503 this[jQuery.expando] = true; 5504 }; 5505 5506 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 5507 // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 5508 jQuery.Event.prototype = { 5509 constructor: jQuery.Event, 5510 isDefaultPrevented: returnFalse, 5511 isPropagationStopped: returnFalse, 5512 isImmediatePropagationStopped: returnFalse, 5513 isSimulated: false, 5514 5515 preventDefault: function () { 5516 var e = this.originalEvent; 5517 5518 this.isDefaultPrevented = returnTrue; 5519 5520 if (e && !this.isSimulated) { 5521 e.preventDefault(); 5522 } 5523 }, 5524 stopPropagation: function () { 5525 var e = this.originalEvent; 5526 5527 this.isPropagationStopped = returnTrue; 5528 5529 if (e && !this.isSimulated) { 5530 e.stopPropagation(); 5531 } 5532 }, 5533 stopImmediatePropagation: function () { 5534 var e = this.originalEvent; 5535 5536 this.isImmediatePropagationStopped = returnTrue; 5537 5538 if (e && !this.isSimulated) { 5539 e.stopImmediatePropagation(); 5540 } 5541 5542 this.stopPropagation(); 5543 } 5544 }; 5545 5546 // Includes all common event props including KeyEvent and MouseEvent specific props 5547 jQuery.each({ 5548 altKey: true, 5549 bubbles: true, 5550 cancelable: true, 5551 changedTouches: true, 5552 ctrlKey: true, 5553 detail: true, 5554 eventPhase: true, 5555 metaKey: true, 5556 pageX: true, 5557 pageY: true, 5558 shiftKey: true, 5559 view: true, 5560 "char": true, 5561 code: true, 5562 charCode: true, 5563 key: true, 5564 keyCode: true, 5565 button: true, 5566 buttons: true, 5567 clientX: true, 5568 clientY: true, 5569 offsetX: true, 5570 offsetY: true, 5571 pointerId: true, 5572 pointerType: true, 5573 screenX: true, 5574 screenY: true, 5575 targetTouches: true, 5576 toElement: true, 5577 touches: true, 5578 which: true 5579 }, jQuery.event.addProp); 5580 5581 jQuery.each({ focus: "focusin", blur: "focusout" }, function (type, delegateType) { 5582 5583 function focusMappedHandler(nativeEvent) { 5584 if (document.documentMode) { 5585 5586 // Support: IE 11+ 5587 // Attach a single focusin/focusout handler on the document while someone wants 5588 // focus/blur. This is because the former are synchronous in IE while the latter 5589 // are async. In other browsers, all those handlers are invoked synchronously. 5590 5591 // `handle` from private data would already wrap the event, but we need 5592 // to change the `type` here. 5593 var handle = dataPriv.get(this, "handle"), 5594 event = jQuery.event.fix(nativeEvent); 5595 event.type = nativeEvent.type === "focusin" ? "focus" : "blur"; 5596 event.isSimulated = true; 5597 5598 // First, handle focusin/focusout 5599 handle(nativeEvent); 5600 5601 // ...then, handle focus/blur 5602 // 5603 // focus/blur don't bubble while focusin/focusout do; simulate the former by only 5604 // invoking the handler at the lower level. 5605 if (event.target === event.currentTarget) { 5606 5607 // The setup part calls `leverageNative`, which, in turn, calls 5608 // `jQuery.event.add`, so event handle will already have been set 5609 // by this point. 5610 handle(event); 5611 } 5612 } else { 5613 5614 // For non-IE browsers, attach a single capturing handler on the document 5615 // while someone wants focusin/focusout. 5616 jQuery.event.simulate(delegateType, nativeEvent.target, 5617 jQuery.event.fix(nativeEvent)); 5618 } 5619 } 5620 5621 jQuery.event.special[type] = { 5622 5623 // Utilize native event if possible so blur/focus sequence is correct 5624 setup: function () { 5625 5626 var attaches; 5627 5628 // Claim the first handler 5629 // dataPriv.set( this, "focus", ... ) 5630 // dataPriv.set( this, "blur", ... ) 5631 leverageNative(this, type, true); 5632 5633 if (document.documentMode) { 5634 5635 // Support: IE 9 - 11+ 5636 // We use the same native handler for focusin & focus (and focusout & blur) 5637 // so we need to coordinate setup & teardown parts between those events. 5638 // Use `delegateType` as the key as `type` is already used by `leverageNative`. 5639 attaches = dataPriv.get(this, delegateType); 5640 if (!attaches) { 5641 this.addEventListener(delegateType, focusMappedHandler); 5642 } 5643 dataPriv.set(this, delegateType, (attaches || 0) + 1); 5644 } else { 5645 5646 // Return false to allow normal processing in the caller 5647 return false; 5648 } 5649 }, 5650 trigger: function () { 5651 5652 // Force setup before trigger 5653 leverageNative(this, type); 5654 5655 // Return non-false to allow normal event-path propagation 5656 return true; 5657 }, 5658 5659 teardown: function () { 5660 var attaches; 5661 5662 if (document.documentMode) { 5663 attaches = dataPriv.get(this, delegateType) - 1; 5664 if (!attaches) { 5665 this.removeEventListener(delegateType, focusMappedHandler); 5666 dataPriv.remove(this, delegateType); 5667 } else { 5668 dataPriv.set(this, delegateType, attaches); 5669 } 5670 } else { 5671 5672 // Return false to indicate standard teardown should be applied 5673 return false; 5674 } 5675 }, 5676 5677 // Suppress native focus or blur if we're currently inside 5678 // a leveraged native-event stack 5679 _default: function (event) { 5680 return dataPriv.get(event.target, type); 5681 }, 5682 5683 delegateType: delegateType 5684 }; 5685 5686 // Support: Firefox <=44 5687 // Firefox doesn't have focus(in | out) events 5688 // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 5689 // 5690 // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 5691 // focus(in | out) events fire after focus & blur events, 5692 // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 5693 // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 5694 // 5695 // Support: IE 9 - 11+ 5696 // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch, 5697 // attach a single handler for both events in IE. 5698 jQuery.event.special[delegateType] = { 5699 setup: function () { 5700 5701 // Handle: regular nodes (via `this.ownerDocument`), window 5702 // (via `this.document`) & document (via `this`). 5703 var doc = this.ownerDocument || this.document || this, 5704 dataHolder = document.documentMode ? this : doc, 5705 attaches = dataPriv.get(dataHolder, delegateType); 5706 5707 // Support: IE 9 - 11+ 5708 // We use the same native handler for focusin & focus (and focusout & blur) 5709 // so we need to coordinate setup & teardown parts between those events. 5710 // Use `delegateType` as the key as `type` is already used by `leverageNative`. 5711 if (!attaches) { 5712 if (document.documentMode) { 5713 this.addEventListener(delegateType, focusMappedHandler); 5714 } else { 5715 doc.addEventListener(type, focusMappedHandler, true); 5716 } 5717 } 5718 dataPriv.set(dataHolder, delegateType, (attaches || 0) + 1); 5719 }, 5720 teardown: function () { 5721 var doc = this.ownerDocument || this.document || this, 5722 dataHolder = document.documentMode ? this : doc, 5723 attaches = dataPriv.get(dataHolder, delegateType) - 1; 5724 5725 if (!attaches) { 5726 if (document.documentMode) { 5727 this.removeEventListener(delegateType, focusMappedHandler); 5728 } else { 5729 doc.removeEventListener(type, focusMappedHandler, true); 5730 } 5731 dataPriv.remove(dataHolder, delegateType); 5732 } else { 5733 dataPriv.set(dataHolder, delegateType, attaches); 5734 } 5735 } 5736 }; 5737 }); 5738 5739 // Create mouseenter/leave events using mouseover/out and event-time checks 5740 // so that event delegation works in jQuery. 5741 // Do the same for pointerenter/pointerleave and pointerover/pointerout 5742 // 5743 // Support: Safari 7 only 5744 // Safari sends mouseenter too often; see: 5745 // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 5746 // for the description of the bug (it existed in older Chrome versions as well). 5747 jQuery.each({ 5748 mouseenter: "mouseover", 5749 mouseleave: "mouseout", 5750 pointerenter: "pointerover", 5751 pointerleave: "pointerout" 5752 }, function (orig, fix) { 5753 jQuery.event.special[orig] = { 5754 delegateType: fix, 5755 bindType: fix, 5756 5757 handle: function (event) { 5758 var ret, 5759 target = this, 5760 related = event.relatedTarget, 5761 handleObj = event.handleObj; 5762 5763 // For mouseenter/leave call the handler if related is outside the target. 5764 // NB: No relatedTarget if the mouse left/entered the browser window 5765 if (!related || related !== target && !jQuery.contains(target, related)) { 5766 event.type = handleObj.origType; 5767 ret = handleObj.handler.apply(this, arguments); 5768 event.type = fix; 5769 } 5770 return ret; 5771 } 5772 }; 5773 }); 5774 5775 jQuery.fn.extend({ 5776 5777 on: function (types, selector, data, fn) { 5778 return on(this, types, selector, data, fn); 5779 }, 5780 one: function (types, selector, data, fn) { 5781 return on(this, types, selector, data, fn, 1); 5782 }, 5783 off: function (types, selector, fn) { 5784 var handleObj, type; 5785 if (types && types.preventDefault && types.handleObj) { 5786 5787 // ( event ) dispatched jQuery.Event 5788 handleObj = types.handleObj; 5789 jQuery(types.delegateTarget).off( 5790 handleObj.namespace ? 5791 handleObj.origType + "." + handleObj.namespace : 5792 handleObj.origType, 5793 handleObj.selector, 5794 handleObj.handler 5795 ); 5796 return this; 5797 } 5798 if (typeof types === "object") { 5799 5800 // ( types-object [, selector] ) 5801 for (type in types) { 5802 this.off(type, selector, types[type]); 5803 } 5804 return this; 5805 } 5806 if (selector === false || typeof selector === "function") { 5807 5808 // ( types [, fn] ) 5809 fn = selector; 5810 selector = undefined; 5811 } 5812 if (fn === false) { 5813 fn = returnFalse; 5814 } 5815 return this.each(function () { 5816 jQuery.event.remove(this, types, fn, selector); 5817 }); 5818 } 5819 }); 5820 5821 5822 var 5823 5824 // Support: IE <=10 - 11, Edge 12 - 13 only 5825 // In IE/Edge using regex groups here causes severe slowdowns. 5826 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 5827 rnoInnerhtml = /<script|<style|<link/i, 5828 5829 // checked="checked" or checked 5830 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5831 5832 rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g; 5833 5834 // Prefer a tbody over its parent table for containing new rows 5835 function manipulationTarget(elem, content) { 5836 if (nodeName(elem, "table") && 5837 nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) { 5838 5839 return jQuery(elem).children("tbody")[0] || elem; 5840 } 5841 5842 return elem; 5843 } 5844 5845 // Replace/restore the type attribute of script elements for safe DOM manipulation 5846 function disableScript(elem) { 5847 elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; 5848 return elem; 5849 } 5850 function restoreScript(elem) { 5851 if ((elem.type || "").slice(0, 5) === "true/") { 5852 elem.type = elem.type.slice(5); 5853 } else { 5854 elem.removeAttribute("type"); 5855 } 5856 5857 return elem; 5858 } 5859 5860 function cloneCopyEvent(src, dest) { 5861 var i, l, type, pdataOld, udataOld, udataCur, events; 5862 5863 if (dest.nodeType !== 1) { 5864 return; 5865 } 5866 5867 // 1. Copy private data: events, handlers, etc. 5868 if (dataPriv.hasData(src)) { 5869 pdataOld = dataPriv.get(src); 5870 events = pdataOld.events; 5871 5872 if (events) { 5873 dataPriv.remove(dest, "handle events"); 5874 5875 for (type in events) { 5876 for (i = 0, l = events[type].length; i < l; i++) { 5877 jQuery.event.add(dest, type, events[type][i]); 5878 } 5879 } 5880 } 5881 } 5882 5883 // 2. Copy user data 5884 if (dataUser.hasData(src)) { 5885 udataOld = dataUser.access(src); 5886 udataCur = jQuery.extend({}, udataOld); 5887 5888 dataUser.set(dest, udataCur); 5889 } 5890 } 5891 5892 // Fix IE bugs, see support tests 5893 function fixInput(src, dest) { 5894 var nodeName = dest.nodeName.toLowerCase(); 5895 5896 // Fails to persist the checked state of a cloned checkbox or radio button. 5897 if (nodeName === "input" && rcheckableType.test(src.type)) { 5898 dest.checked = src.checked; 5899 5900 // Fails to return the selected option to the default selected state when cloning options 5901 } else if (nodeName === "input" || nodeName === "textarea") { 5902 dest.defaultValue = src.defaultValue; 5903 } 5904 } 5905 5906 function domManip(collection, args, callback, ignored) { 5907 5908 // Flatten any nested arrays 5909 args = flat(args); 5910 5911 var fragment,first,scripts,hasScripts,node,doc, 5912 i = 0, 5913 l = collection.length, 5914 iNoClone = l - 1, 5915 value = args[0], 5916 valueIsFunction = isFunction(value); 5917 5918 // We can't cloneNode fragments that contain checked, in WebKit 5919 if (valueIsFunction || 5920 l > 1 && typeof value === "string" && 5921 !support.checkClone && rchecked.test(value)) { 5922 return collection.each(function (index) { 5923 var self = collection.eq(index); 5924 if (valueIsFunction) { 5925 args[0] = value.call(this, index, self.html()); 5926 } 5927 domManip(self, args, callback, ignored); 5928 }); 5929 } 5930 5931 if (l) { 5932 fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored); 5933 first = fragment.firstChild; 5934 5935 if (fragment.childNodes.length === 1) { 5936 fragment = first; 5937 } 5938 5939 // Require either new content or an interest in ignored elements to invoke the callback 5940 if (first || ignored) { 5941 scripts = jQuery.map(getAll(fragment, "script"), disableScript); 5942 hasScripts = scripts.length; 5943 5944 // Use the original fragment for the last item 5945 // instead of the first because it can end up 5946 // being emptied incorrectly in certain situations (trac-8070). 5947 for (; i < l; i++) { 5948 node = fragment; 5949 5950 if (i !== iNoClone) { 5951 node = jQuery.clone(node, true, true); 5952 5953 // Keep references to cloned scripts for later restoration 5954 if (hasScripts) { 5955 5956 // Support: Android <=4.0 only, PhantomJS 1 only 5957 // push.apply(_, arraylike) throws on ancient WebKit 5958 jQuery.merge(scripts, getAll(node, "script")); 5959 } 5960 } 5961 5962 callback.call(collection[i], node, i); 5963 } 5964 5965 if (hasScripts) { 5966 doc = scripts[scripts.length - 1].ownerDocument; 5967 5968 // Re-enable scripts 5969 jQuery.map(scripts, restoreScript); 5970 5971 // Evaluate executable scripts on first document insertion 5972 for (i = 0; i < hasScripts; i++) { 5973 node = scripts[i]; 5974 if (rscriptType.test(node.type || "") && 5975 !dataPriv.access(node, "globalEval") && 5976 jQuery.contains(doc, node)) { 5977 5978 if (node.src && (node.type || "").toLowerCase() !== "module") { 5979 5980 // Optional AJAX dependency, but won't run scripts if not present 5981 if (jQuery._evalUrl && !node.noModule) { 5982 jQuery._evalUrl(node.src, { 5983 nonce: node.nonce || node.getAttribute("nonce") 5984 }, doc); 5985 } 5986 } else { 5987 5988 // Unwrap a CDATA section containing script contents. This shouldn't be 5989 // needed as in XML documents they're already not visible when 5990 // inspecting element contents and in HTML documents they have no 5991 // meaning but we're preserving that logic for backwards compatibility. 5992 // This will be removed completely in 4.0. See gh-4904. 5993 DOMEval(node.textContent.replace(rcleanScript, ""), node, doc); 5994 } 5995 } 5996 } 5997 } 5998 } 5999 } 6000 6001 return collection; 6002 } 6003 6004 function remove(elem, selector, keepData) { 6005 var node, 6006 nodes = selector ? jQuery.filter(selector, elem) : elem, 6007 i = 0; 6008 6009 for (; (node = nodes[i]) != null; i++) { 6010 if (!keepData && node.nodeType === 1) { 6011 jQuery.cleanData(getAll(node)); 6012 } 6013 6014 if (node.parentNode) { 6015 if (keepData && isAttached(node)) { 6016 setGlobalEval(getAll(node, "script")); 6017 } 6018 node.parentNode.removeChild(node); 6019 } 6020 } 6021 6022 return elem; 6023 } 6024 6025 jQuery.extend({ 6026 htmlPrefilter: function (html) { 6027 return html; 6028 }, 6029 6030 clone: function (elem, dataAndEvents, deepDataAndEvents) { 6031 var i,l,srcElements,destElements, 6032 clone = elem.cloneNode(true), 6033 inPage = isAttached(elem); 6034 6035 // Fix IE cloning issues 6036 if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && 6037 !jQuery.isXMLDoc(elem)) { 6038 6039 // We eschew jQuery#find here for performance reasons: 6040 // https://jsperf.com/getall-vs-sizzle/2 6041 destElements = getAll(clone); 6042 srcElements = getAll(elem); 6043 6044 for (i = 0, l = srcElements.length; i < l; i++) { 6045 fixInput(srcElements[i], destElements[i]); 6046 } 6047 } 6048 6049 // Copy the events from the original to the clone 6050 if (dataAndEvents) { 6051 if (deepDataAndEvents) { 6052 srcElements = srcElements || getAll(elem); 6053 destElements = destElements || getAll(clone); 6054 6055 for (i = 0, l = srcElements.length; i < l; i++) { 6056 cloneCopyEvent(srcElements[i], destElements[i]); 6057 } 6058 } else { 6059 cloneCopyEvent(elem, clone); 6060 } 6061 } 6062 6063 // Preserve script evaluation history 6064 destElements = getAll(clone, "script"); 6065 if (destElements.length > 0) { 6066 setGlobalEval(destElements, !inPage && getAll(elem, "script")); 6067 } 6068 6069 // Return the cloned set 6070 return clone; 6071 }, 6072 6073 cleanData: function (elems) { 6074 var data,elem,type, 6075 special = jQuery.event.special, 6076 i = 0; 6077 6078 for (; (elem = elems[i]) !== undefined; i++) { 6079 if (acceptData(elem)) { 6080 if (data = elem[dataPriv.expando]) { 6081 if (data.events) { 6082 for (type in data.events) { 6083 if (special[type]) { 6084 jQuery.event.remove(elem, type); 6085 6086 // This is a shortcut to avoid jQuery.event.remove's overhead 6087 } else { 6088 jQuery.removeEvent(elem, type, data.handle); 6089 } 6090 } 6091 } 6092 6093 // Support: Chrome <=35 - 45+ 6094 // Assign undefined instead of using delete, see Data#remove 6095 elem[dataPriv.expando] = undefined; 6096 } 6097 if (elem[dataUser.expando]) { 6098 6099 // Support: Chrome <=35 - 45+ 6100 // Assign undefined instead of using delete, see Data#remove 6101 elem[dataUser.expando] = undefined; 6102 } 6103 } 6104 } 6105 } 6106 }); 6107 6108 jQuery.fn.extend({ 6109 detach: function (selector) { 6110 return remove(this, selector, true); 6111 }, 6112 6113 remove: function (selector) { 6114 return remove(this, selector); 6115 }, 6116 6117 text: function (value) { 6118 return access(this, function (value) { 6119 return value === undefined ? 6120 jQuery.text(this) : 6121 this.empty().each(function () { 6122 if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { 6123 this.textContent = value; 6124 } 6125 }); 6126 }, null, value, arguments.length); 6127 }, 6128 6129 append: function () { 6130 return domManip(this, arguments, function (elem) { 6131 if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { 6132 var target = manipulationTarget(this, elem); 6133 target.appendChild(elem); 6134 } 6135 }); 6136 }, 6137 6138 prepend: function () { 6139 return domManip(this, arguments, function (elem) { 6140 if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { 6141 var target = manipulationTarget(this, elem); 6142 target.insertBefore(elem, target.firstChild); 6143 } 6144 }); 6145 }, 6146 6147 before: function () { 6148 return domManip(this, arguments, function (elem) { 6149 if (this.parentNode) { 6150 this.parentNode.insertBefore(elem, this); 6151 } 6152 }); 6153 }, 6154 6155 after: function () { 6156 return domManip(this, arguments, function (elem) { 6157 if (this.parentNode) { 6158 this.parentNode.insertBefore(elem, this.nextSibling); 6159 } 6160 }); 6161 }, 6162 6163 empty: function () { 6164 var elem, 6165 i = 0; 6166 6167 for (; (elem = this[i]) != null; i++) { 6168 if (elem.nodeType === 1) { 6169 6170 // Prevent memory leaks 6171 jQuery.cleanData(getAll(elem, false)); 6172 6173 // Remove any remaining nodes 6174 elem.textContent = ""; 6175 } 6176 } 6177 6178 return this; 6179 }, 6180 6181 clone: function (dataAndEvents, deepDataAndEvents) { 6182 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 6183 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 6184 6185 return this.map(function () { 6186 return jQuery.clone(this, dataAndEvents, deepDataAndEvents); 6187 }); 6188 }, 6189 6190 html: function (value) { 6191 return access(this, function (value) { 6192 var elem = this[0] || {}, 6193 i = 0, 6194 l = this.length; 6195 6196 if (value === undefined && elem.nodeType === 1) { 6197 return elem.innerHTML; 6198 } 6199 6200 // See if we can take a shortcut and just use innerHTML 6201 if (typeof value === "string" && !rnoInnerhtml.test(value) && 6202 !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) { 6203 6204 value = jQuery.htmlPrefilter(value); 6205 6206 try { 6207 for (; i < l; i++) { 6208 elem = this[i] || {}; 6209 6210 // Remove element nodes and prevent memory leaks 6211 if (elem.nodeType === 1) { 6212 jQuery.cleanData(getAll(elem, false)); 6213 elem.innerHTML = value; 6214 } 6215 } 6216 6217 elem = 0; 6218 6219 // If using innerHTML throws an exception, use the fallback method 6220 } catch (e) {} 6221 } 6222 6223 if (elem) { 6224 this.empty().append(value); 6225 } 6226 }, null, value, arguments.length); 6227 }, 6228 6229 replaceWith: function () { 6230 var ignored = []; 6231 6232 // Make the changes, replacing each non-ignored context element with the new content 6233 return domManip(this, arguments, function (elem) { 6234 var parent = this.parentNode; 6235 6236 if (jQuery.inArray(this, ignored) < 0) { 6237 jQuery.cleanData(getAll(this)); 6238 if (parent) { 6239 parent.replaceChild(elem, this); 6240 } 6241 } 6242 6243 // Force callback invocation 6244 }, ignored); 6245 } 6246 }); 6247 6248 jQuery.each({ 6249 appendTo: "append", 6250 prependTo: "prepend", 6251 insertBefore: "before", 6252 insertAfter: "after", 6253 replaceAll: "replaceWith" 6254 }, function (name, original) { 6255 jQuery.fn[name] = function (selector) { 6256 var elems, 6257 ret = [], 6258 insert = jQuery(selector), 6259 last = insert.length - 1, 6260 i = 0; 6261 6262 for (; i <= last; i++) { 6263 elems = i === last ? this : this.clone(true); 6264 jQuery(insert[i])[original](elems); 6265 6266 // Support: Android <=4.0 only, PhantomJS 1 only 6267 // .get() because push.apply(_, arraylike) throws on ancient WebKit 6268 push.apply(ret, elems.get()); 6269 } 6270 6271 return this.pushStack(ret); 6272 }; 6273 }); 6274 var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i"); 6275 6276 var rcustomProp = /^--/; 6277 6278 6279 var getStyles = function (elem) { 6280 6281 // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150) 6282 // IE throws on elements created in popups 6283 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 6284 var view = elem.ownerDocument.defaultView; 6285 6286 if (!view || !view.opener) { 6287 view = window; 6288 } 6289 6290 return view.getComputedStyle(elem); 6291 }; 6292 6293 var swap = function (elem, options, callback) { 6294 var ret,name, 6295 old = {}; 6296 6297 // Remember the old values, and insert the new ones 6298 for (name in options) { 6299 old[name] = elem.style[name]; 6300 elem.style[name] = options[name]; 6301 } 6302 6303 ret = callback.call(elem); 6304 6305 // Revert the old values 6306 for (name in options) { 6307 elem.style[name] = old[name]; 6308 } 6309 6310 return ret; 6311 }; 6312 6313 6314 var rboxStyle = new RegExp(cssExpand.join("|"), "i"); 6315 6316 6317 6318 (function () { 6319 6320 // Executing both pixelPosition & boxSizingReliable tests require only one layout 6321 // so they're executed at the same time to save the second computation. 6322 function computeStyleTests() { 6323 6324 // This is a singleton, we need to execute it only once 6325 if (!div) { 6326 return; 6327 } 6328 6329 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 6330 "margin-top:1px;padding:0;border:0"; 6331 div.style.cssText = 6332 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 6333 "margin:auto;border:1px;padding:1px;" + 6334 "width:60%;top:1%"; 6335 documentElement.appendChild(container).appendChild(div); 6336 6337 var divStyle = window.getComputedStyle(div); 6338 pixelPositionVal = divStyle.top !== "1%"; 6339 6340 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 6341 reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; 6342 6343 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 6344 // Some styles come back with percentage values, even though they shouldn't 6345 div.style.right = "60%"; 6346 pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; 6347 6348 // Support: IE 9 - 11 only 6349 // Detect misreporting of content dimensions for box-sizing:border-box elements 6350 boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; 6351 6352 // Support: IE 9 only 6353 // Detect overflow:scroll screwiness (gh-3699) 6354 // Support: Chrome <=64 6355 // Don't get tricked when zoom affects offsetWidth (gh-4029) 6356 div.style.position = "absolute"; 6357 scrollboxSizeVal = roundPixelMeasures(div.offsetWidth / 3) === 12; 6358 6359 documentElement.removeChild(container); 6360 6361 // Nullify the div so it wouldn't be stored in the memory and 6362 // it will also be a sign that checks already performed 6363 div = null; 6364 } 6365 6366 function roundPixelMeasures(measure) { 6367 return Math.round(parseFloat(measure)); 6368 } 6369 6370 var pixelPositionVal,boxSizingReliableVal,scrollboxSizeVal,pixelBoxStylesVal, 6371 reliableTrDimensionsVal,reliableMarginLeftVal, 6372 container = document.createElement("div"), 6373 div = document.createElement("div"); 6374 6375 // Finish early in limited (non-browser) environments 6376 if (!div.style) { 6377 return; 6378 } 6379 6380 // Support: IE <=9 - 11 only 6381 // Style of cloned element affects source element cloned (trac-8908) 6382 div.style.backgroundClip = "content-box"; 6383 div.cloneNode(true).style.backgroundClip = ""; 6384 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 6385 6386 jQuery.extend(support, { 6387 boxSizingReliable: function () { 6388 computeStyleTests(); 6389 return boxSizingReliableVal; 6390 }, 6391 pixelBoxStyles: function () { 6392 computeStyleTests(); 6393 return pixelBoxStylesVal; 6394 }, 6395 pixelPosition: function () { 6396 computeStyleTests(); 6397 return pixelPositionVal; 6398 }, 6399 reliableMarginLeft: function () { 6400 computeStyleTests(); 6401 return reliableMarginLeftVal; 6402 }, 6403 scrollboxSize: function () { 6404 computeStyleTests(); 6405 return scrollboxSizeVal; 6406 }, 6407 6408 // Support: IE 9 - 11+, Edge 15 - 18+ 6409 // IE/Edge misreport `getComputedStyle` of table rows with width/height 6410 // set in CSS while `offset*` properties report correct values. 6411 // Behavior in IE 9 is more subtle than in newer versions & it passes 6412 // some versions of this test; make sure not to make it pass there! 6413 // 6414 // Support: Firefox 70+ 6415 // Only Firefox includes border widths 6416 // in computed dimensions. (gh-4529) 6417 reliableTrDimensions: function () { 6418 var table, tr, trChild, trStyle; 6419 if (reliableTrDimensionsVal == null) { 6420 table = document.createElement("table"); 6421 tr = document.createElement("tr"); 6422 trChild = document.createElement("div"); 6423 6424 table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; 6425 tr.style.cssText = "box-sizing:content-box;border:1px solid"; 6426 6427 // Support: Chrome 86+ 6428 // Height set through cssText does not get applied. 6429 // Computed height then comes back as 0. 6430 tr.style.height = "1px"; 6431 trChild.style.height = "9px"; 6432 6433 // Support: Android 8 Chrome 86+ 6434 // In our bodyBackground.html iframe, 6435 // display for all div elements is set to "inline", 6436 // which causes a problem only in Android 8 Chrome 86. 6437 // Ensuring the div is `display: block` 6438 // gets around this issue. 6439 trChild.style.display = "block"; 6440 6441 documentElement. 6442 appendChild(table). 6443 appendChild(tr). 6444 appendChild(trChild); 6445 6446 trStyle = window.getComputedStyle(tr); 6447 reliableTrDimensionsVal = parseInt(trStyle.height, 10) + 6448 parseInt(trStyle.borderTopWidth, 10) + 6449 parseInt(trStyle.borderBottomWidth, 10) === tr.offsetHeight; 6450 6451 documentElement.removeChild(table); 6452 } 6453 return reliableTrDimensionsVal; 6454 } 6455 }); 6456 })(); 6457 6458 6459 function curCSS(elem, name, computed) { 6460 var width,minWidth,maxWidth,ret, 6461 isCustomProp = rcustomProp.test(name), 6462 6463 // Support: Firefox 51+ 6464 // Retrieving style before computed somehow 6465 // fixes an issue with getting wrong values 6466 // on detached elements 6467 style = elem.style; 6468 6469 computed = computed || getStyles(elem); 6470 6471 // getPropertyValue is needed for: 6472 // .css('filter') (IE 9 only, trac-12537) 6473 // .css('--customProperty) (gh-3144) 6474 if (computed) { 6475 6476 // Support: IE <=9 - 11+ 6477 // IE only supports `"float"` in `getPropertyValue`; in computed styles 6478 // it's only available as `"cssFloat"`. We no longer modify properties 6479 // sent to `.css()` apart from camelCasing, so we need to check both. 6480 // Normally, this would create difference in behavior: if 6481 // `getPropertyValue` returns an empty string, the value returned 6482 // by `.css()` would be `undefined`. This is usually the case for 6483 // disconnected elements. However, in IE even disconnected elements 6484 // with no styles return `"none"` for `getPropertyValue( "float" )` 6485 ret = computed.getPropertyValue(name) || computed[name]; 6486 6487 if (isCustomProp && ret) { 6488 6489 // Support: Firefox 105+, Chrome <=105+ 6490 // Spec requires trimming whitespace for custom properties (gh-4926). 6491 // Firefox only trims leading whitespace. Chrome just collapses 6492 // both leading & trailing whitespace to a single space. 6493 // 6494 // Fall back to `undefined` if empty string returned. 6495 // This collapses a missing definition with property defined 6496 // and set to an empty string but there's no standard API 6497 // allowing us to differentiate them without a performance penalty 6498 // and returning `undefined` aligns with older jQuery. 6499 // 6500 // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED 6501 // as whitespace while CSS does not, but this is not a problem 6502 // because CSS preprocessing replaces them with U+000A LINE FEED 6503 // (which *is* CSS whitespace) 6504 // https://www.w3.org/TR/css-syntax-3/#input-preprocessing 6505 ret = ret.replace(rtrimCSS, "$1") || undefined; 6506 } 6507 6508 if (ret === "" && !isAttached(elem)) { 6509 ret = jQuery.style(elem, name); 6510 } 6511 6512 // A tribute to the "awesome hack by Dean Edwards" 6513 // Android Browser returns percentage for some values, 6514 // but width seems to be reliably pixels. 6515 // This is against the CSSOM draft spec: 6516 // https://drafts.csswg.org/cssom/#resolved-values 6517 if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) { 6518 6519 // Remember the original values 6520 width = style.width; 6521 minWidth = style.minWidth; 6522 maxWidth = style.maxWidth; 6523 6524 // Put in the new values to get a computed value out 6525 style.minWidth = style.maxWidth = style.width = ret; 6526 ret = computed.width; 6527 6528 // Revert the changed values 6529 style.width = width; 6530 style.minWidth = minWidth; 6531 style.maxWidth = maxWidth; 6532 } 6533 } 6534 6535 return ret !== undefined ? 6536 6537 // Support: IE <=9 - 11 only 6538 // IE returns zIndex value as an integer. 6539 ret + "" : 6540 ret; 6541 } 6542 6543 6544 function addGetHookIf(conditionFn, hookFn) { 6545 6546 // Define the hook, we'll check on the first run if it's really needed. 6547 return { 6548 get: function () { 6549 if (conditionFn()) { 6550 6551 // Hook not needed (or it's not possible to use it due 6552 // to missing dependency), remove it. 6553 delete this.get; 6554 return; 6555 } 6556 6557 // Hook needed; redefine it so that the support test is not executed again. 6558 return (this.get = hookFn).apply(this, arguments); 6559 } 6560 }; 6561 } 6562 6563 6564 var cssPrefixes = ["Webkit", "Moz", "ms"], 6565 emptyStyle = document.createElement("div").style, 6566 vendorProps = {}; 6567 6568 // Return a vendor-prefixed property or undefined 6569 function vendorPropName(name) { 6570 6571 // Check for vendor prefixed names 6572 var capName = name[0].toUpperCase() + name.slice(1), 6573 i = cssPrefixes.length; 6574 6575 while (i--) { 6576 name = cssPrefixes[i] + capName; 6577 if (name in emptyStyle) { 6578 return name; 6579 } 6580 } 6581 } 6582 6583 // Return a potentially-mapped jQuery.cssProps or vendor prefixed property 6584 function finalPropName(name) { 6585 var final = jQuery.cssProps[name] || vendorProps[name]; 6586 6587 if (final) { 6588 return final; 6589 } 6590 if (name in emptyStyle) { 6591 return name; 6592 } 6593 return vendorProps[name] = vendorPropName(name) || name; 6594 } 6595 6596 6597 var 6598 6599 // Swappable if display is none or starts with table 6600 // except "table", "table-cell", or "table-caption" 6601 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 6602 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 6603 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6604 cssNormalTransform = { 6605 letterSpacing: "0", 6606 fontWeight: "400" 6607 }; 6608 6609 function setPositiveNumber(_elem, value, subtract) { 6610 6611 // Any relative (+/-) values have already been 6612 // normalized at this point 6613 var matches = rcssNum.exec(value); 6614 return matches ? 6615 6616 // Guard against undefined "subtract", e.g., when used as in cssHooks 6617 Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : 6618 value; 6619 } 6620 6621 function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) { 6622 var i = dimension === "width" ? 1 : 0, 6623 extra = 0, 6624 delta = 0, 6625 marginDelta = 0; 6626 6627 // Adjustment may not be necessary 6628 if (box === (isBorderBox ? "border" : "content")) { 6629 return 0; 6630 } 6631 6632 for (; i < 4; i += 2) { 6633 6634 // Both box models exclude margin 6635 // Count margin delta separately to only add it after scroll gutter adjustment. 6636 // This is needed to make negative margins work with `outerHeight( true )` (gh-3982). 6637 if (box === "margin") { 6638 marginDelta += jQuery.css(elem, box + cssExpand[i], true, styles); 6639 } 6640 6641 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 6642 if (!isBorderBox) { 6643 6644 // Add padding 6645 delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles); 6646 6647 // For "border" or "margin", add border 6648 if (box !== "padding") { 6649 delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); 6650 6651 // But still keep track of it otherwise 6652 } else { 6653 extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); 6654 } 6655 6656 // If we get here with a border-box (content + padding + border), we're seeking "content" or 6657 // "padding" or "margin" 6658 } else { 6659 6660 // For "content", subtract padding 6661 if (box === "content") { 6662 delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles); 6663 } 6664 6665 // For "content" or "padding", subtract border 6666 if (box !== "margin") { 6667 delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); 6668 } 6669 } 6670 } 6671 6672 // Account for positive content-box scroll gutter when requested by providing computedVal 6673 if (!isBorderBox && computedVal >= 0) { 6674 6675 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 6676 // Assuming integer scroll gutter, subtract the rest and round down 6677 delta += Math.max(0, Math.ceil( 6678 elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - 6679 computedVal - 6680 delta - 6681 extra - 6682 0.5 6683 6684 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 6685 // Use an explicit zero to avoid NaN (gh-3964) 6686 )) || 0; 6687 } 6688 6689 return delta + marginDelta; 6690 } 6691 6692 function getWidthOrHeight(elem, dimension, extra) { 6693 6694 // Start with computed style 6695 var styles = getStyles(elem), 6696 6697 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 6698 // Fake content-box until we know it's needed to know the true value. 6699 boxSizingNeeded = !support.boxSizingReliable() || extra, 6700 isBorderBox = boxSizingNeeded && 6701 jQuery.css(elem, "boxSizing", false, styles) === "border-box", 6702 valueIsBorderBox = isBorderBox, 6703 6704 val = curCSS(elem, dimension, styles), 6705 offsetProp = "offset" + dimension[0].toUpperCase() + dimension.slice(1); 6706 6707 // Support: Firefox <=54 6708 // Return a confounding non-pixel value or feign ignorance, as appropriate. 6709 if (rnumnonpx.test(val)) { 6710 if (!extra) { 6711 return val; 6712 } 6713 val = "auto"; 6714 } 6715 6716 6717 // Support: IE 9 - 11 only 6718 // Use offsetWidth/offsetHeight for when box sizing is unreliable. 6719 // In those cases, the computed value can be trusted to be border-box. 6720 if ((!support.boxSizingReliable() && isBorderBox || 6721 6722 // Support: IE 10 - 11+, Edge 15 - 18+ 6723 // IE/Edge misreport `getComputedStyle` of table rows with width/height 6724 // set in CSS while `offset*` properties report correct values. 6725 // Interestingly, in some cases IE 9 doesn't suffer from this issue. 6726 !support.reliableTrDimensions() && nodeName(elem, "tr") || 6727 6728 // Fall back to offsetWidth/offsetHeight when value is "auto" 6729 // This happens for inline elements with no explicit setting (gh-3571) 6730 val === "auto" || 6731 6732 // Support: Android <=4.1 - 4.3 only 6733 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 6734 !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") && 6735 6736 // Make sure the element is visible & connected 6737 elem.getClientRects().length) { 6738 6739 isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box"; 6740 6741 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 6742 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 6743 // retrieved value as a content box dimension. 6744 valueIsBorderBox = offsetProp in elem; 6745 if (valueIsBorderBox) { 6746 val = elem[offsetProp]; 6747 } 6748 } 6749 6750 // Normalize "" and auto 6751 val = parseFloat(val) || 0; 6752 6753 // Adjust for the element's box model 6754 return val + 6755 boxModelAdjustment( 6756 elem, 6757 dimension, 6758 extra || (isBorderBox ? "border" : "content"), 6759 valueIsBorderBox, 6760 styles, 6761 6762 // Provide the current computed size to request scroll gutter calculation (gh-3589) 6763 val 6764 ) + 6765 "px"; 6766 } 6767 6768 jQuery.extend({ 6769 6770 // Add in style property hooks for overriding the default 6771 // behavior of getting and setting a style property 6772 cssHooks: { 6773 opacity: { 6774 get: function (elem, computed) { 6775 if (computed) { 6776 6777 // We should always get a number back from opacity 6778 var ret = curCSS(elem, "opacity"); 6779 return ret === "" ? "1" : ret; 6780 } 6781 } 6782 } 6783 }, 6784 6785 // Don't automatically add "px" to these possibly-unitless properties 6786 cssNumber: { 6787 animationIterationCount: true, 6788 aspectRatio: true, 6789 borderImageSlice: true, 6790 columnCount: true, 6791 flexGrow: true, 6792 flexShrink: true, 6793 fontWeight: true, 6794 gridArea: true, 6795 gridColumn: true, 6796 gridColumnEnd: true, 6797 gridColumnStart: true, 6798 gridRow: true, 6799 gridRowEnd: true, 6800 gridRowStart: true, 6801 lineHeight: true, 6802 opacity: true, 6803 order: true, 6804 orphans: true, 6805 scale: true, 6806 widows: true, 6807 zIndex: true, 6808 zoom: true, 6809 6810 // SVG-related 6811 fillOpacity: true, 6812 floodOpacity: true, 6813 stopOpacity: true, 6814 strokeMiterlimit: true, 6815 strokeOpacity: true 6816 }, 6817 6818 // Add in properties whose names you wish to fix before 6819 // setting or getting the value 6820 cssProps: {}, 6821 6822 // Get and set the style property on a DOM Node 6823 style: function (elem, name, value, extra) { 6824 6825 // Don't set styles on text and comment nodes 6826 if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { 6827 return; 6828 } 6829 6830 // Make sure that we're working with the right name 6831 var ret,type,hooks, 6832 origName = camelCase(name), 6833 isCustomProp = rcustomProp.test(name), 6834 style = elem.style; 6835 6836 // Make sure that we're working with the right name. We don't 6837 // want to query the value if it is a CSS custom property 6838 // since they are user-defined. 6839 if (!isCustomProp) { 6840 name = finalPropName(origName); 6841 } 6842 6843 // Gets hook for the prefixed version, then unprefixed version 6844 hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; 6845 6846 // Check if we're setting a value 6847 if (value !== undefined) { 6848 type = typeof value; 6849 6850 // Convert "+=" or "-=" to relative numbers (trac-7345) 6851 if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) { 6852 value = adjustCSS(elem, name, ret); 6853 6854 // Fixes bug trac-9237 6855 type = "number"; 6856 } 6857 6858 // Make sure that null and NaN values aren't set (trac-7116) 6859 if (value == null || value !== value) { 6860 return; 6861 } 6862 6863 // If a number was passed in, add the unit (except for certain CSS properties) 6864 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 6865 // "px" to a few hardcoded values. 6866 if (type === "number" && !isCustomProp) { 6867 value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px"); 6868 } 6869 6870 // background-* props affect original clone's values 6871 if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) { 6872 style[name] = "inherit"; 6873 } 6874 6875 // If a hook was provided, use that value, otherwise just set the specified value 6876 if (!hooks || !("set" in hooks) || 6877 (value = hooks.set(elem, value, extra)) !== undefined) { 6878 6879 if (isCustomProp) { 6880 style.setProperty(name, value); 6881 } else { 6882 style[name] = value; 6883 } 6884 } 6885 6886 } else { 6887 6888 // If a hook was provided get the non-computed value from there 6889 if (hooks && "get" in hooks && 6890 (ret = hooks.get(elem, false, extra)) !== undefined) { 6891 6892 return ret; 6893 } 6894 6895 // Otherwise just get the value from the style object 6896 return style[name]; 6897 } 6898 }, 6899 6900 css: function (elem, name, extra, styles) { 6901 var val,num,hooks, 6902 origName = camelCase(name), 6903 isCustomProp = rcustomProp.test(name); 6904 6905 // Make sure that we're working with the right name. We don't 6906 // want to modify the value if it is a CSS custom property 6907 // since they are user-defined. 6908 if (!isCustomProp) { 6909 name = finalPropName(origName); 6910 } 6911 6912 // Try prefixed name followed by the unprefixed name 6913 hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; 6914 6915 // If a hook was provided get the computed value from there 6916 if (hooks && "get" in hooks) { 6917 val = hooks.get(elem, true, extra); 6918 } 6919 6920 // Otherwise, if a way to get the computed value exists, use that 6921 if (val === undefined) { 6922 val = curCSS(elem, name, styles); 6923 } 6924 6925 // Convert "normal" to computed value 6926 if (val === "normal" && name in cssNormalTransform) { 6927 val = cssNormalTransform[name]; 6928 } 6929 6930 // Make numeric if forced or a qualifier was provided and val looks numeric 6931 if (extra === "" || extra) { 6932 num = parseFloat(val); 6933 return extra === true || isFinite(num) ? num || 0 : val; 6934 } 6935 6936 return val; 6937 } 6938 }); 6939 6940 jQuery.each(["height", "width"], function (_i, dimension) { 6941 jQuery.cssHooks[dimension] = { 6942 get: function (elem, computed, extra) { 6943 if (computed) { 6944 6945 // Certain elements can have dimension info if we invisibly show them 6946 // but it must have a current display style that would benefit 6947 return rdisplayswap.test(jQuery.css(elem, "display")) && ( 6948 6949 // Support: Safari 8+ 6950 // Table columns in Safari have non-zero offsetWidth & zero 6951 // getBoundingClientRect().width unless display is changed. 6952 // Support: IE <=11 only 6953 // Running getBoundingClientRect on a disconnected node 6954 // in IE throws an error. 6955 !elem.getClientRects().length || !elem.getBoundingClientRect().width) ? 6956 swap(elem, cssShow, function () { 6957 return getWidthOrHeight(elem, dimension, extra); 6958 }) : 6959 getWidthOrHeight(elem, dimension, extra); 6960 } 6961 }, 6962 6963 set: function (elem, value, extra) { 6964 var matches, 6965 styles = getStyles(elem), 6966 6967 // Only read styles.position if the test has a chance to fail 6968 // to avoid forcing a reflow. 6969 scrollboxSizeBuggy = !support.scrollboxSize() && 6970 styles.position === "absolute", 6971 6972 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 6973 boxSizingNeeded = scrollboxSizeBuggy || extra, 6974 isBorderBox = boxSizingNeeded && 6975 jQuery.css(elem, "boxSizing", false, styles) === "border-box", 6976 subtract = extra ? 6977 boxModelAdjustment( 6978 elem, 6979 dimension, 6980 extra, 6981 isBorderBox, 6982 styles 6983 ) : 6984 0; 6985 6986 // Account for unreliable border-box dimensions by comparing offset* to computed and 6987 // faking a content-box to get border and padding (gh-3699) 6988 if (isBorderBox && scrollboxSizeBuggy) { 6989 subtract -= Math.ceil( 6990 elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - 6991 parseFloat(styles[dimension]) - 6992 boxModelAdjustment(elem, dimension, "border", false, styles) - 6993 0.5 6994 ); 6995 } 6996 6997 // Convert to pixels if value adjustment is needed 6998 if (subtract && (matches = rcssNum.exec(value)) && 6999 (matches[3] || "px") !== "px") { 7000 7001 elem.style[dimension] = value; 7002 value = jQuery.css(elem, dimension); 7003 } 7004 7005 return setPositiveNumber(elem, value, subtract); 7006 } 7007 }; 7008 }); 7009 7010 jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, 7011 function (elem, computed) { 7012 if (computed) { 7013 return (parseFloat(curCSS(elem, "marginLeft")) || 7014 elem.getBoundingClientRect().left - 7015 swap(elem, { marginLeft: 0 }, function () { 7016 return elem.getBoundingClientRect().left; 7017 })) + 7018 "px"; 7019 } 7020 } 7021 ); 7022 7023 // These hooks are used by animate to expand properties 7024 jQuery.each({ 7025 margin: "", 7026 padding: "", 7027 border: "Width" 7028 }, function (prefix, suffix) { 7029 jQuery.cssHooks[prefix + suffix] = { 7030 expand: function (value) { 7031 var i = 0, 7032 expanded = {}, 7033 7034 // Assumes a single number if not a string 7035 parts = typeof value === "string" ? value.split(" ") : [value]; 7036 7037 for (; i < 4; i++) { 7038 expanded[prefix + cssExpand[i] + suffix] = 7039 parts[i] || parts[i - 2] || parts[0]; 7040 } 7041 7042 return expanded; 7043 } 7044 }; 7045 7046 if (prefix !== "margin") { 7047 jQuery.cssHooks[prefix + suffix].set = setPositiveNumber; 7048 } 7049 }); 7050 7051 jQuery.fn.extend({ 7052 css: function (name, value) { 7053 return access(this, function (elem, name, value) { 7054 var styles,len, 7055 map = {}, 7056 i = 0; 7057 7058 if (Array.isArray(name)) { 7059 styles = getStyles(elem); 7060 len = name.length; 7061 7062 for (; i < len; i++) { 7063 map[name[i]] = jQuery.css(elem, name[i], false, styles); 7064 } 7065 7066 return map; 7067 } 7068 7069 return value !== undefined ? 7070 jQuery.style(elem, name, value) : 7071 jQuery.css(elem, name); 7072 }, name, value, arguments.length > 1); 7073 } 7074 }); 7075 7076 7077 function Tween(elem, options, prop, end, easing) { 7078 return new Tween.prototype.init(elem, options, prop, end, easing); 7079 } 7080 jQuery.Tween = Tween; 7081 7082 Tween.prototype = { 7083 constructor: Tween, 7084 init: function (elem, options, prop, end, easing, unit) { 7085 this.elem = elem; 7086 this.prop = prop; 7087 this.easing = easing || jQuery.easing._default; 7088 this.options = options; 7089 this.start = this.now = this.cur(); 7090 this.end = end; 7091 this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px"); 7092 }, 7093 cur: function () { 7094 var hooks = Tween.propHooks[this.prop]; 7095 7096 return hooks && hooks.get ? 7097 hooks.get(this) : 7098 Tween.propHooks._default.get(this); 7099 }, 7100 run: function (percent) { 7101 var eased, 7102 hooks = Tween.propHooks[this.prop]; 7103 7104 if (this.options.duration) { 7105 this.pos = eased = jQuery.easing[this.easing]( 7106 percent, this.options.duration * percent, 0, 1, this.options.duration 7107 ); 7108 } else { 7109 this.pos = eased = percent; 7110 } 7111 this.now = (this.end - this.start) * eased + this.start; 7112 7113 if (this.options.step) { 7114 this.options.step.call(this.elem, this.now, this); 7115 } 7116 7117 if (hooks && hooks.set) { 7118 hooks.set(this); 7119 } else { 7120 Tween.propHooks._default.set(this); 7121 } 7122 return this; 7123 } 7124 }; 7125 7126 Tween.prototype.init.prototype = Tween.prototype; 7127 7128 Tween.propHooks = { 7129 _default: { 7130 get: function (tween) { 7131 var result; 7132 7133 // Use a property on the element directly when it is not a DOM element, 7134 // or when there is no matching style property that exists. 7135 if (tween.elem.nodeType !== 1 || 7136 tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) { 7137 return tween.elem[tween.prop]; 7138 } 7139 7140 // Passing an empty string as a 3rd parameter to .css will automatically 7141 // attempt a parseFloat and fallback to a string if the parse fails. 7142 // Simple values such as "10px" are parsed to Float; 7143 // complex values such as "rotate(1rad)" are returned as-is. 7144 result = jQuery.css(tween.elem, tween.prop, ""); 7145 7146 // Empty strings, null, undefined and "auto" are converted to 0. 7147 return !result || result === "auto" ? 0 : result; 7148 }, 7149 set: function (tween) { 7150 7151 // Use step hook for back compat. 7152 // Use cssHook if its there. 7153 // Use .style if available and use plain properties where available. 7154 if (jQuery.fx.step[tween.prop]) { 7155 jQuery.fx.step[tween.prop](tween); 7156 } else if (tween.elem.nodeType === 1 && ( 7157 jQuery.cssHooks[tween.prop] || 7158 tween.elem.style[finalPropName(tween.prop)] != null)) { 7159 jQuery.style(tween.elem, tween.prop, tween.now + tween.unit); 7160 } else { 7161 tween.elem[tween.prop] = tween.now; 7162 } 7163 } 7164 } 7165 }; 7166 7167 // Support: IE <=9 only 7168 // Panic based approach to setting things on disconnected nodes 7169 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 7170 set: function (tween) { 7171 if (tween.elem.nodeType && tween.elem.parentNode) { 7172 tween.elem[tween.prop] = tween.now; 7173 } 7174 } 7175 }; 7176 7177 jQuery.easing = { 7178 linear: function (p) { 7179 return p; 7180 }, 7181 swing: function (p) { 7182 return 0.5 - Math.cos(p * Math.PI) / 2; 7183 }, 7184 _default: "swing" 7185 }; 7186 7187 jQuery.fx = Tween.prototype.init; 7188 7189 // Back compat <1.8 extension point 7190 jQuery.fx.step = {}; 7191 7192 7193 7194 7195 var 7196 fxNow,inProgress, 7197 rfxtypes = /^(?:toggle|show|hide)$/, 7198 rrun = /queueHooks$/; 7199 7200 function schedule() { 7201 if (inProgress) { 7202 if (document.hidden === false && window.requestAnimationFrame) { 7203 window.requestAnimationFrame(schedule); 7204 } else { 7205 window.setTimeout(schedule, jQuery.fx.interval); 7206 } 7207 7208 jQuery.fx.tick(); 7209 } 7210 } 7211 7212 // Animations created synchronously will run synchronously 7213 function createFxNow() { 7214 window.setTimeout(function () { 7215 fxNow = undefined; 7216 }); 7217 return fxNow = Date.now(); 7218 } 7219 7220 // Generate parameters to create a standard animation 7221 function genFx(type, includeWidth) { 7222 var which, 7223 i = 0, 7224 attrs = { height: type }; 7225 7226 // If we include width, step value is 1 to do all cssExpand values, 7227 // otherwise step value is 2 to skip over Left and Right 7228 includeWidth = includeWidth ? 1 : 0; 7229 for (; i < 4; i += 2 - includeWidth) { 7230 which = cssExpand[i]; 7231 attrs["margin" + which] = attrs["padding" + which] = type; 7232 } 7233 7234 if (includeWidth) { 7235 attrs.opacity = attrs.width = type; 7236 } 7237 7238 return attrs; 7239 } 7240 7241 function createTween(value, prop, animation) { 7242 var tween, 7243 collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]), 7244 index = 0, 7245 length = collection.length; 7246 for (; index < length; index++) { 7247 if (tween = collection[index].call(animation, prop, value)) { 7248 7249 // We're done with this property 7250 return tween; 7251 } 7252 } 7253 } 7254 7255 function defaultPrefilter(elem, props, opts) { 7256 var prop,value,toggle,hooks,oldfire,propTween,restoreDisplay,display, 7257 isBox = "width" in props || "height" in props, 7258 anim = this, 7259 orig = {}, 7260 style = elem.style, 7261 hidden = elem.nodeType && isHiddenWithinTree(elem), 7262 dataShow = dataPriv.get(elem, "fxshow"); 7263 7264 // Queue-skipping animations hijack the fx hooks 7265 if (!opts.queue) { 7266 hooks = jQuery._queueHooks(elem, "fx"); 7267 if (hooks.unqueued == null) { 7268 hooks.unqueued = 0; 7269 oldfire = hooks.empty.fire; 7270 hooks.empty.fire = function () { 7271 if (!hooks.unqueued) { 7272 oldfire(); 7273 } 7274 }; 7275 } 7276 hooks.unqueued++; 7277 7278 anim.always(function () { 7279 7280 // Ensure the complete handler is called before this completes 7281 anim.always(function () { 7282 hooks.unqueued--; 7283 if (!jQuery.queue(elem, "fx").length) { 7284 hooks.empty.fire(); 7285 } 7286 }); 7287 }); 7288 } 7289 7290 // Detect show/hide animations 7291 for (prop in props) { 7292 value = props[prop]; 7293 if (rfxtypes.test(value)) { 7294 delete props[prop]; 7295 toggle = toggle || value === "toggle"; 7296 if (value === (hidden ? "hide" : "show")) { 7297 7298 // Pretend to be hidden if this is a "show" and 7299 // there is still data from a stopped show/hide 7300 if (value === "show" && dataShow && dataShow[prop] !== undefined) { 7301 hidden = true; 7302 7303 // Ignore all other no-op show/hide data 7304 } else { 7305 continue; 7306 } 7307 } 7308 orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop); 7309 } 7310 } 7311 7312 // Bail out if this is a no-op like .hide().hide() 7313 propTween = !jQuery.isEmptyObject(props); 7314 if (!propTween && jQuery.isEmptyObject(orig)) { 7315 return; 7316 } 7317 7318 // Restrict "overflow" and "display" styles during box animations 7319 if (isBox && elem.nodeType === 1) { 7320
vendor: 3,446 bytes, lines 7321-7432
7321 // Support: IE <=9 - 11, Edge 12 - 15 7322 // Record all 3 overflow attributes because IE does not infer the shorthand 7323 // from identically-valued overflowX and overflowY and Edge just mirrors 7324 // the overflowX value there. 7325 opts.overflow = [style.overflow, style.overflowX, style.overflowY]; 7326 7327 // Identify a display type, preferring old show/hide data over the CSS cascade 7328 restoreDisplay = dataShow && dataShow.display; 7329 if (restoreDisplay == null) { 7330 restoreDisplay = dataPriv.get(elem, "display"); 7331 } 7332 display = jQuery.css(elem, "display"); 7333 if (display === "none") { 7334 if (restoreDisplay) { 7335 display = restoreDisplay; 7336 } else { 7337 7338 // Get nonempty value(s) by temporarily forcing visibility 7339 showHide([elem], true); 7340 restoreDisplay = elem.style.display || restoreDisplay; 7341 display = jQuery.css(elem, "display"); 7342 showHide([elem]); 7343 } 7344 } 7345 7346 // Animate inline elements as inline-block 7347 if (display === "inline" || display === "inline-block" && restoreDisplay != null) { 7348 if (jQuery.css(elem, "float") === "none") { 7349 7350 // Restore the original display value at the end of pure show/hide animations 7351 if (!propTween) { 7352 anim.done(function () { 7353 style.display = restoreDisplay; 7354 }); 7355 if (restoreDisplay == null) { 7356 display = style.display; 7357 restoreDisplay = display === "none" ? "" : display; 7358 } 7359 } 7360 style.display = "inline-block"; 7361 } 7362 } 7363 } 7364 7365 if (opts.overflow) { 7366 style.overflow = "hidden"; 7367 anim.always(function () { 7368 style.overflow = opts.overflow[0]; 7369 style.overflowX = opts.overflow[1]; 7370 style.overflowY = opts.overflow[2]; 7371 }); 7372 } 7373 7374 // Implement show/hide animations 7375 propTween = false; 7376 for (prop in orig) { 7377 7378 // General show/hide setup for this element animation 7379 if (!propTween) { 7380 if (dataShow) { 7381 if ("hidden" in dataShow) { 7382 hidden = dataShow.hidden; 7383 } 7384 } else { 7385 dataShow = dataPriv.access(elem, "fxshow", { display: restoreDisplay }); 7386 } 7387 7388 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 7389 if (toggle) { 7390 dataShow.hidden = !hidden; 7391 } 7392 7393 // Show elements before animating them 7394 if (hidden) { 7395 showHide([elem], true); 7396 } 7397 7398 /* eslint-disable no-loop-func */ 7399 7400 anim.done(function () { 7401 7402 /* eslint-enable no-loop-func */ 7403 7404 // The final step of a "hide" animation is actually hiding the element 7405 if (!hidden) { 7406 showHide([elem]); 7407 } 7408 dataPriv.remove(elem, "fxshow"); 7409 for (prop in orig) { 7410 jQuery.style(elem, prop, orig[prop]); 7411 } 7412 }); 7413 } 7414 7415 // Per-property setup 7416 propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim); 7417 if (!(prop in dataShow)) { 7418 dataShow[prop] = propTween.start; 7419 if (hidden) { 7420 propTween.end = propTween.start; 7421 propTween.start = 0; 7422 } 7423 } 7424 } 7425 } 7426 7427 function propFilter(props, specialEasing) { 7428 var index, name, easing, value, hooks; 7429 7430 // camelCase, specialEasing and expand cssHook pass 7431 for (index in props) { 7432 name = camelCase(index);
vendor: 45,328 bytes, lines 7433-9093
7433 easing = specialEasing[name]; 7434 value = props[index]; 7435 if (Array.isArray(value)) { 7436 easing = value[1]; 7437 value = props[index] = value[0]; 7438 } 7439 7440 if (index !== name) { 7441 props[name] = value; 7442 delete props[index]; 7443 } 7444 7445 hooks = jQuery.cssHooks[name]; 7446 if (hooks && "expand" in hooks) { 7447 value = hooks.expand(value); 7448 delete props[name]; 7449 7450 // Not quite $.extend, this won't overwrite existing keys. 7451 // Reusing 'index' because we have the correct "name" 7452 for (index in value) { 7453 if (!(index in props)) { 7454 props[index] = value[index]; 7455 specialEasing[index] = easing; 7456 } 7457 } 7458 } else { 7459 specialEasing[name] = easing; 7460 } 7461 } 7462 } 7463 7464 function Animation(elem, properties, options) { 7465 var result, 7466 stopped, 7467 index = 0, 7468 length = Animation.prefilters.length, 7469 deferred = jQuery.Deferred().always(function () { 7470 7471 // Don't match elem in the :animated selector 7472 delete tick.elem; 7473 }), 7474 tick = function () { 7475 if (stopped) { 7476 return false; 7477 } 7478 var currentTime = fxNow || createFxNow(), 7479 remaining = Math.max(0, animation.startTime + animation.duration - currentTime), 7480 7481 // Support: Android 2.3 only 7482 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497) 7483 temp = remaining / animation.duration || 0, 7484 percent = 1 - temp, 7485 index = 0, 7486 length = animation.tweens.length; 7487 7488 for (; index < length; index++) { 7489 animation.tweens[index].run(percent); 7490 } 7491 7492 deferred.notifyWith(elem, [animation, percent, remaining]); 7493 7494 // If there's more to do, yield 7495 if (percent < 1 && length) { 7496 return remaining; 7497 } 7498 7499 // If this was an empty animation, synthesize a final progress notification 7500 if (!length) { 7501 deferred.notifyWith(elem, [animation, 1, 0]); 7502 } 7503 7504 // Resolve the animation and report its conclusion 7505 deferred.resolveWith(elem, [animation]); 7506 return false; 7507 }, 7508 animation = deferred.promise({ 7509 elem: elem, 7510 props: jQuery.extend({}, properties), 7511 opts: jQuery.extend(true, { 7512 specialEasing: {}, 7513 easing: jQuery.easing._default 7514 }, options), 7515 originalProperties: properties, 7516 originalOptions: options, 7517 startTime: fxNow || createFxNow(), 7518 duration: options.duration, 7519 tweens: [], 7520 createTween: function (prop, end) { 7521 var tween = jQuery.Tween(elem, animation.opts, prop, end, 7522 animation.opts.specialEasing[prop] || animation.opts.easing); 7523 animation.tweens.push(tween); 7524 return tween; 7525 }, 7526 stop: function (gotoEnd) { 7527 var index = 0, 7528 7529 // If we are going to the end, we want to run all the tweens 7530 // otherwise we skip this part 7531 length = gotoEnd ? animation.tweens.length : 0; 7532 if (stopped) { 7533 return this; 7534 } 7535 stopped = true; 7536 for (; index < length; index++) { 7537 animation.tweens[index].run(1); 7538 } 7539 7540 // Resolve when we played the last frame; otherwise, reject 7541 if (gotoEnd) { 7542 deferred.notifyWith(elem, [animation, 1, 0]); 7543 deferred.resolveWith(elem, [animation, gotoEnd]); 7544 } else { 7545 deferred.rejectWith(elem, [animation, gotoEnd]); 7546 } 7547 return this; 7548 } 7549 }), 7550 props = animation.props; 7551 7552 propFilter(props, animation.opts.specialEasing); 7553 7554 for (; index < length; index++) { 7555 result = Animation.prefilters[index].call(animation, elem, props, animation.opts); 7556 if (result) { 7557 if (isFunction(result.stop)) { 7558 jQuery._queueHooks(animation.elem, animation.opts.queue).stop = 7559 result.stop.bind(result); 7560 } 7561 return result; 7562 } 7563 } 7564 7565 jQuery.map(props, createTween, animation); 7566 7567 if (isFunction(animation.opts.start)) { 7568 animation.opts.start.call(elem, animation); 7569 } 7570 7571 // Attach callbacks from options 7572 animation. 7573 progress(animation.opts.progress). 7574 done(animation.opts.done, animation.opts.complete). 7575 fail(animation.opts.fail). 7576 always(animation.opts.always); 7577 7578 jQuery.fx.timer( 7579 jQuery.extend(tick, { 7580 elem: elem, 7581 anim: animation, 7582 queue: animation.opts.queue 7583 }) 7584 ); 7585 7586 return animation; 7587 } 7588 7589 jQuery.Animation = jQuery.extend(Animation, { 7590 7591 tweeners: { 7592 "*": [function (prop, value) { 7593 var tween = this.createTween(prop, value); 7594 adjustCSS(tween.elem, prop, rcssNum.exec(value), tween); 7595 return tween; 7596 }] 7597 }, 7598 7599 tweener: function (props, callback) { 7600 if (isFunction(props)) { 7601 callback = props; 7602 props = ["*"]; 7603 } else { 7604 props = props.match(rnothtmlwhite); 7605 } 7606 7607 var prop, 7608 index = 0, 7609 length = props.length; 7610 7611 for (; index < length; index++) { 7612 prop = props[index]; 7613 Animation.tweeners[prop] = Animation.tweeners[prop] || []; 7614 Animation.tweeners[prop].unshift(callback); 7615 } 7616 }, 7617 7618 prefilters: [defaultPrefilter], 7619 7620 prefilter: function (callback, prepend) { 7621 if (prepend) { 7622 Animation.prefilters.unshift(callback); 7623 } else { 7624 Animation.prefilters.push(callback); 7625 } 7626 } 7627 }); 7628 7629 jQuery.speed = function (speed, easing, fn) { 7630 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : { 7631 complete: fn || !fn && easing || 7632 isFunction(speed) && speed, 7633 duration: speed, 7634 easing: fn && easing || easing && !isFunction(easing) && easing 7635 }; 7636 7637 // Go to the end state if fx are off 7638 if (jQuery.fx.off) { 7639 opt.duration = 0; 7640 7641 } else { 7642 if (typeof opt.duration !== "number") { 7643 if (opt.duration in jQuery.fx.speeds) { 7644 opt.duration = jQuery.fx.speeds[opt.duration]; 7645 7646 } else { 7647 opt.duration = jQuery.fx.speeds._default; 7648 } 7649 } 7650 } 7651 7652 // Normalize opt.queue - true/undefined/null -> "fx" 7653 if (opt.queue == null || opt.queue === true) { 7654 opt.queue = "fx"; 7655 } 7656 7657 // Queueing 7658 opt.old = opt.complete; 7659 7660 opt.complete = function () { 7661 if (isFunction(opt.old)) { 7662 opt.old.call(this); 7663 } 7664 7665 if (opt.queue) { 7666 jQuery.dequeue(this, opt.queue); 7667 } 7668 }; 7669 7670 return opt; 7671 }; 7672 7673 jQuery.fn.extend({ 7674 fadeTo: function (speed, to, easing, callback) { 7675 7676 // Show any hidden elements after setting opacity to 0 7677 return this.filter(isHiddenWithinTree).css("opacity", 0).show() 7678 7679 // Animate to the value specified 7680 .end().animate({ opacity: to }, speed, easing, callback); 7681 }, 7682 animate: function (prop, speed, easing, callback) { 7683 var empty = jQuery.isEmptyObject(prop), 7684 optall = jQuery.speed(speed, easing, callback), 7685 doAnimation = function () { 7686 7687 // Operate on a copy of prop so per-property easing won't be lost 7688 var anim = Animation(this, jQuery.extend({}, prop), optall); 7689 7690 // Empty animations, or finishing resolves immediately 7691 if (empty || dataPriv.get(this, "finish")) { 7692 anim.stop(true); 7693 } 7694 }; 7695 7696 doAnimation.finish = doAnimation; 7697 7698 return empty || optall.queue === false ? 7699 this.each(doAnimation) : 7700 this.queue(optall.queue, doAnimation); 7701 }, 7702 stop: function (type, clearQueue, gotoEnd) { 7703 var stopQueue = function (hooks) { 7704 var stop = hooks.stop; 7705 delete hooks.stop; 7706 stop(gotoEnd); 7707 }; 7708 7709 if (typeof type !== "string") { 7710 gotoEnd = clearQueue; 7711 clearQueue = type; 7712 type = undefined; 7713 } 7714 if (clearQueue) { 7715 this.queue(type || "fx", []); 7716 } 7717 7718 return this.each(function () { 7719 var dequeue = true, 7720 index = type != null && type + "queueHooks", 7721 timers = jQuery.timers, 7722 data = dataPriv.get(this); 7723 7724 if (index) { 7725 if (data[index] && data[index].stop) { 7726 stopQueue(data[index]); 7727 } 7728 } else { 7729 for (index in data) { 7730 if (data[index] && data[index].stop && rrun.test(index)) { 7731 stopQueue(data[index]); 7732 } 7733 } 7734 } 7735 7736 for (index = timers.length; index--;) { 7737 if (timers[index].elem === this && ( 7738 type == null || timers[index].queue === type)) { 7739 7740 timers[index].anim.stop(gotoEnd); 7741 dequeue = false; 7742 timers.splice(index, 1); 7743 } 7744 } 7745 7746 // Start the next in the queue if the last step wasn't forced. 7747 // Timers currently will call their complete callbacks, which 7748 // will dequeue but only if they were gotoEnd. 7749 if (dequeue || !gotoEnd) { 7750 jQuery.dequeue(this, type); 7751 } 7752 }); 7753 }, 7754 finish: function (type) { 7755 if (type !== false) { 7756 type = type || "fx"; 7757 } 7758 return this.each(function () { 7759 var index, 7760 data = dataPriv.get(this), 7761 queue = data[type + "queue"], 7762 hooks = data[type + "queueHooks"], 7763 timers = jQuery.timers, 7764 length = queue ? queue.length : 0; 7765 7766 // Enable finishing flag on private data 7767 data.finish = true; 7768 7769 // Empty the queue first 7770 jQuery.queue(this, type, []); 7771 7772 if (hooks && hooks.stop) { 7773 hooks.stop.call(this, true); 7774 } 7775 7776 // Look for any active animations, and finish them 7777 for (index = timers.length; index--;) { 7778 if (timers[index].elem === this && timers[index].queue === type) { 7779 timers[index].anim.stop(true); 7780 timers.splice(index, 1); 7781 } 7782 } 7783 7784 // Look for any animations in the old queue and finish them 7785 for (index = 0; index < length; index++) { 7786 if (queue[index] && queue[index].finish) { 7787 queue[index].finish.call(this); 7788 } 7789 } 7790 7791 // Turn off finishing flag 7792 delete data.finish; 7793 }); 7794 } 7795 }); 7796 7797 jQuery.each(["toggle", "show", "hide"], function (_i, name) { 7798 var cssFn = jQuery.fn[name]; 7799 jQuery.fn[name] = function (speed, easing, callback) { 7800 return speed == null || typeof speed === "boolean" ? 7801 cssFn.apply(this, arguments) : 7802 this.animate(genFx(name, true), speed, easing, callback); 7803 }; 7804 }); 7805 7806 // Generate shortcuts for custom animations 7807 jQuery.each({ 7808 slideDown: genFx("show"), 7809 slideUp: genFx("hide"), 7810 slideToggle: genFx("toggle"), 7811 fadeIn: { opacity: "show" }, 7812 fadeOut: { opacity: "hide" }, 7813 fadeToggle: { opacity: "toggle" } 7814 }, function (name, props) { 7815 jQuery.fn[name] = function (speed, easing, callback) { 7816 return this.animate(props, speed, easing, callback); 7817 }; 7818 }); 7819 7820 jQuery.timers = []; 7821 jQuery.fx.tick = function () { 7822 var timer, 7823 i = 0, 7824 timers = jQuery.timers; 7825 7826 fxNow = Date.now(); 7827 7828 for (; i < timers.length; i++) { 7829 timer = timers[i]; 7830 7831 // Run the timer and safely remove it when done (allowing for external removal) 7832 if (!timer() && timers[i] === timer) { 7833 timers.splice(i--, 1); 7834 } 7835 } 7836 7837 if (!timers.length) { 7838 jQuery.fx.stop(); 7839 } 7840 fxNow = undefined; 7841 }; 7842 7843 jQuery.fx.timer = function (timer) { 7844 jQuery.timers.push(timer); 7845 jQuery.fx.start(); 7846 }; 7847 7848 jQuery.fx.interval = 13; 7849 jQuery.fx.start = function () { 7850 if (inProgress) { 7851 return; 7852 } 7853 7854 inProgress = true; 7855 schedule(); 7856 }; 7857 7858 jQuery.fx.stop = function () { 7859 inProgress = null; 7860 }; 7861 7862 jQuery.fx.speeds = { 7863 slow: 600, 7864 fast: 200, 7865 7866 // Default speed 7867 _default: 400 7868 }; 7869 7870 7871 // Based off of the plugin by Clint Helfers, with permission. 7872 jQuery.fn.delay = function (time, type) { 7873 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; 7874 type = type || "fx"; 7875 7876 return this.queue(type, function (next, hooks) { 7877 var timeout = window.setTimeout(next, time); 7878 hooks.stop = function () { 7879 window.clearTimeout(timeout); 7880 }; 7881 }); 7882 }; 7883 7884 7885 (function () { 7886 var input = document.createElement("input"), 7887 select = document.createElement("select"), 7888 opt = select.appendChild(document.createElement("option")); 7889 7890 input.type = "checkbox"; 7891 7892 // Support: Android <=4.3 only 7893 // Default value for a checkbox should be "on" 7894 support.checkOn = input.value !== ""; 7895 7896 // Support: IE <=11 only 7897 // Must access selectedIndex to make default options select 7898 support.optSelected = opt.selected; 7899 7900 // Support: IE <=11 only 7901 // An input loses its value after becoming a radio 7902 input = document.createElement("input"); 7903 input.value = "t"; 7904 input.type = "radio"; 7905 support.radioValue = input.value === "t"; 7906 })(); 7907 7908 7909 var boolHook, 7910 attrHandle = jQuery.expr.attrHandle; 7911 7912 jQuery.fn.extend({ 7913 attr: function (name, value) { 7914 return access(this, jQuery.attr, name, value, arguments.length > 1); 7915 }, 7916 7917 removeAttr: function (name) { 7918 return this.each(function () { 7919 jQuery.removeAttr(this, name); 7920 }); 7921 } 7922 }); 7923 7924 jQuery.extend({ 7925 attr: function (elem, name, value) { 7926 var ret,hooks, 7927 nType = elem.nodeType; 7928 7929 // Don't get/set attributes on text, comment and attribute nodes 7930 if (nType === 3 || nType === 8 || nType === 2) { 7931 return; 7932 } 7933 7934 // Fallback to prop when attributes are not supported 7935 if (typeof elem.getAttribute === "undefined") { 7936 return jQuery.prop(elem, name, value); 7937 } 7938 7939 // Attribute hooks are determined by the lowercase version 7940 // Grab necessary hook if one is defined 7941 if (nType !== 1 || !jQuery.isXMLDoc(elem)) { 7942 hooks = jQuery.attrHooks[name.toLowerCase()] || ( 7943 jQuery.expr.match.bool.test(name) ? boolHook : undefined); 7944 } 7945 7946 if (value !== undefined) { 7947 if (value === null) { 7948 jQuery.removeAttr(elem, name); 7949 return; 7950 } 7951 7952 if (hooks && "set" in hooks && 7953 (ret = hooks.set(elem, value, name)) !== undefined) { 7954 return ret; 7955 } 7956 7957 elem.setAttribute(name, value + ""); 7958 return value; 7959 } 7960 7961 if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { 7962 return ret; 7963 } 7964 7965 ret = jQuery.find.attr(elem, name); 7966 7967 // Non-existent attributes return null, we normalize to undefined 7968 return ret == null ? undefined : ret; 7969 }, 7970 7971 attrHooks: { 7972 type: { 7973 set: function (elem, value) { 7974 if (!support.radioValue && value === "radio" && 7975 nodeName(elem, "input")) { 7976 var val = elem.value; 7977 elem.setAttribute("type", value); 7978 if (val) { 7979 elem.value = val; 7980 } 7981 return value; 7982 } 7983 } 7984 } 7985 }, 7986 7987 removeAttr: function (elem, value) { 7988 var name, 7989 i = 0, 7990 7991 // Attribute names can contain non-HTML whitespace characters 7992 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 7993 attrNames = value && value.match(rnothtmlwhite); 7994 7995 if (attrNames && elem.nodeType === 1) { 7996 while (name = attrNames[i++]) { 7997 elem.removeAttribute(name); 7998 } 7999 } 8000 } 8001 }); 8002 8003 // Hooks for boolean attributes 8004 boolHook = { 8005 set: function (elem, value, name) { 8006 if (value === false) { 8007 8008 // Remove boolean attributes when set to false 8009 jQuery.removeAttr(elem, name); 8010 } else { 8011 elem.setAttribute(name, name); 8012 } 8013 return name; 8014 } 8015 }; 8016 8017 jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (_i, name) { 8018 var getter = attrHandle[name] || jQuery.find.attr; 8019 8020 attrHandle[name] = function (elem, name, isXML) { 8021 var ret,handle, 8022 lowercaseName = name.toLowerCase(); 8023 8024 if (!isXML) { 8025 8026 // Avoid an infinite loop by temporarily removing this function from the getter 8027 handle = attrHandle[lowercaseName]; 8028 attrHandle[lowercaseName] = ret; 8029 ret = getter(elem, name, isXML) != null ? 8030 lowercaseName : 8031 null; 8032 attrHandle[lowercaseName] = handle; 8033 } 8034 return ret; 8035 }; 8036 }); 8037 8038 8039 8040 8041 var rfocusable = /^(?:input|select|textarea|button)$/i, 8042 rclickable = /^(?:a|area)$/i; 8043 8044 jQuery.fn.extend({ 8045 prop: function (name, value) { 8046 return access(this, jQuery.prop, name, value, arguments.length > 1); 8047 }, 8048 8049 removeProp: function (name) { 8050 return this.each(function () { 8051 delete this[jQuery.propFix[name] || name]; 8052 }); 8053 } 8054 }); 8055 8056 jQuery.extend({ 8057 prop: function (elem, name, value) { 8058 var ret,hooks, 8059 nType = elem.nodeType; 8060 8061 // Don't get/set properties on text, comment and attribute nodes 8062 if (nType === 3 || nType === 8 || nType === 2) { 8063 return; 8064 } 8065 8066 if (nType !== 1 || !jQuery.isXMLDoc(elem)) { 8067 8068 // Fix name and attach hooks 8069 name = jQuery.propFix[name] || name; 8070 hooks = jQuery.propHooks[name]; 8071 } 8072 8073 if (value !== undefined) { 8074 if (hooks && "set" in hooks && 8075 (ret = hooks.set(elem, value, name)) !== undefined) { 8076 return ret; 8077 } 8078 8079 return elem[name] = value; 8080 } 8081 8082 if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { 8083 return ret; 8084 } 8085 8086 return elem[name]; 8087 }, 8088 8089 propHooks: { 8090 tabIndex: { 8091 get: function (elem) { 8092 8093 // Support: IE <=9 - 11 only 8094 // elem.tabIndex doesn't always return the 8095 // correct value when it hasn't been explicitly set 8096 // Use proper attribute retrieval (trac-12072) 8097 var tabindex = jQuery.find.attr(elem, "tabindex"); 8098 8099 if (tabindex) { 8100 return parseInt(tabindex, 10); 8101 } 8102 8103 if ( 8104 rfocusable.test(elem.nodeName) || 8105 rclickable.test(elem.nodeName) && 8106 elem.href) 8107 { 8108 return 0; 8109 } 8110 8111 return -1; 8112 } 8113 } 8114 }, 8115 8116 propFix: { 8117 "for": "htmlFor", 8118 "class": "className" 8119 } 8120 }); 8121 8122 // Support: IE <=11 only 8123 // Accessing the selectedIndex property 8124 // forces the browser to respect setting selected 8125 // on the option 8126 // The getter ensures a default option is selected 8127 // when in an optgroup 8128 // eslint rule "no-unused-expressions" is disabled for this code 8129 // since it considers such accessions noop 8130 if (!support.optSelected) { 8131 jQuery.propHooks.selected = { 8132 get: function (elem) { 8133 8134 /* eslint no-unused-expressions: "off" */ 8135 8136 var parent = elem.parentNode; 8137 if (parent && parent.parentNode) { 8138 parent.parentNode.selectedIndex; 8139 } 8140 return null; 8141 }, 8142 set: function (elem) { 8143 8144 /* eslint no-unused-expressions: "off" */ 8145 8146 var parent = elem.parentNode; 8147 if (parent) { 8148 parent.selectedIndex; 8149 8150 if (parent.parentNode) { 8151 parent.parentNode.selectedIndex; 8152 } 8153 } 8154 } 8155 }; 8156 } 8157 8158 jQuery.each([ 8159 "tabIndex", 8160 "readOnly", 8161 "maxLength", 8162 "cellSpacing", 8163 "cellPadding", 8164 "rowSpan", 8165 "colSpan", 8166 "useMap", 8167 "frameBorder", 8168 "contentEditable"], 8169 function () { 8170 jQuery.propFix[this.toLowerCase()] = this; 8171 }); 8172 8173 8174 8175 8176 // Strip and collapse whitespace according to HTML spec 8177 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 8178 function stripAndCollapse(value) { 8179 var tokens = value.match(rnothtmlwhite) || []; 8180 return tokens.join(" "); 8181 } 8182 8183 8184 function getClass(elem) { 8185 return elem.getAttribute && elem.getAttribute("class") || ""; 8186 } 8187 8188 function classesToArray(value) { 8189 if (Array.isArray(value)) { 8190 return value; 8191 } 8192 if (typeof value === "string") { 8193 return value.match(rnothtmlwhite) || []; 8194 } 8195 return []; 8196 } 8197 8198 jQuery.fn.extend({ 8199 addClass: function (value) { 8200 var classNames, cur, curValue, className, i, finalValue; 8201 8202 if (isFunction(value)) { 8203 return this.each(function (j) { 8204 jQuery(this).addClass(value.call(this, j, getClass(this))); 8205 }); 8206 } 8207 8208 classNames = classesToArray(value); 8209 8210 if (classNames.length) { 8211 return this.each(function () { 8212 curValue = getClass(this); 8213 cur = this.nodeType === 1 && " " + stripAndCollapse(curValue) + " "; 8214 8215 if (cur) { 8216 for (i = 0; i < classNames.length; i++) { 8217 className = classNames[i]; 8218 if (cur.indexOf(" " + className + " ") < 0) { 8219 cur += className + " "; 8220 } 8221 } 8222 8223 // Only assign if different to avoid unneeded rendering. 8224 finalValue = stripAndCollapse(cur); 8225 if (curValue !== finalValue) { 8226 this.setAttribute("class", finalValue); 8227 } 8228 } 8229 }); 8230 } 8231 8232 return this; 8233 }, 8234 8235 removeClass: function (value) { 8236 var classNames, cur, curValue, className, i, finalValue; 8237 8238 if (isFunction(value)) { 8239 return this.each(function (j) { 8240 jQuery(this).removeClass(value.call(this, j, getClass(this))); 8241 }); 8242 } 8243 8244 if (!arguments.length) { 8245 return this.attr("class", ""); 8246 } 8247 8248 classNames = classesToArray(value); 8249 8250 if (classNames.length) { 8251 return this.each(function () { 8252 curValue = getClass(this); 8253 8254 // This expression is here for better compressibility (see addClass) 8255 cur = this.nodeType === 1 && " " + stripAndCollapse(curValue) + " "; 8256 8257 if (cur) { 8258 for (i = 0; i < classNames.length; i++) { 8259 className = classNames[i]; 8260 8261 // Remove *all* instances 8262 while (cur.indexOf(" " + className + " ") > -1) { 8263 cur = cur.replace(" " + className + " ", " "); 8264 } 8265 } 8266 8267 // Only assign if different to avoid unneeded rendering. 8268 finalValue = stripAndCollapse(cur); 8269 if (curValue !== finalValue) { 8270 this.setAttribute("class", finalValue); 8271 } 8272 } 8273 }); 8274 } 8275 8276 return this; 8277 }, 8278 8279 toggleClass: function (value, stateVal) { 8280 var classNames,className,i,self, 8281 type = typeof value, 8282 isValidValue = type === "string" || Array.isArray(value); 8283 8284 if (isFunction(value)) { 8285 return this.each(function (i) { 8286 jQuery(this).toggleClass( 8287 value.call(this, i, getClass(this), stateVal), 8288 stateVal 8289 ); 8290 }); 8291 } 8292 8293 if (typeof stateVal === "boolean" && isValidValue) { 8294 return stateVal ? this.addClass(value) : this.removeClass(value); 8295 } 8296 8297 classNames = classesToArray(value); 8298 8299 return this.each(function () { 8300 if (isValidValue) { 8301 8302 // Toggle individual class names 8303 self = jQuery(this); 8304 8305 for (i = 0; i < classNames.length; i++) { 8306 className = classNames[i]; 8307 8308 // Check each className given, space separated list 8309 if (self.hasClass(className)) { 8310 self.removeClass(className); 8311 } else { 8312 self.addClass(className); 8313 } 8314 } 8315 8316 // Toggle whole class name 8317 } else if (value === undefined || type === "boolean") { 8318 className = getClass(this); 8319 if (className) { 8320 8321 // Store className if set 8322 dataPriv.set(this, "__className__", className); 8323 } 8324 8325 // If the element has a class name or if we're passed `false`, 8326 // then remove the whole classname (if there was one, the above saved it). 8327 // Otherwise bring back whatever was previously saved (if anything), 8328 // falling back to the empty string if nothing was stored. 8329 if (this.setAttribute) { 8330 this.setAttribute("class", 8331 className || value === false ? 8332 "" : 8333 dataPriv.get(this, "__className__") || "" 8334 ); 8335 } 8336 } 8337 }); 8338 }, 8339 8340 hasClass: function (selector) { 8341 var className,elem, 8342 i = 0; 8343 8344 className = " " + selector + " "; 8345 while (elem = this[i++]) { 8346 if (elem.nodeType === 1 && 8347 (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) { 8348 return true; 8349 } 8350 } 8351 8352 return false; 8353 } 8354 }); 8355 8356 8357 8358 8359 var rreturn = /\r/g; 8360 8361 jQuery.fn.extend({ 8362 val: function (value) { 8363 var hooks,ret,valueIsFunction, 8364 elem = this[0]; 8365 8366 if (!arguments.length) { 8367 if (elem) { 8368 hooks = jQuery.valHooks[elem.type] || 8369 jQuery.valHooks[elem.nodeName.toLowerCase()]; 8370 8371 if (hooks && 8372 "get" in hooks && 8373 (ret = hooks.get(elem, "value")) !== undefined) 8374 { 8375 return ret; 8376 } 8377 8378 ret = elem.value; 8379 8380 // Handle most common string cases 8381 if (typeof ret === "string") { 8382 return ret.replace(rreturn, ""); 8383 } 8384 8385 // Handle cases where value is null/undef or number 8386 return ret == null ? "" : ret; 8387 } 8388 8389 return; 8390 } 8391 8392 valueIsFunction = isFunction(value); 8393 8394 return this.each(function (i) { 8395 var val; 8396 8397 if (this.nodeType !== 1) { 8398 return; 8399 } 8400 8401 if (valueIsFunction) { 8402 val = value.call(this, i, jQuery(this).val()); 8403 } else { 8404 val = value; 8405 } 8406 8407 // Treat null/undefined as ""; convert numbers to string 8408 if (val == null) { 8409 val = ""; 8410 8411 } else if (typeof val === "number") { 8412 val += ""; 8413 8414 } else if (Array.isArray(val)) { 8415 val = jQuery.map(val, function (value) { 8416 return value == null ? "" : value + ""; 8417 }); 8418 } 8419 8420 hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; 8421 8422 // If set returns undefined, fall back to normal setting 8423 if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) { 8424 this.value = val; 8425 } 8426 }); 8427 } 8428 }); 8429 8430 jQuery.extend({ 8431 valHooks: { 8432 option: { 8433 get: function (elem) { 8434 8435 var val = jQuery.find.attr(elem, "value"); 8436 return val != null ? 8437 val : 8438 8439 // Support: IE <=10 - 11 only 8440 // option.text throws exceptions (trac-14686, trac-14858) 8441 // Strip and collapse whitespace 8442 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 8443 stripAndCollapse(jQuery.text(elem)); 8444 } 8445 }, 8446 select: { 8447 get: function (elem) { 8448 var value,option,i, 8449 options = elem.options, 8450 index = elem.selectedIndex, 8451 one = elem.type === "select-one", 8452 values = one ? null : [], 8453 max = one ? index + 1 : options.length; 8454 8455 if (index < 0) { 8456 i = max; 8457 8458 } else { 8459 i = one ? index : 0; 8460 } 8461 8462 // Loop through all the selected options 8463 for (; i < max; i++) { 8464 option = options[i]; 8465 8466 // Support: IE <=9 only 8467 // IE8-9 doesn't update selected after form reset (trac-2551) 8468 if ((option.selected || i === index) && 8469 8470 // Don't return options that are disabled or in a disabled optgroup 8471 !option.disabled && ( 8472 !option.parentNode.disabled || 8473 !nodeName(option.parentNode, "optgroup"))) { 8474 8475 // Get the specific value for the option 8476 value = jQuery(option).val(); 8477 8478 // We don't need an array for one selects 8479 if (one) { 8480 return value; 8481 } 8482 8483 // Multi-Selects return an array 8484 values.push(value); 8485 } 8486 } 8487 8488 return values; 8489 }, 8490 8491 set: function (elem, value) { 8492 var optionSet,option, 8493 options = elem.options, 8494 values = jQuery.makeArray(value), 8495 i = options.length; 8496 8497 while (i--) { 8498 option = options[i]; 8499 8500 /* eslint-disable no-cond-assign */ 8501 8502 if (option.selected = 8503 jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) 8504 { 8505 optionSet = true; 8506 } 8507 8508 /* eslint-enable no-cond-assign */ 8509 } 8510 8511 // Force browsers to behave consistently when non-matching value is set 8512 if (!optionSet) { 8513 elem.selectedIndex = -1; 8514 } 8515 return values; 8516 } 8517 } 8518 } 8519 }); 8520 8521 // Radios and checkboxes getter/setter 8522 jQuery.each(["radio", "checkbox"], function () { 8523 jQuery.valHooks[this] = { 8524 set: function (elem, value) { 8525 if (Array.isArray(value)) { 8526 return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1; 8527 } 8528 } 8529 }; 8530 if (!support.checkOn) { 8531 jQuery.valHooks[this].get = function (elem) { 8532 return elem.getAttribute("value") === null ? "on" : elem.value; 8533 }; 8534 } 8535 }); 8536 8537 8538 8539 8540 // Return jQuery for attributes-only inclusion 8541 var location = window.location; 8542 8543 var nonce = { guid: Date.now() }; 8544 8545 var rquery = /\?/; 8546 8547 8548 8549 // Cross-browser xml parsing 8550 jQuery.parseXML = function (data) { 8551 var xml, parserErrorElem; 8552 if (!data || typeof data !== "string") { 8553 return null; 8554 } 8555 8556 // Support: IE 9 - 11 only 8557 // IE throws on parseFromString with invalid input. 8558 try { 8559 xml = new window.DOMParser().parseFromString(data, "text/xml"); 8560 } catch (e) {} 8561 8562 parserErrorElem = xml && xml.getElementsByTagName("parsererror")[0]; 8563 if (!xml || parserErrorElem) { 8564 jQuery.error("Invalid XML: " + ( 8565 parserErrorElem ? 8566 jQuery.map(parserErrorElem.childNodes, function (el) { 8567 return el.textContent; 8568 }).join("\n") : 8569 data) 8570 ); 8571 } 8572 return xml; 8573 }; 8574 8575 8576 var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 8577 stopPropagationCallback = function (e) { 8578 e.stopPropagation(); 8579 }; 8580 8581 jQuery.extend(jQuery.event, { 8582 8583 trigger: function (event, data, elem, onlyHandlers) { 8584 8585 var i,cur,tmp,bubbleType,ontype,handle,special,lastElement, 8586 eventPath = [elem || document], 8587 type = hasOwn.call(event, "type") ? event.type : event, 8588 namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : []; 8589 8590 cur = lastElement = tmp = elem = elem || document; 8591 8592 // Don't do events on text and comment nodes 8593 if (elem.nodeType === 3 || elem.nodeType === 8) { 8594 return; 8595 } 8596 8597 // focus/blur morphs to focusin/out; ensure we're not firing them right now 8598 if (rfocusMorph.test(type + jQuery.event.triggered)) { 8599 return; 8600 } 8601 8602 if (type.indexOf(".") > -1) { 8603 8604 // Namespaced trigger; create a regexp to match event type in handle() 8605 namespaces = type.split("."); 8606 type = namespaces.shift(); 8607 namespaces.sort(); 8608 } 8609 ontype = type.indexOf(":") < 0 && "on" + type; 8610 8611 // Caller can pass in a jQuery.Event object, Object, or just an event type string 8612 event = event[jQuery.expando] ? 8613 event : 8614 new jQuery.Event(type, typeof event === "object" && event); 8615 8616 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 8617 event.isTrigger = onlyHandlers ? 2 : 3; 8618 event.namespace = namespaces.join("."); 8619 event.rnamespace = event.namespace ? 8620 new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : 8621 null; 8622 8623 // Clean up the event in case it is being reused 8624 event.result = undefined; 8625 if (!event.target) { 8626 event.target = elem; 8627 } 8628 8629 // Clone any incoming data and prepend the event, creating the handler arg list 8630 data = data == null ? 8631 [event] : 8632 jQuery.makeArray(data, [event]); 8633 8634 // Allow special events to draw outside the lines 8635 special = jQuery.event.special[type] || {}; 8636 if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) { 8637 return; 8638 } 8639 8640 // Determine event propagation path in advance, per W3C events spec (trac-9951) 8641 // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724) 8642 if (!onlyHandlers && !special.noBubble && !isWindow(elem)) { 8643 8644 bubbleType = special.delegateType || type; 8645 if (!rfocusMorph.test(bubbleType + type)) { 8646 cur = cur.parentNode; 8647 } 8648 for (; cur; cur = cur.parentNode) { 8649 eventPath.push(cur); 8650 tmp = cur; 8651 } 8652 8653 // Only add window if we got to document (e.g., not plain obj or detached DOM) 8654 if (tmp === (elem.ownerDocument || document)) { 8655 eventPath.push(tmp.defaultView || tmp.parentWindow || window); 8656 } 8657 } 8658 8659 // Fire handlers on the event path 8660 i = 0; 8661 while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { 8662 lastElement = cur; 8663 event.type = i > 1 ? 8664 bubbleType : 8665 special.bindType || type; 8666 8667 // jQuery handler 8668 handle = (dataPriv.get(cur, "events") || Object.create(null))[event.type] && 8669 dataPriv.get(cur, "handle"); 8670 if (handle) { 8671 handle.apply(cur, data); 8672 } 8673 8674 // Native handler 8675 handle = ontype && cur[ontype]; 8676 if (handle && handle.apply && acceptData(cur)) { 8677 event.result = handle.apply(cur, data); 8678 if (event.result === false) { 8679 event.preventDefault(); 8680 } 8681 } 8682 } 8683 event.type = type; 8684 8685 // If nobody prevented the default action, do it now 8686 if (!onlyHandlers && !event.isDefaultPrevented()) { 8687 8688 if ((!special._default || 8689 special._default.apply(eventPath.pop(), data) === false) && 8690 acceptData(elem)) { 8691 8692 // Call a native DOM method on the target with the same name as the event. 8693 // Don't do default actions on window, that's where global variables be (trac-6170) 8694 if (ontype && isFunction(elem[type]) && !isWindow(elem)) { 8695 8696 // Don't re-trigger an onFOO event when we call its FOO() method 8697 tmp = elem[ontype]; 8698 8699 if (tmp) { 8700 elem[ontype] = null; 8701 } 8702 8703 // Prevent re-triggering of the same event, since we already bubbled it above 8704 jQuery.event.triggered = type; 8705 8706 if (event.isPropagationStopped()) { 8707 lastElement.addEventListener(type, stopPropagationCallback); 8708 } 8709 8710 elem[type](); 8711 8712 if (event.isPropagationStopped()) { 8713 lastElement.removeEventListener(type, stopPropagationCallback); 8714 } 8715 8716 jQuery.event.triggered = undefined; 8717 8718 if (tmp) { 8719 elem[ontype] = tmp; 8720 } 8721 } 8722 } 8723 } 8724 8725 return event.result; 8726 }, 8727 8728 // Piggyback on a donor event to simulate a different one 8729 // Used only for `focus(in | out)` events 8730 simulate: function (type, elem, event) { 8731 var e = jQuery.extend( 8732 new jQuery.Event(), 8733 event, 8734 { 8735 type: type, 8736 isSimulated: true 8737 } 8738 ); 8739 8740 jQuery.event.trigger(e, null, elem); 8741 } 8742 8743 }); 8744 8745 jQuery.fn.extend({ 8746 8747 trigger: function (type, data) { 8748 return this.each(function () { 8749 jQuery.event.trigger(type, data, this); 8750 }); 8751 }, 8752 triggerHandler: function (type, data) { 8753 var elem = this[0]; 8754 if (elem) { 8755 return jQuery.event.trigger(type, data, elem, true); 8756 } 8757 } 8758 }); 8759 8760 8761 var 8762 rbracket = /\[\]$/, 8763 rCRLF = /\r?\n/g, 8764 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 8765 rsubmittable = /^(?:input|select|textarea|keygen)/i; 8766 8767 function buildParams(prefix, obj, traditional, add) { 8768 var name; 8769 8770 if (Array.isArray(obj)) { 8771 8772 // Serialize array item. 8773 jQuery.each(obj, function (i, v) { 8774 if (traditional || rbracket.test(prefix)) { 8775 8776 // Treat each array item as a scalar. 8777 add(prefix, v); 8778 8779 } else { 8780 8781 // Item is non-scalar (array or object), encode its numeric index. 8782 buildParams( 8783 prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", 8784 v, 8785 traditional, 8786 add 8787 ); 8788 } 8789 }); 8790 8791 } else if (!traditional && toType(obj) === "object") { 8792 8793 // Serialize object item. 8794 for (name in obj) { 8795 buildParams(prefix + "[" + name + "]", obj[name], traditional, add); 8796 } 8797 8798 } else { 8799 8800 // Serialize scalar item. 8801 add(prefix, obj); 8802 } 8803 } 8804 8805 // Serialize an array of form elements or a set of 8806 // key/values into a query string 8807 jQuery.param = function (a, traditional) { 8808 var prefix, 8809 s = [], 8810 add = function (key, valueOrFunction) { 8811 8812 // If value is a function, invoke it and use its return value 8813 var value = isFunction(valueOrFunction) ? 8814 valueOrFunction() : 8815 valueOrFunction; 8816 8817 s[s.length] = encodeURIComponent(key) + "=" + 8818 encodeURIComponent(value == null ? "" : value); 8819 }; 8820 8821 if (a == null) { 8822 return ""; 8823 } 8824 8825 // If an array was passed in, assume that it is an array of form elements. 8826 if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) { 8827 8828 // Serialize the form elements 8829 jQuery.each(a, function () { 8830 add(this.name, this.value); 8831 }); 8832 8833 } else { 8834 8835 // If traditional, encode the "old" way (the way 1.3.2 or older 8836 // did it), otherwise encode params recursively. 8837 for (prefix in a) { 8838 buildParams(prefix, a[prefix], traditional, add); 8839 } 8840 } 8841 8842 // Return the resulting serialization 8843 return s.join("&"); 8844 }; 8845 8846 jQuery.fn.extend({ 8847 serialize: function () { 8848 return jQuery.param(this.serializeArray()); 8849 }, 8850 serializeArray: function () { 8851 return this.map(function () { 8852 8853 // Can add propHook for "elements" to filter or add form elements 8854 var elements = jQuery.prop(this, "elements"); 8855 return elements ? jQuery.makeArray(elements) : this; 8856 }).filter(function () { 8857 var type = this.type; 8858 8859 // Use .is( ":disabled" ) so that fieldset[disabled] works 8860 return this.name && !jQuery(this).is(":disabled") && 8861 rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && ( 8862 this.checked || !rcheckableType.test(type)); 8863 }).map(function (_i, elem) { 8864 var val = jQuery(this).val(); 8865 8866 if (val == null) { 8867 return null; 8868 } 8869 8870 if (Array.isArray(val)) { 8871 return jQuery.map(val, function (val) { 8872 return { name: elem.name, value: val.replace(rCRLF, "\r\n") }; 8873 }); 8874 } 8875 8876 return { name: elem.name, value: val.replace(rCRLF, "\r\n") }; 8877 }).get(); 8878 } 8879 }); 8880 8881 8882 var 8883 r20 = /%20/g, 8884 rhash = /#.*$/, 8885 rantiCache = /([?&])_=[^&]*/, 8886 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 8887 8888 // trac-7653, trac-8125, trac-8152: local protocol detection 8889 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 8890 rnoContent = /^(?:GET|HEAD)$/, 8891 rprotocol = /^\/\//, 8892 8893 /* Prefilters 8894 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 8895 * 2) These are called: 8896 * - BEFORE asking for a transport 8897 * - AFTER param serialization (s.data is a string if s.processData is true) 8898 * 3) key is the dataType 8899 * 4) the catchall symbol "*" can be used 8900 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 8901 */ 8902 prefilters = {}, 8903 8904 /* Transports bindings 8905 * 1) key is the dataType 8906 * 2) the catchall symbol "*" can be used 8907 * 3) selection will start with transport dataType and THEN go to "*" if needed 8908 */ 8909 transports = {}, 8910 8911 // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression 8912 allTypes = "*/".concat("*"), 8913 8914 // Anchor tag for parsing the document origin 8915 originAnchor = document.createElement("a"); 8916 8917 originAnchor.href = location.href; 8918 8919 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 8920 function addToPrefiltersOrTransports(structure) { 8921 8922 // dataTypeExpression is optional and defaults to "*" 8923 return function (dataTypeExpression, func) { 8924 8925 if (typeof dataTypeExpression !== "string") { 8926 func = dataTypeExpression; 8927 dataTypeExpression = "*"; 8928 } 8929 8930 var dataType, 8931 i = 0, 8932 dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || []; 8933 8934 if (isFunction(func)) { 8935 8936 // For each dataType in the dataTypeExpression 8937 while (dataType = dataTypes[i++]) { 8938 8939 // Prepend if requested 8940 if (dataType[0] === "+") { 8941 dataType = dataType.slice(1) || "*"; 8942 (structure[dataType] = structure[dataType] || []).unshift(func); 8943 8944 // Otherwise append 8945 } else { 8946 (structure[dataType] = structure[dataType] || []).push(func); 8947 } 8948 } 8949 } 8950 }; 8951 } 8952 8953 // Base inspection function for prefilters and transports 8954 function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) { 8955 8956 var inspected = {}, 8957 seekingTransport = structure === transports; 8958 8959 function inspect(dataType) { 8960 var selected; 8961 inspected[dataType] = true; 8962 jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) { 8963 var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR); 8964 if (typeof dataTypeOrTransport === "string" && 8965 !seekingTransport && !inspected[dataTypeOrTransport]) { 8966 8967 options.dataTypes.unshift(dataTypeOrTransport); 8968 inspect(dataTypeOrTransport); 8969 return false; 8970 } else if (seekingTransport) { 8971 return !(selected = dataTypeOrTransport); 8972 } 8973 }); 8974 return selected; 8975 } 8976 8977 return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*"); 8978 } 8979 8980 // A special extend for ajax options 8981 // that takes "flat" options (not to be deep extended) 8982 // Fixes trac-9887 8983 function ajaxExtend(target, src) { 8984 var key,deep, 8985 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 8986 8987 for (key in src) { 8988 if (src[key] !== undefined) { 8989 (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key]; 8990 } 8991 } 8992 if (deep) { 8993 jQuery.extend(true, target, deep); 8994 } 8995 8996 return target; 8997 } 8998 8999 /* Handles responses to an ajax request: 9000 * - finds the right dataType (mediates between content-type and expected dataType) 9001 * - returns the corresponding response 9002 */ 9003 function ajaxHandleResponses(s, jqXHR, responses) { 9004 9005 var ct,type,finalDataType,firstDataType, 9006 contents = s.contents, 9007 dataTypes = s.dataTypes; 9008 9009 // Remove auto dataType and get content-type in the process 9010 while (dataTypes[0] === "*") { 9011 dataTypes.shift(); 9012 if (ct === undefined) { 9013 ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); 9014 } 9015 } 9016 9017 // Check if we're dealing with a known content-type 9018 if (ct) { 9019 for (type in contents) { 9020 if (contents[type] && contents[type].test(ct)) { 9021 dataTypes.unshift(type); 9022 break; 9023 } 9024 } 9025 } 9026 9027 // Check to see if we have a response for the expected dataType 9028 if (dataTypes[0] in responses) { 9029 finalDataType = dataTypes[0]; 9030 } else { 9031 9032 // Try convertible dataTypes 9033 for (type in responses) { 9034 if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) { 9035 finalDataType = type; 9036 break; 9037 } 9038 if (!firstDataType) { 9039 firstDataType = type; 9040 } 9041 } 9042 9043 // Or just use first one 9044 finalDataType = finalDataType || firstDataType; 9045 } 9046 9047 // If we found a dataType 9048 // We add the dataType to the list if needed 9049 // and return the corresponding response 9050 if (finalDataType) { 9051 if (finalDataType !== dataTypes[0]) { 9052 dataTypes.unshift(finalDataType); 9053 } 9054 return responses[finalDataType]; 9055 } 9056 } 9057 9058 /* Chain conversions given the request and the original response 9059 * Also sets the responseXXX fields on the jqXHR instance 9060 */ 9061 function ajaxConvert(s, response, jqXHR, isSuccess) { 9062 var conv2,current,conv,tmp,prev, 9063 converters = {}, 9064 9065 // Work with a copy of dataTypes in case we need to modify it for conversion 9066 dataTypes = s.dataTypes.slice(); 9067 9068 // Create converters map with lowercased keys 9069 if (dataTypes[1]) { 9070 for (conv in s.converters) { 9071 converters[conv.toLowerCase()] = s.converters[conv]; 9072 } 9073 } 9074 9075 current = dataTypes.shift(); 9076 9077 // Convert to each sequential dataType 9078 while (current) { 9079 9080 if (s.responseFields[current]) { 9081 jqXHR[s.responseFields[current]] = response; 9082 } 9083 9084 // Apply the dataFilter if provided 9085 if (!prev && isSuccess && s.dataFilter) { 9086 response = s.dataFilter(response, s.dataType); 9087 } 9088 9089 prev = current; 9090 current = dataTypes.shift(); 9091 9092 if (current) { 9093
vendor: 8,893 bytes, lines 9094-9407
9094 // There's only work to do if current dataType is non-auto 9095 if (current === "*") { 9096 9097 current = prev; 9098 9099 // Convert response if prev dataType is non-auto and differs from current 9100 } else if (prev !== "*" && prev !== current) { 9101 9102 // Seek a direct converter 9103 conv = converters[prev + " " + current] || converters["* " + current]; 9104 9105 // If none found, seek a pair 9106 if (!conv) { 9107 for (conv2 in converters) { 9108 9109 // If conv2 outputs current 9110 tmp = conv2.split(" "); 9111 if (tmp[1] === current) { 9112 9113 // If prev can be converted to accepted input 9114 conv = converters[prev + " " + tmp[0]] || 9115 converters["* " + tmp[0]]; 9116 if (conv) { 9117 9118 // Condense equivalence converters 9119 if (conv === true) { 9120 conv = converters[conv2]; 9121 9122 // Otherwise, insert the intermediate dataType 9123 } else if (converters[conv2] !== true) { 9124 current = tmp[0]; 9125 dataTypes.unshift(tmp[1]); 9126 } 9127 break; 9128 } 9129 } 9130 } 9131 } 9132 9133 // Apply converter (if not an equivalence) 9134 if (conv !== true) { 9135 9136 // Unless errors are allowed to bubble, catch and return them 9137 if (conv && s.throws) { 9138 response = conv(response); 9139 } else { 9140 try { 9141 response = conv(response); 9142 } catch (e) { 9143 return { 9144 state: "parsererror", 9145 error: conv ? e : "No conversion from " + prev + " to " + current 9146 }; 9147 } 9148 } 9149 } 9150 } 9151 } 9152 } 9153 9154 return { state: "success", data: response }; 9155 } 9156 9157 jQuery.extend({ 9158 9159 // Counter for holding the number of active queries 9160 active: 0, 9161 9162 // Last-Modified header cache for next request 9163 lastModified: {}, 9164 etag: {}, 9165 9166 ajaxSettings: { 9167 url: location.href, 9168 type: "GET", 9169 isLocal: rlocalProtocol.test(location.protocol), 9170 global: true, 9171 processData: true, 9172 async: true, 9173 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 9174 9175 /* 9176 timeout: 0, 9177 data: null, 9178 dataType: null, 9179 username: null, 9180 password: null, 9181 cache: null, 9182 throws: false, 9183 traditional: false, 9184 headers: {}, 9185 */ 9186 9187 accepts: { 9188 "*": allTypes, 9189 text: "text/plain", 9190 html: "text/html", 9191 xml: "application/xml, text/xml", 9192 json: "application/json, text/javascript" 9193 }, 9194 9195 contents: { 9196 xml: /\bxml\b/, 9197 html: /\bhtml/, 9198 json: /\bjson\b/ 9199 }, 9200 9201 responseFields: { 9202 xml: "responseXML", 9203 text: "responseText", 9204 json: "responseJSON" 9205 }, 9206 9207 // Data converters 9208 // Keys separate source (or catchall "*") and destination types with a single space 9209 converters: { 9210 9211 // Convert anything to text 9212 "* text": String, 9213 9214 // Text to html (true = no transformation) 9215 "text html": true, 9216 9217 // Evaluate text as a json expression 9218 "text json": JSON.parse, 9219 9220 // Parse text as xml 9221 "text xml": jQuery.parseXML 9222 }, 9223 9224 // For options that shouldn't be deep extended: 9225 // you can add your own custom options here if 9226 // and when you create one that shouldn't be 9227 // deep extended (see ajaxExtend) 9228 flatOptions: { 9229 url: true, 9230 context: true 9231 } 9232 }, 9233 9234 // Creates a full fledged settings object into target 9235 // with both ajaxSettings and settings fields. 9236 // If target is omitted, writes into ajaxSettings. 9237 ajaxSetup: function (target, settings) { 9238 return settings ? 9239 9240 // Building a settings object 9241 ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) : 9242 9243 // Extending ajaxSettings 9244 ajaxExtend(jQuery.ajaxSettings, target); 9245 }, 9246 9247 ajaxPrefilter: addToPrefiltersOrTransports(prefilters), 9248 ajaxTransport: addToPrefiltersOrTransports(transports), 9249 9250 // Main method 9251 ajax: function (url, options) { 9252 9253 // If url is an object, simulate pre-1.5 signature 9254 if (typeof url === "object") { 9255 options = url; 9256 url = undefined; 9257 } 9258 9259 // Force options to be an object 9260 options = options || {}; 9261 9262 var transport, 9263 9264 // URL without anti-cache param 9265 cacheURL, 9266 9267 // Response headers 9268 responseHeadersString, 9269 responseHeaders, 9270 9271 // timeout handle 9272 timeoutTimer, 9273 9274 // Url cleanup var 9275 urlAnchor, 9276 9277 // Request state (becomes false upon send and true upon completion) 9278 completed, 9279 9280 // To know if global events are to be dispatched 9281 fireGlobals, 9282 9283 // Loop variable 9284 i, 9285 9286 // uncached part of the url 9287 uncached, 9288 9289 // Create the final options object 9290 s = jQuery.ajaxSetup({}, options), 9291 9292 // Callbacks context 9293 callbackContext = s.context || s, 9294 9295 // Context for global events is callbackContext if it is a DOM node or jQuery collection 9296 globalEventContext = s.context && ( 9297 callbackContext.nodeType || callbackContext.jquery) ? 9298 jQuery(callbackContext) : 9299 jQuery.event, 9300 9301 // Deferreds 9302 deferred = jQuery.Deferred(), 9303 completeDeferred = jQuery.Callbacks("once memory"), 9304 9305 // Status-dependent callbacks 9306 statusCode = s.statusCode || {}, 9307 9308 // Headers (they are sent all at once) 9309 requestHeaders = {}, 9310 requestHeadersNames = {}, 9311 9312 // Default abort message 9313 strAbort = "canceled", 9314 9315 // Fake xhr 9316 jqXHR = { 9317 readyState: 0, 9318 9319 // Builds headers hashtable if needed 9320 getResponseHeader: function (key) { 9321 var match; 9322 if (completed) { 9323 if (!responseHeaders) { 9324 responseHeaders = {}; 9325 while (match = rheaders.exec(responseHeadersString)) { 9326 responseHeaders[match[1].toLowerCase() + " "] = 9327 (responseHeaders[match[1].toLowerCase() + " "] || []). 9328 concat(match[2]); 9329 } 9330 } 9331 match = responseHeaders[key.toLowerCase() + " "]; 9332 } 9333 return match == null ? null : match.join(", "); 9334 }, 9335 9336 // Raw string 9337 getAllResponseHeaders: function () { 9338 return completed ? responseHeadersString : null; 9339 }, 9340 9341 // Caches the header 9342 setRequestHeader: function (name, value) { 9343 if (completed == null) { 9344 name = requestHeadersNames[name.toLowerCase()] = 9345 requestHeadersNames[name.toLowerCase()] || name; 9346 requestHeaders[name] = value; 9347 } 9348 return this; 9349 }, 9350 9351 // Overrides response content-type header 9352 overrideMimeType: function (type) { 9353 if (completed == null) { 9354 s.mimeType = type; 9355 } 9356 return this; 9357 }, 9358 9359 // Status-dependent callbacks 9360 statusCode: function (map) { 9361 var code; 9362 if (map) { 9363 if (completed) { 9364 9365 // Execute the appropriate callbacks 9366 jqXHR.always(map[jqXHR.status]); 9367 } else { 9368 9369 // Lazy-add the new callbacks in a way that preserves old ones 9370 for (code in map) { 9371 statusCode[code] = [statusCode[code], map[code]]; 9372 } 9373 } 9374 } 9375 return this; 9376 }, 9377 9378 // Cancel the request 9379 abort: function (statusText) { 9380 var finalText = statusText || strAbort; 9381 if (transport) { 9382 transport.abort(finalText); 9383 } 9384 done(0, finalText); 9385 return this; 9386 } 9387 }; 9388 9389 // Attach deferreds 9390 deferred.promise(jqXHR); 9391 9392 // Add protocol if not provided (prefilters might expect it) 9393 // Handle falsy url in the settings object (trac-10093: consistency with old signature) 9394 // We also use the url parameter if available 9395 s.url = ((url || s.url || location.href) + ""). 9396 replace(rprotocol, location.protocol + "//"); 9397 9398 // Alias method option to type as per ticket trac-12004 9399 s.type = options.method || options.type || s.method || s.type; 9400 9401 // Extract dataTypes list 9402 s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""]; 9403 9404 // A cross-domain request is in order when the origin doesn't match the current origin. 9405 if (s.crossDomain == null) { 9406 urlAnchor = document.createElement("a"); 9407
vendor: 23,119 bytes, lines 9408-10189
9408 // Support: IE <=8 - 11, Edge 12 - 15 9409 // IE throws exception on accessing the href property if url is malformed, 9410 // e.g. http://example.com:80x/ 9411 try { 9412 urlAnchor.href = s.url; 9413 9414 // Support: IE <=8 - 11 only 9415 // Anchor's host property isn't correctly set when s.url is relative 9416 urlAnchor.href = urlAnchor.href; 9417 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 9418 urlAnchor.protocol + "//" + urlAnchor.host; 9419 } catch (e) { 9420 9421 // If there is an error parsing the URL, assume it is crossDomain, 9422 // it can be rejected by the transport if it is invalid 9423 s.crossDomain = true; 9424 } 9425 } 9426 9427 // Convert data if not already a string 9428 if (s.data && s.processData && typeof s.data !== "string") { 9429 s.data = jQuery.param(s.data, s.traditional); 9430 } 9431 9432 // Apply prefilters 9433 inspectPrefiltersOrTransports(prefilters, s, options, jqXHR); 9434 9435 // If request was aborted inside a prefilter, stop there 9436 if (completed) { 9437 return jqXHR; 9438 } 9439 9440 // We can fire global events as of now if asked to 9441 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118) 9442 fireGlobals = jQuery.event && s.global; 9443 9444 // Watch for a new set of requests 9445 if (fireGlobals && jQuery.active++ === 0) { 9446 jQuery.event.trigger("ajaxStart"); 9447 } 9448 9449 // Uppercase the type 9450 s.type = s.type.toUpperCase(); 9451 9452 // Determine if request has content 9453 s.hasContent = !rnoContent.test(s.type); 9454 9455 // Save the URL in case we're toying with the If-Modified-Since 9456 // and/or If-None-Match header later on 9457 // Remove hash to simplify url manipulation 9458 cacheURL = s.url.replace(rhash, ""); 9459 9460 // More options handling for requests with no content 9461 if (!s.hasContent) { 9462 9463 // Remember the hash so we can put it back 9464 uncached = s.url.slice(cacheURL.length); 9465 9466 // If data is available and should be processed, append data to url 9467 if (s.data && (s.processData || typeof s.data === "string")) { 9468 cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data; 9469 9470 // trac-9682: remove data so that it's not used in an eventual retry 9471 delete s.data; 9472 } 9473 9474 // Add or update anti-cache param if needed 9475 if (s.cache === false) { 9476 cacheURL = cacheURL.replace(rantiCache, "$1"); 9477 uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce.guid++ + 9478 uncached; 9479 } 9480 9481 // Put hash and anti-cache on the URL that will be requested (gh-1732) 9482 s.url = cacheURL + uncached; 9483 9484 // Change '%20' to '+' if this is encoded form body content (gh-2658) 9485 } else if (s.data && s.processData && 9486 (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) { 9487 s.data = s.data.replace(r20, "+"); 9488 } 9489 9490 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9491 if (s.ifModified) { 9492 if (jQuery.lastModified[cacheURL]) { 9493 jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]); 9494 } 9495 if (jQuery.etag[cacheURL]) { 9496 jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]); 9497 } 9498 } 9499 9500 // Set the correct header, if data is being sent 9501 if (s.data && s.hasContent && s.contentType !== false || options.contentType) { 9502 jqXHR.setRequestHeader("Content-Type", s.contentType); 9503 } 9504 9505 // Set the Accepts header for the server, depending on the dataType 9506 jqXHR.setRequestHeader( 9507 "Accept", 9508 s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? 9509 s.accepts[s.dataTypes[0]] + ( 9510 s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : 9511 s.accepts["*"] 9512 ); 9513 9514 // Check for headers option 9515 for (i in s.headers) { 9516 jqXHR.setRequestHeader(i, s.headers[i]); 9517 } 9518 9519 // Allow custom headers/mimetypes and early abort 9520 if (s.beforeSend && ( 9521 s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) { 9522 9523 // Abort if not done already and return 9524 return jqXHR.abort(); 9525 } 9526 9527 // Aborting is no longer a cancellation 9528 strAbort = "abort"; 9529 9530 // Install callbacks on deferreds 9531 completeDeferred.add(s.complete); 9532 jqXHR.done(s.success); 9533 jqXHR.fail(s.error); 9534 9535 // Get transport 9536 transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR); 9537 9538 // If no transport, we auto-abort 9539 if (!transport) { 9540 done(-1, "No Transport"); 9541 } else { 9542 jqXHR.readyState = 1; 9543 9544 // Send global event 9545 if (fireGlobals) { 9546 globalEventContext.trigger("ajaxSend", [jqXHR, s]); 9547 } 9548 9549 // If request was aborted inside ajaxSend, stop there 9550 if (completed) { 9551 return jqXHR; 9552 } 9553 9554 // Timeout 9555 if (s.async && s.timeout > 0) { 9556 timeoutTimer = window.setTimeout(function () { 9557 jqXHR.abort("timeout"); 9558 }, s.timeout); 9559 } 9560 9561 try { 9562 completed = false; 9563 transport.send(requestHeaders, done); 9564 } catch (e) { 9565 9566 // Rethrow post-completion exceptions 9567 if (completed) { 9568 throw e; 9569 } 9570 9571 // Propagate others as results 9572 done(-1, e); 9573 } 9574 } 9575 9576 // Callback for when everything is done 9577 function done(status, nativeStatusText, responses, headers) { 9578 var isSuccess,success,error,response,modified, 9579 statusText = nativeStatusText; 9580 9581 // Ignore repeat invocations 9582 if (completed) { 9583 return; 9584 } 9585 9586 completed = true; 9587 9588 // Clear timeout if it exists 9589 if (timeoutTimer) { 9590 window.clearTimeout(timeoutTimer); 9591 } 9592 9593 // Dereference transport for early garbage collection 9594 // (no matter how long the jqXHR object will be used) 9595 transport = undefined; 9596 9597 // Cache response headers 9598 responseHeadersString = headers || ""; 9599 9600 // Set readyState 9601 jqXHR.readyState = status > 0 ? 4 : 0; 9602 9603 // Determine if successful 9604 isSuccess = status >= 200 && status < 300 || status === 304; 9605 9606 // Get response data 9607 if (responses) { 9608 response = ajaxHandleResponses(s, jqXHR, responses); 9609 } 9610 9611 // Use a noop converter for missing script but not if jsonp 9612 if (!isSuccess && 9613 jQuery.inArray("script", s.dataTypes) > -1 && 9614 jQuery.inArray("json", s.dataTypes) < 0) { 9615 s.converters["text script"] = function () {}; 9616 } 9617 9618 // Convert no matter what (that way responseXXX fields are always set) 9619 response = ajaxConvert(s, response, jqXHR, isSuccess); 9620 9621 // If successful, handle type chaining 9622 if (isSuccess) { 9623 9624 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9625 if (s.ifModified) { 9626 modified = jqXHR.getResponseHeader("Last-Modified"); 9627 if (modified) { 9628 jQuery.lastModified[cacheURL] = modified; 9629 } 9630 modified = jqXHR.getResponseHeader("etag"); 9631 if (modified) { 9632 jQuery.etag[cacheURL] = modified; 9633 } 9634 } 9635 9636 // if no content 9637 if (status === 204 || s.type === "HEAD") { 9638 statusText = "nocontent"; 9639 9640 // if not modified 9641 } else if (status === 304) { 9642 statusText = "notmodified"; 9643 9644 // If we have data, let's convert it 9645 } else { 9646 statusText = response.state; 9647 success = response.data; 9648 error = response.error; 9649 isSuccess = !error; 9650 } 9651 } else { 9652 9653 // Extract error from statusText and normalize for non-aborts 9654 error = statusText; 9655 if (status || !statusText) { 9656 statusText = "error"; 9657 if (status < 0) { 9658 status = 0; 9659 } 9660 } 9661 } 9662 9663 // Set data for the fake xhr object 9664 jqXHR.status = status; 9665 jqXHR.statusText = (nativeStatusText || statusText) + ""; 9666 9667 // Success/Error 9668 if (isSuccess) { 9669 deferred.resolveWith(callbackContext, [success, statusText, jqXHR]); 9670 } else { 9671 deferred.rejectWith(callbackContext, [jqXHR, statusText, error]); 9672 } 9673 9674 // Status-dependent callbacks 9675 jqXHR.statusCode(statusCode); 9676 statusCode = undefined; 9677 9678 if (fireGlobals) { 9679 globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", 9680 [jqXHR, s, isSuccess ? success : error]); 9681 } 9682 9683 // Complete 9684 completeDeferred.fireWith(callbackContext, [jqXHR, statusText]); 9685 9686 if (fireGlobals) { 9687 globalEventContext.trigger("ajaxComplete", [jqXHR, s]); 9688 9689 // Handle the global AJAX counter 9690 if (! --jQuery.active) { 9691 jQuery.event.trigger("ajaxStop"); 9692 } 9693 } 9694 } 9695 9696 return jqXHR; 9697 }, 9698 9699 getJSON: function (url, data, callback) { 9700 return jQuery.get(url, data, callback, "json"); 9701 }, 9702 9703 getScript: function (url, callback) { 9704 return jQuery.get(url, undefined, callback, "script"); 9705 } 9706 }); 9707 9708 jQuery.each(["get", "post"], function (_i, method) { 9709 jQuery[method] = function (url, data, callback, type) { 9710 9711 // Shift arguments if data argument was omitted 9712 if (isFunction(data)) { 9713 type = type || callback; 9714 callback = data; 9715 data = undefined; 9716 } 9717 9718 // The url can be an options object (which then must have .url) 9719 return jQuery.ajax(jQuery.extend({ 9720 url: url, 9721 type: method, 9722 dataType: type, 9723 data: data, 9724 success: callback 9725 }, jQuery.isPlainObject(url) && url)); 9726 }; 9727 }); 9728 9729 jQuery.ajaxPrefilter(function (s) { 9730 var i; 9731 for (i in s.headers) { 9732 if (i.toLowerCase() === "content-type") { 9733 s.contentType = s.headers[i] || ""; 9734 } 9735 } 9736 }); 9737 9738 9739 jQuery._evalUrl = function (url, options, doc) { 9740 return jQuery.ajax({ 9741 url: url, 9742 9743 // Make this explicit, since user can override this through ajaxSetup (trac-11264) 9744 type: "GET", 9745 dataType: "script", 9746 cache: true, 9747 async: false, 9748 global: false, 9749 9750 // Only evaluate the response if it is successful (gh-4126) 9751 // dataFilter is not invoked for failure responses, so using it instead 9752 // of the default converter is kludgy but it works. 9753 converters: { 9754 "text script": function () {} 9755 }, 9756 dataFilter: function (response) { 9757 jQuery.globalEval(response, options, doc); 9758 } 9759 }); 9760 }; 9761 9762 9763 jQuery.fn.extend({ 9764 wrapAll: function (html) { 9765 var wrap; 9766 9767 if (this[0]) { 9768 if (isFunction(html)) { 9769 html = html.call(this[0]); 9770 } 9771 9772 // The elements to wrap the target around 9773 wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true); 9774 9775 if (this[0].parentNode) { 9776 wrap.insertBefore(this[0]); 9777 } 9778 9779 wrap.map(function () { 9780 var elem = this; 9781 9782 while (elem.firstElementChild) { 9783 elem = elem.firstElementChild; 9784 } 9785 9786 return elem; 9787 }).append(this); 9788 } 9789 9790 return this; 9791 }, 9792 9793 wrapInner: function (html) { 9794 if (isFunction(html)) { 9795 return this.each(function (i) { 9796 jQuery(this).wrapInner(html.call(this, i)); 9797 }); 9798 } 9799 9800 return this.each(function () { 9801 var self = jQuery(this), 9802 contents = self.contents(); 9803 9804 if (contents.length) { 9805 contents.wrapAll(html); 9806 9807 } else { 9808 self.append(html); 9809 } 9810 }); 9811 }, 9812 9813 wrap: function (html) { 9814 var htmlIsFunction = isFunction(html); 9815 9816 return this.each(function (i) { 9817 jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html); 9818 }); 9819 }, 9820 9821 unwrap: function (selector) { 9822 this.parent(selector).not("body").each(function () { 9823 jQuery(this).replaceWith(this.childNodes); 9824 }); 9825 return this; 9826 } 9827 }); 9828 9829 9830 jQuery.expr.pseudos.hidden = function (elem) { 9831 return !jQuery.expr.pseudos.visible(elem); 9832 }; 9833 jQuery.expr.pseudos.visible = function (elem) { 9834 return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); 9835 }; 9836 9837 9838 9839 9840 jQuery.ajaxSettings.xhr = function () { 9841 try { 9842 return new window.XMLHttpRequest(); 9843 } catch (e) {} 9844 }; 9845 9846 var xhrSuccessStatus = { 9847 9848 // File protocol always yields status code 0, assume 200 9849 0: 200, 9850 9851 // Support: IE <=9 only 9852 // trac-1450: sometimes IE returns 1223 when it should be 204 9853 1223: 204 9854 }, 9855 xhrSupported = jQuery.ajaxSettings.xhr(); 9856 9857 support.cors = !!xhrSupported && "withCredentials" in xhrSupported; 9858 support.ajax = xhrSupported = !!xhrSupported; 9859 9860 jQuery.ajaxTransport(function (options) { 9861 var callback, errorCallback; 9862 9863 // Cross domain only allowed if supported through XMLHttpRequest 9864 if (support.cors || xhrSupported && !options.crossDomain) { 9865 return { 9866 send: function (headers, complete) { 9867 var i, 9868 xhr = options.xhr(); 9869 9870 xhr.open( 9871 options.type, 9872 options.url, 9873 options.async, 9874 options.username, 9875 options.password 9876 ); 9877 9878 // Apply custom fields if provided 9879 if (options.xhrFields) { 9880 for (i in options.xhrFields) { 9881 xhr[i] = options.xhrFields[i]; 9882 } 9883 } 9884 9885 // Override mime type if needed 9886 if (options.mimeType && xhr.overrideMimeType) { 9887 xhr.overrideMimeType(options.mimeType); 9888 } 9889 9890 // X-Requested-With header 9891 // For cross-domain requests, seeing as conditions for a preflight are 9892 // akin to a jigsaw puzzle, we simply never set it to be sure. 9893 // (it can always be set on a per-request basis or even using ajaxSetup) 9894 // For same-domain requests, won't change header if already provided. 9895 if (!options.crossDomain && !headers["X-Requested-With"]) { 9896 headers["X-Requested-With"] = "XMLHttpRequest"; 9897 } 9898 9899 // Set headers 9900 for (i in headers) { 9901 xhr.setRequestHeader(i, headers[i]); 9902 } 9903 9904 // Callback 9905 callback = function (type) { 9906 return function () { 9907 if (callback) { 9908 callback = errorCallback = xhr.onload = 9909 xhr.onerror = xhr.onabort = xhr.ontimeout = 9910 xhr.onreadystatechange = null; 9911 9912 if (type === "abort") { 9913 xhr.abort(); 9914 } else if (type === "error") { 9915 9916 // Support: IE <=9 only 9917 // On a manual native abort, IE9 throws 9918 // errors on any property access that is not readyState 9919 if (typeof xhr.status !== "number") { 9920 complete(0, "error"); 9921 } else { 9922 complete( 9923 9924 // File: protocol always yields status 0; see trac-8605, trac-14207 9925 xhr.status, 9926 xhr.statusText 9927 ); 9928 } 9929 } else { 9930 complete( 9931 xhrSuccessStatus[xhr.status] || xhr.status, 9932 xhr.statusText, 9933 9934 // Support: IE <=9 only 9935 // IE9 has no XHR2 but throws on binary (trac-11426) 9936 // For XHR2 non-text, let the caller handle it (gh-2498) 9937 (xhr.responseType || "text") !== "text" || 9938 typeof xhr.responseText !== "string" ? 9939 { binary: xhr.response } : 9940 { text: xhr.responseText }, 9941 xhr.getAllResponseHeaders() 9942 ); 9943 } 9944 } 9945 }; 9946 }; 9947 9948 // Listen to events 9949 xhr.onload = callback(); 9950 errorCallback = xhr.onerror = xhr.ontimeout = callback("error"); 9951 9952 // Support: IE 9 only 9953 // Use onreadystatechange to replace onabort 9954 // to handle uncaught aborts 9955 if (xhr.onabort !== undefined) { 9956 xhr.onabort = errorCallback; 9957 } else { 9958 xhr.onreadystatechange = function () { 9959 9960 // Check readyState before timeout as it changes 9961 if (xhr.readyState === 4) { 9962 9963 // Allow onerror to be called first, 9964 // but that will not handle a native abort 9965 // Also, save errorCallback to a variable 9966 // as xhr.onerror cannot be accessed 9967 window.setTimeout(function () { 9968 if (callback) { 9969 errorCallback(); 9970 } 9971 }); 9972 } 9973 }; 9974 } 9975 9976 // Create the abort callback 9977 callback = callback("abort"); 9978 9979 try { 9980 9981 // Do send the request (this may raise an exception) 9982 xhr.send(options.hasContent && options.data || null); 9983 } catch (e) { 9984 9985 // trac-14683: Only rethrow if this hasn't been notified as an error yet 9986 if (callback) { 9987 throw e; 9988 } 9989 } 9990 }, 9991 9992 abort: function () { 9993 if (callback) { 9994 callback(); 9995 } 9996 } 9997 }; 9998 } 9999 }); 10000 10001 10002 10003 10004 // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 10005 jQuery.ajaxPrefilter(function (s) { 10006 if (s.crossDomain) { 10007 s.contents.script = false; 10008 } 10009 }); 10010 10011 // Install script dataType 10012 jQuery.ajaxSetup({ 10013 accepts: { 10014 script: "text/javascript, application/javascript, " + 10015 "application/ecmascript, application/x-ecmascript" 10016 }, 10017 contents: { 10018 script: /\b(?:java|ecma)script\b/ 10019 }, 10020 converters: { 10021 "text script": function (text) { 10022 jQuery.globalEval(text); 10023 return text; 10024 } 10025 } 10026 }); 10027 10028 // Handle cache's special case and crossDomain 10029 jQuery.ajaxPrefilter("script", function (s) { 10030 if (s.cache === undefined) { 10031 s.cache = false; 10032 } 10033 if (s.crossDomain) { 10034 s.type = "GET"; 10035 } 10036 }); 10037 10038 // Bind script tag hack transport 10039 jQuery.ajaxTransport("script", function (s) { 10040 10041 // This transport only deals with cross domain or forced-by-attrs requests 10042 if (s.crossDomain || s.scriptAttrs) { 10043 var script, callback; 10044 return { 10045 send: function (_, complete) { 10046 script = jQuery("<script>"). 10047 attr(s.scriptAttrs || {}). 10048 prop({ charset: s.scriptCharset, src: s.url }). 10049 on("load error", callback = function (evt) { 10050 script.remove(); 10051 callback = null; 10052 if (evt) { 10053 complete(evt.type === "error" ? 404 : 200, evt.type); 10054 } 10055 }); 10056 10057 // Use native DOM manipulation to avoid our domManip AJAX trickery 10058 document.head.appendChild(script[0]); 10059 }, 10060 abort: function () { 10061 if (callback) { 10062 callback(); 10063 } 10064 } 10065 }; 10066 } 10067 }); 10068 10069 10070 10071 10072 var oldCallbacks = [], 10073 rjsonp = /(=)\?(?=&|$)|\?\?/; 10074 10075 // Default jsonp settings 10076 jQuery.ajaxSetup({ 10077 jsonp: "callback", 10078 jsonpCallback: function () { 10079 var callback = oldCallbacks.pop() || jQuery.expando + "_" + nonce.guid++; 10080 this[callback] = true; 10081 return callback; 10082 } 10083 }); 10084 10085 // Detect, normalize options and install callbacks for jsonp requests 10086 jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) { 10087 10088 var callbackName,overwritten,responseContainer, 10089 jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? 10090 "url" : 10091 typeof s.data === "string" && 10092 (s.contentType || ""). 10093 indexOf("application/x-www-form-urlencoded") === 0 && 10094 rjsonp.test(s.data) && "data"); 10095 10096 10097 // Handle iff the expected data type is "jsonp" or we have a parameter to set 10098 if (jsonProp || s.dataTypes[0] === "jsonp") { 10099 10100 // Get callback name, remembering preexisting value associated with it 10101 callbackName = s.jsonpCallback = isFunction(s.jsonpCallback) ? 10102 s.jsonpCallback() : 10103 s.jsonpCallback; 10104 10105 // Insert callback into url or form data 10106 if (jsonProp) { 10107 s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName); 10108 } else if (s.jsonp !== false) { 10109 s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName; 10110 } 10111 10112 // Use data converter to retrieve json after script execution 10113 s.converters["script json"] = function () { 10114 if (!responseContainer) { 10115 jQuery.error(callbackName + " was not called"); 10116 } 10117 return responseContainer[0]; 10118 }; 10119 10120 // Force json dataType 10121 s.dataTypes[0] = "json"; 10122 10123 // Install callback 10124 overwritten = window[callbackName]; 10125 window[callbackName] = function () { 10126 responseContainer = arguments; 10127 }; 10128 10129 // Clean-up function (fires after converters) 10130 jqXHR.always(function () { 10131 10132 // If previous value didn't exist - remove it 10133 if (overwritten === undefined) { 10134 jQuery(window).removeProp(callbackName); 10135 10136 // Otherwise restore preexisting value 10137 } else { 10138 window[callbackName] = overwritten; 10139 } 10140 10141 // Save back as free 10142 if (s[callbackName]) { 10143 10144 // Make sure that re-using the options doesn't screw things around 10145 s.jsonpCallback = originalSettings.jsonpCallback; 10146 10147 // Save the callback name for future use 10148 oldCallbacks.push(callbackName); 10149 } 10150 10151 // Call if it was a function and we have a response 10152 if (responseContainer && isFunction(overwritten)) { 10153 overwritten(responseContainer[0]); 10154 } 10155 10156 responseContainer = overwritten = undefined; 10157 }); 10158 10159 // Delegate to script 10160 return "script"; 10161 } 10162 }); 10163 10164 10165 10166 10167 // Support: Safari 8 only 10168 // In Safari 8 documents created via document.implementation.createHTMLDocument 10169 // collapse sibling forms: the second one becomes a child of the first one. 10170 // Because of that, this security measure has to be disabled in Safari 8. 10171 // https://bugs.webkit.org/show_bug.cgi?id=137337 10172 support.createHTMLDocument = function () { 10173 var body = document.implementation.createHTMLDocument("").body; 10174 body.innerHTML = "<form></form><form></form>"; 10175 return body.childNodes.length === 2; 10176 }(); 10177 10178 10179 // Argument "data" should be string of html 10180 // context (optional): If specified, the fragment will be created in this context, 10181 // defaults to document 10182 // keepScripts (optional): If true, will include scripts passed in the html string 10183 jQuery.parseHTML = function (data, context, keepScripts) { 10184 if (typeof data !== "string") { 10185 return []; 10186 } 10187 if (typeof context === "boolean") { 10188 keepScripts = context; 10189 context = false;
vendor: 5,097 bytes, lines 10190-10378
10190 } 10191 10192 var base, parsed, scripts; 10193 10194 if (!context) { 10195 10196 // Stop scripts or inline event handlers from being executed immediately 10197 // by using document.implementation 10198 if (support.createHTMLDocument) { 10199 context = document.implementation.createHTMLDocument(""); 10200 10201 // Set the base href for the created document 10202 // so any parsed elements with URLs 10203 // are based on the document's URL (gh-2965) 10204 base = context.createElement("base"); 10205 base.href = document.location.href; 10206 context.head.appendChild(base); 10207 } else { 10208 context = document; 10209 } 10210 } 10211 10212 parsed = rsingleTag.exec(data); 10213 scripts = !keepScripts && []; 10214 10215 // Single tag 10216 if (parsed) { 10217 return [context.createElement(parsed[1])]; 10218 } 10219 10220 parsed = buildFragment([data], context, scripts); 10221 10222 if (scripts && scripts.length) { 10223 jQuery(scripts).remove(); 10224 } 10225 10226 return jQuery.merge([], parsed.childNodes); 10227 }; 10228 10229 10230 /** 10231 * Load a url into a page 10232 */ 10233 jQuery.fn.load = function (url, params, callback) { 10234 var selector,type,response, 10235 self = this, 10236 off = url.indexOf(" "); 10237 10238 if (off > -1) { 10239 selector = stripAndCollapse(url.slice(off)); 10240 url = url.slice(0, off); 10241 } 10242 10243 // If it's a function 10244 if (isFunction(params)) { 10245 10246 // We assume that it's the callback 10247 callback = params; 10248 params = undefined; 10249 10250 // Otherwise, build a param string 10251 } else if (params && typeof params === "object") { 10252 type = "POST"; 10253 } 10254 10255 // If we have elements to modify, make the request 10256 if (self.length > 0) { 10257 jQuery.ajax({ 10258 url: url, 10259 10260 // If "type" variable is undefined, then "GET" method will be used. 10261 // Make value of this field explicit since 10262 // user can override it through ajaxSetup method 10263 type: type || "GET", 10264 dataType: "html", 10265 data: params 10266 }).done(function (responseText) { 10267 10268 // Save response for use in complete callback 10269 response = arguments; 10270 10271 self.html(selector ? 10272 10273 // If a selector was specified, locate the right elements in a dummy div 10274 // Exclude scripts to avoid IE 'Permission Denied' errors 10275 jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) : 10276 10277 // Otherwise use the full result 10278 responseText); 10279 10280 // If the request succeeds, this function gets "data", "status", "jqXHR" 10281 // but they are ignored because response was set above. 10282 // If it fails, this function gets "jqXHR", "status", "error" 10283 }).always(callback && function (jqXHR, status) { 10284 self.each(function () { 10285 callback.apply(this, response || [jqXHR.responseText, status, jqXHR]); 10286 }); 10287 }); 10288 } 10289 10290 return this; 10291 }; 10292 10293 10294 10295 10296 jQuery.expr.pseudos.animated = function (elem) { 10297 return jQuery.grep(jQuery.timers, function (fn) { 10298 return elem === fn.elem; 10299 }).length; 10300 }; 10301 10302 10303 10304 10305 jQuery.offset = { 10306 setOffset: function (elem, options, i) { 10307 var curPosition,curLeft,curCSSTop,curTop,curOffset,curCSSLeft,calculatePosition, 10308 position = jQuery.css(elem, "position"), 10309 curElem = jQuery(elem), 10310 props = {}; 10311 10312 // Set position first, in-case top/left are set even on static elem 10313 if (position === "static") { 10314 elem.style.position = "relative"; 10315 } 10316 10317 curOffset = curElem.offset(); 10318 curCSSTop = jQuery.css(elem, "top"); 10319 curCSSLeft = jQuery.css(elem, "left"); 10320 calculatePosition = (position === "absolute" || position === "fixed") && 10321 (curCSSTop + curCSSLeft).indexOf("auto") > -1; 10322 10323 // Need to be able to calculate position if either 10324 // top or left is auto and position is either absolute or fixed 10325 if (calculatePosition) { 10326 curPosition = curElem.position(); 10327 curTop = curPosition.top; 10328 curLeft = curPosition.left; 10329 10330 } else { 10331 curTop = parseFloat(curCSSTop) || 0; 10332 curLeft = parseFloat(curCSSLeft) || 0; 10333 } 10334 10335 if (isFunction(options)) { 10336 10337 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 10338 options = options.call(elem, i, jQuery.extend({}, curOffset)); 10339 } 10340 10341 if (options.top != null) { 10342 props.top = options.top - curOffset.top + curTop; 10343 } 10344 if (options.left != null) { 10345 props.left = options.left - curOffset.left + curLeft; 10346 } 10347 10348 if ("using" in options) { 10349 options.using.call(elem, props); 10350 10351 } else { 10352 curElem.css(props); 10353 } 10354 } 10355 }; 10356 10357 jQuery.fn.extend({ 10358 10359 // offset() relates an element's border box to the document origin 10360 offset: function (options) { 10361 10362 // Preserve chaining for setter 10363 if (arguments.length) { 10364 return options === undefined ? 10365 this : 10366 this.each(function (i) { 10367 jQuery.offset.setOffset(this, options, i); 10368 }); 10369 } 10370 10371 var rect,win, 10372 elem = this[0]; 10373 10374 if (!elem) { 10375 return; 10376 } 10377 10378 // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
vendor: 5,057 bytes, lines 10379-10520
10379 // Support: IE <=11 only 10380 // Running getBoundingClientRect on a 10381 // disconnected node in IE throws an error 10382 if (!elem.getClientRects().length) { 10383 return { top: 0, left: 0 }; 10384 } 10385 10386 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 10387 rect = elem.getBoundingClientRect(); 10388 win = elem.ownerDocument.defaultView; 10389 return { 10390 top: rect.top + win.pageYOffset, 10391 left: rect.left + win.pageXOffset 10392 }; 10393 }, 10394 10395 // position() relates an element's margin box to its offset parent's padding box 10396 // This corresponds to the behavior of CSS absolute positioning 10397 position: function () { 10398 if (!this[0]) { 10399 return; 10400 } 10401 10402 var offsetParent,offset,doc, 10403 elem = this[0], 10404 parentOffset = { top: 0, left: 0 }; 10405 10406 // position:fixed elements are offset from the viewport, which itself always has zero offset 10407 if (jQuery.css(elem, "position") === "fixed") { 10408 10409 // Assume position:fixed implies availability of getBoundingClientRect 10410 offset = elem.getBoundingClientRect(); 10411 10412 } else { 10413 offset = this.offset(); 10414 10415 // Account for the *real* offset parent, which can be the document or its root element 10416 // when a statically positioned element is identified 10417 doc = elem.ownerDocument; 10418 offsetParent = elem.offsetParent || doc.documentElement; 10419 while (offsetParent && ( 10420 offsetParent === doc.body || offsetParent === doc.documentElement) && 10421 jQuery.css(offsetParent, "position") === "static") { 10422 10423 offsetParent = offsetParent.parentNode; 10424 } 10425 if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) { 10426 10427 // Incorporate borders into its offset, since they are outside its content origin 10428 parentOffset = jQuery(offsetParent).offset(); 10429 parentOffset.top += jQuery.css(offsetParent, "borderTopWidth", true); 10430 parentOffset.left += jQuery.css(offsetParent, "borderLeftWidth", true); 10431 } 10432 } 10433 10434 // Subtract parent offsets and element margins 10435 return { 10436 top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true), 10437 left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true) 10438 }; 10439 }, 10440 10441 // This method will return documentElement in the following cases: 10442 // 1) For the element inside the iframe without offsetParent, this method will return 10443 // documentElement of the parent window 10444 // 2) For the hidden or detached element 10445 // 3) For body or html element, i.e. in case of the html node - it will return itself 10446 // 10447 // but those exceptions were never presented as a real life use-cases 10448 // and might be considered as more preferable results. 10449 // 10450 // This logic, however, is not guaranteed and can change at any point in the future 10451 offsetParent: function () { 10452 return this.map(function () { 10453 var offsetParent = this.offsetParent; 10454 10455 while (offsetParent && jQuery.css(offsetParent, "position") === "static") { 10456 offsetParent = offsetParent.offsetParent; 10457 } 10458 10459 return offsetParent || documentElement; 10460 }); 10461 } 10462 }); 10463 10464 // Create scrollLeft and scrollTop methods 10465 jQuery.each({ scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function (method, prop) { 10466 var top = "pageYOffset" === prop; 10467 10468 jQuery.fn[method] = function (val) { 10469 return access(this, function (elem, method, val) { 10470 10471 // Coalesce documents and windows 10472 var win; 10473 if (isWindow(elem)) { 10474 win = elem; 10475 } else if (elem.nodeType === 9) { 10476 win = elem.defaultView; 10477 } 10478 10479 if (val === undefined) { 10480 return win ? win[prop] : elem[method]; 10481 } 10482 10483 if (win) { 10484 win.scrollTo( 10485 !top ? val : win.pageXOffset, 10486 top ? val : win.pageYOffset 10487 ); 10488 10489 } else { 10490 elem[method] = val; 10491 } 10492 }, method, val, arguments.length); 10493 }; 10494 }); 10495 10496 // Support: Safari <=7 - 9.1, Chrome <=37 - 49 10497 // Add the top/left cssHooks using jQuery.fn.position 10498 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 10499 // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 10500 // getComputedStyle returns percent when specified for top/left/bottom/right; 10501 // rather than make the css module depend on the offset module, just check for it here 10502 jQuery.each(["top", "left"], function (_i, prop) { 10503 jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition, 10504 function (elem, computed) { 10505 if (computed) { 10506 computed = curCSS(elem, prop); 10507 10508 // If curCSS returns percentage, fallback to offset 10509 return rnumnonpx.test(computed) ? 10510 jQuery(elem).position()[prop] + "px" : 10511 computed; 10512 } 10513 } 10514 ); 10515 }); 10516 10517 10518 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 10519 jQuery.each({ Height: "height", Width: "width" }, function (name, type) { 10520 jQuery.each({
10521 padding: "inner" + name, 10522 content: type, 10523 "": "outer" + name 10524 }, function (defaultExtra, funcName) { 10525 10526 // Margin is only for outerHeight, outerWidth 10527 jQuery.fn[funcName] = function (margin, value) { 10528 var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"), 10529 extra = defaultExtra || (margin === true || value === true ? "margin" : "border"); 10530 10531 return access(this, function (elem, type, value) { 10532 var doc; 10533 10534 if (isWindow(elem)) { 10535 10536 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 10537 return funcName.indexOf("outer") === 0 ? 10538 elem["inner" + name] : 10539 elem.document.documentElement["client" + name]; 10540 } 10541 10542 // Get document width or height 10543 if (elem.nodeType === 9) { 10544 doc = elem.documentElement; 10545 10546 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 10547 // whichever is greatest 10548 return Math.max( 10549 elem.body["scroll" + name], doc["scroll" + name], 10550 elem.body["offset" + name], doc["offset" + name], 10551 doc["client" + name] 10552 ); 10553 } 10554 10555 return value === undefined ? 10556 10557 // Get width or height on the element, requesting but not forcing parseFloat 10558 jQuery.css(elem, type, extra) : 10559 10560 // Set width or height on the element 10561 jQuery.style(elem, type, value, extra); 10562 }, type, chainable ? margin : undefined, chainable); 10563 }; 10564 }); 10565 }); 10566 10567 10568 jQuery.each([ 10569 "ajaxStart", 10570 "ajaxStop", 10571 "ajaxComplete", 10572 "ajaxError", 10573 "ajaxSuccess", 10574 "ajaxSend"], 10575 function (_i, type) { 10576 jQuery.fn[type] = function (fn) { 10577 return this.on(type, fn); 10578 }; 10579 }); 10580 10581 10582 10583 10584 jQuery.fn.extend({ 10585 10586 bind: function (types, data, fn) { 10587 return this.on(types, null, data, fn); 10588 }, 10589 unbind: function (types, fn) { 10590 return this.off(types, null, fn); 10591 }, 10592 10593 delegate: function (selector, types, data, fn) { 10594 return this.on(types, selector, data, fn); 10595 }, 10596 undelegate: function (selector, types, fn) { 10597 10598 // ( namespace ) or ( selector, types [, fn] ) 10599 return arguments.length === 1 ? 10600 this.off(selector, "**") : 10601 this.off(types, selector || "**", fn); 10602 }, 10603 10604 hover: function (fnOver, fnOut) { 10605 return this. 10606 on("mouseenter", fnOver). 10607 on("mouseleave", fnOut || fnOver); 10608 } 10609 }); 10610 10611 jQuery.each( 10612 ("blur focus focusin focusout resize scroll click dblclick " + 10613 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 10614 "change select submit keydown keypress keyup contextmenu").split(" "), 10615 function (_i, name) { 10616 10617 // Handle event binding 10618 jQuery.fn[name] = function (data, fn) { 10619 return arguments.length > 0 ? 10620 this.on(name, null, data, fn) : 10621 this.trigger(name); 10622 }; 10623 } 10624 ); 10625 10626 10627 10628 10629 // Support: Android <=4.0 only 10630 // Make sure we trim BOM and NBSP 10631 // Require that the "whitespace run" starts from a non-whitespace 10632 // to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position. 10633 var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g; 10634 10635 // Bind a function to a context, optionally partially applying any 10636 // arguments. 10637 // jQuery.proxy is deprecated to promote standards (specifically Function#bind) 10638 // However, it is not slated for removal any time soon 10639 jQuery.proxy = function (fn, context) { 10640 var tmp, args, proxy; 10641 10642 if (typeof context === "string") { 10643 tmp = fn[context]; 10644 context = fn; 10645 fn = tmp; 10646 } 10647 10648 // Quick check to determine if target is callable, in the spec 10649 // this throws a TypeError, but we will just return undefined. 10650 if (!isFunction(fn)) { 10651 return undefined; 10652 } 10653 10654 // Simulated bind 10655 args = slice.call(arguments, 2); 10656 proxy = function () { 10657 return fn.apply(context || this, args.concat(slice.call(arguments))); 10658 }; 10659 10660 // Set the guid of unique handler to the same of original handler, so it can be removed 10661 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 10662 10663 return proxy; 10664 }; 10665 10666 jQuery.holdReady = function (hold) { 10667 if (hold) { 10668 jQuery.readyWait++; 10669 } else { 10670 jQuery.ready(true); 10671 } 10672 }; 10673 jQuery.isArray = Array.isArray; 10674 jQuery.parseJSON = JSON.parse; 10675 jQuery.nodeName = nodeName; 10676 jQuery.isFunction = isFunction; 10677 jQuery.isWindow = isWindow; 10678 jQuery.camelCase = camelCase; 10679 jQuery.type = toType; 10680 10681 jQuery.now = Date.now; 10682 10683 jQuery.isNumeric = function (obj) { 10684 10685 // As of jQuery 3.0, isNumeric is limited to 10686 // strings and numbers (primitives or objects) 10687 // that can be coerced to finite numbers (gh-2662) 10688 var type = jQuery.type(obj); 10689 return (type === "number" || type === "string") && 10690 10691 // parseFloat NaNs numeric-cast false positives ("") 10692 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 10693 // subtraction forces infinities to NaN 10694 !isNaN(obj - parseFloat(obj)); 10695 }; 10696 10697 jQuery.trim = function (text) { 10698 return text == null ? 10699 "" : 10700 (text + "").replace(rtrim, "$1"); 10701 }; 10702 10703 10704 10705 // Register as a named AMD module, since jQuery can be concatenated with other 10706 // files that may use define, but not via a proper concatenation script that 10707 // understands anonymous AMD modules. A named AMD is safest and most robust 10708 // way to register. Lowercase jquery is used because AMD module names are 10709 // derived from file names, and jQuery is normally delivered in a lowercase 10710 // file name. Do this after creating the global so that if an AMD module wants 10711 // to call noConflict to hide this version of jQuery, it will work. 10712 10713 // Note that for maximum portability, libraries that are not jQuery should 10714 // declare themselves as anonymous modules, and avoid setting a global if an 10715 // AMD loader is present. jQuery is a special case. For more information, see 10716 // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 10717 10718 if (typeof define === "function" && define.amd) { 10719 define("jquery", [], function () { 10720 return jQuery; 10721 }); 10722 } 10723 10724 10725 10726 10727 var 10728 10729 // Map over jQuery in case of overwrite 10730 _jQuery = window.jQuery, 10731 10732 // Map over the $ in case of overwrite 10733 _$ = window.$; 10734 10735 jQuery.noConflict = function (deep) { 10736 if (window.$ === jQuery) { 10737 window.$ = _$; 10738 } 10739 10740 if (deep && window.jQuery === jQuery) { 10741 window.jQuery = _jQuery; 10742 } 10743 10744 return jQuery; 10745 }; 10746 10747 // Expose jQuery and $ identifiers, even in AMD 10748 // (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557) 10749 // and CommonJS for browser emulators (trac-13566) 10750 if (typeof noGlobal === "undefined") { 10751 window.jQuery = window.$ = jQuery; 10752 } 10753 10754 10755 10756 10757 return jQuery; 10758}); 10759 10760 /* Ende jquery */ 10761 /* Start tracking */ 10762 "use strict";var _paq=_paq||[];function matomoConsentFunction(){var t=$("body").attr("data-tracking-site-id"),e=document.createElement("script");_paq.push(["setConsentGiven"]),/^\d+$/u.test(t)&&0===$("#cmsMatomoScript").length&&(_paq.push(["disableCookies"]),_paq.push(["requireConsent"]),_paq.push(["setDocumentTitle",`${document.domain}/${document.title}`]),_paq.push(["trackPageView"]),_paq.push(["enableLinkTracking"]),_paq.push(["setTrackerUrl","//piwik.itzbund.de/js/"]),_paq.push(["setSiteId",Number(t)]),e.id="cmsMatomoScript",e.type="text/javascript",e.async=!0,e.defer=!0,e.src="//piwik.itzbund.de/js/",document.head.appendChild(e))}function matomoRejectFunction(){_paq.push(["forgetConsentGiven"])}function setConsent(){document.cookie.match(/matomoTracking=true/u)?matomoConsentFunction():matomoRejectFunction()}setConsent(),$("#cookiebanner").on("afterClose",function(){setConsent()}); 10763 10764 /* Ende tracking */ 10765 /* Start cms_aria */ 10766 /*! --GSBDocStart 10767 * @name: @cms/cms_aria 10768 * @version: 2.0.0 10769 * @description: A toggle mechanism for aria attributes 10770 * --CMSDocEnd 10771*/"use strict"; 10772var cms; 10773cms = cms || {}; 10774(function ($, cms) { 10775 // Entry point into lib, is called by module. 10776 cms.aria = function aria(el, options, params) {// Creates, initializes and returns an instance of a cms_aria Module 10777 var base = Object.create(aria.prototype); // Instance of aria-object is used in. 10778 base.$el = $(el); 10779 base.el = el; 10780 base.moduleName = "cms.aria"; 10781 base.$el.data(base.moduleName, base); 10782 base.options = $.extend({}, cms.aria.defaultOptions, options); 10783 base.init(el, options, params); 10784 return base; 10785 }; 10786 10787 cms.aria.prototype = { 10788 /** 10789 * @method generateID
10790 * @desc generiert eine ID aus einer Zufallszahl und dessen toString result mit der Basis 36 10791 */ 10792 generateID: function () { 10793 // Math.random should be unique because of its seeding algorithm. 10794 // Convert it to base 36 (numbers + letters), and grab the first 9 characters 10795 // after the decimal. 10796 return '_' + Math.random().toString(36).substr(2, 9); 10797 }, 10798 10799 // Initializes elements with starting values. 10800 setInitialValues: function () { 10801 var base = this; 10802 10803 // Closes every Element in "Types" as default init. 10804 Object.keys(base.types).forEach(function (typeName) { 10805 var type = this[typeName]; 10806 base.applyToggle(type, typeName, 1); 10807 type.prop('cms_aria_index', function (index) {return index;}); 10808 }, base.types); 10809 10810 // Applies Initializing Functions, Values as defined in Module "Aria-Initialize-Object" to elements. 10811 base.initial.forEach(function (statement) { 10812 var typeName = statement._type, 10813 type = base.types[typeName]; 10814 Object.keys(statement).forEach(function (attrName) { 10815 var attrValue = statement[attrName]; 10816 if (attrName === "_type") { 10817 10818 //ignore 10819 } else if (attrName === "class") { 10820 //ignore 10821 } else if (typeof attrValue === "function") {type.each(function (i, el) { 10822 $(el).attr(attrName, attrValue.call(base, base, i, attrName)); // <- If Initialize contains Function on Key, it is called 10823 }); // and it's return value assigned to element. (HTML-Tag) 10824 } else { 10825 type.attr(attrName, attrValue); // <- Value assigned to element. 10826 } 10827 }); 10828 }); 10829 }, 10830 10831 // Sets the Options to the values given by Module. 10832 init: function (_, __, params) {// Gets "Types" (Class Names), "Initials" (Initial Values) and "Toggles" (Values for 'open' and 'close) 10833 this.types = params.types; 10834 this.initial = params.initial; 10835 this.toggles = params.toggles; 10836 this.setInitialValues(); 10837 }, 10838 10839 // Gets the by the current toggle value of an element and returns those as object of attributes. 10840 getToggleValues: function (object, index) { 10841 var values = {}; 10842 Object.keys(object || {}).forEach(function (key) { 10843 if (key !== "class" && key !== "style") { 10844 values[key] = object[key][index]; 10845 } 10846 }); 10847 return values; 10848 }, 10849 10850 // Applies the toggle changes defined by the module it is used by. 10851 applyToggle: function ($elements, typeName, index) { 10852 var base = this, 10853 toggles = base.toggles[typeName] || {}, 10854 classes = toggles["class"] || []; 10855 $elements.attr(base.getToggleValues(toggles, index)); // <- Gets toggle values defined by the cms_module it is used by and applies them to current element 10856 $elements.removeClass(classes[index === 0 ? 1 : 0]); // <- Specifically deals with class changes of html elements.
10857 $elements.addClass(classes[index]); // Which are treated different than other HTML-Tag properties. 10858 }, 10859 10860 // Is called when the aria status of an element should be changed/updated. 10861 updateAria: function (elem, open, singleOpen) { 10862 var base = this, 10863 index = elem['cms_aria_index']; 10864 if (!open || singleOpen) { 10865 Object.keys(base.types).forEach(function (typeName) { 10866 var type = base.types[typeName]; 10867 base.applyToggle($(type[index]), typeName, open ? 0 : 1); 10868 }); 10869 } else { 10870 Object.keys(base.types).forEach(function (typeName) { 10871 var type = base.types[typeName]; 10872 $(type).each(function (idx) { 10873 if (index === idx) { 10874 // Toggles Element that should be opened to open, in regard to aria toggle 10875 base.applyToggle($(type[idx]), typeName, 0); 10876 } else { 10877 // Toggles Element that should be closed to closed, in regard to aria toggle 10878 base.applyToggle($(type[idx]), typeName, 1); 10879 } 10880 }); 10881 }); 10882 } 10883 } 10884 }; 10885 10886 cms.aria.defaultOptions = { 10887 10888 //options 10889 };})(jQuery, cms); 10890 10891 /* Ende cms_aria */ 10892 /* Start cms_makeCMSModule */ 10893 /*! --GSBDocStart 10894 * @name: @cms/cms_makeCMSModule 10895 * @version: 3.0.1 10896 * @description: JS-Modul-Factory 10897 * --CMSDocEnd 10898*/"use strict"; 10899var cms; 10900cms = cms || {}; 10901(function ($, cms) { 10902 10903 /* @example 10904 * function module(){} 10905 * var $; 10906 * set($, ['cms', 'foo', 'bar'], module); 10907 * $.cms && $.cms.foo && $.cms.foo.bar === module //true 10908 */ 10909 function set(object, namespace, value) {// Build name space recursively and adds the "module(el, userOptions, ...additionalParameters)" 10910 var i,l = namespace.length - 1, // function to last ID of given namespace. Skips existing IDs, adds empty object for none existing. 10911 property,last = namespace[l]; 10912 for (i = 0; i < l; i++) { 10913 property = namespace[i]; 10914 object[property] = object[property] || {}; 10915 object = object[property]; 10916 } 10917 object[last] = value; 10918 } 10919 /* @example 10920 * var $ = { 10921 * cms: { 10922 * foo: { 10923 * bar: function(x){ 10924 * return x; 10925 * } 10926 * } 10927 * } 10928 * }; 10929 * apply($, ['cms', 'foo', 'bar'], ['baz']) === 'baz' //true 10930 */ 10931 function apply(object, namespace, args) {// Descents recursively through namespace and calls last ID if it contains a function. 10932 var i,l = namespace.length - 1, // Should be "module(el, userOptions, ...additionalParameters)" function. 10933 property,last = namespace[l]; 10934 for (i = 0; i < l; i++) { 10935 property = namespace[i]; 10936 object = object && object[property]; 10937 } 10938 if (typeof object[last] === "function") { 10939 object[last].apply(object, args); 10940 } 10941 } 10942 10943 // Adds meta properties to the module template. Currently: eventName and moduleName as identifier. 10944 function enhance(fullName, namespace, template) {//returns an "enhanced" copy of a template 10945 return $.extend(true, { 10946 eventName: namespace.slice().reverse().join('.'), 10947 moduleName: fullName, 10948 generateID: function () { 10949 // Math.random should be unique because of its seeding algorithm. 10950 // Convert it to base 36 (numbers + letters), and grab the first 9 characters 10951 // after the decimal. 10952 return '_' + Math.random().toString(36).substr(2, 9); 10953 }, 10954 sharedBetweenInstances: { 10955 instanceCount: 0 10956 } 10957 }, template); 10958 } 10959 10960 // Is called in each Module respectively. Registers the Modules build process to the jQuery Prototype. Adds a shortcut to execute 10961 // initialization of module to a list jQuery objects. 10962 cms.makeCMSModule = function makeCMSModule(fullName, template) { 10963 var namespace = fullName.split('.'); 10964 10965 // A function to initialize an instance of a module inside a jQuery object. 10966 function module(el, userOptions, ...additionalParameters) { 10967 var base = $.extend({}, template); 10968 base.el = el; 10969 base.$el = $(el); 10970 base.options = $.extend(true, {}, template.defaultOptions, userOptions); 10971 base.$el.data(namespace.join('.'), base); 10972 base.sharedBetweenInstances.instanceCount++; 10973 base.instanceNamespace = '.instance' + base.sharedBetweenInstances.instanceCount + '.' + base.eventName; 10974 base.init(el, userOptions, ...additionalParameters); 10975 } 10976 10977 template = enhance(fullName, namespace, template); 10978 10979 module.defaultOptions = template.defaultOptions || {}; 10980 10981 set($, namespace, module); 10982 10983 // Applies the apply function to every jQuery-Element in a list if that element doesn't contain a module already or the given module 10984 // has the option "force" set to true.
10985 // Is called in init by "snake_cased" module name. $('.my-selector').cms_my_module. 10986 $.fn[namespace.join('_')] = function (userOptions, ...additionalParameters) { 10987 $(this).each(function (i, el) { 10988 if (!$(el).data(namespace.join('.')) || userOptions && userOptions.force) {//Is not occupied or is force true? 10989 apply($, namespace, [el, userOptions, ...additionalParameters]); 10990 } 10991 }); 10992 return this; 10993 }; 10994 }; 10995})(jQuery, cms); 10996 10997 /* Ende cms_makeCMSModule */ 10998 /* Start cms_requireCMSComponent */ 10999 /*! --GSBDocStart 11000 * @name: @cms/cms_requireCMSComponent 11001 * @version: 3.0.0 11002 * @description: Lib um Javascript-Ressourcen als Bündel nachzuladen wenn diese gebraucht werden. Zielsetzung: Verringerung von Ladezeiten 11003 * --CMSDocEnd 11004*/"use strict"; 11005var cms; 11006cms = cms || {}; 11007(function ($, cms) { 11008 const state = { 11009 instanceCount: 0, 11010 promises: {} 11011 }; 11012 11013 function requireGenericCMSComponent(componentName, instanceName) { 11014 const promiseArray = createScriptTags(cms.jsComponents.definitions[componentName].scriptList, instanceName); 11015 return Promise.all(promiseArray); 11016 } 11017 11018 function createScriptTags(scriptList, instanceName) { 11019 const promiseArray = []; 11020 scriptList.forEach((scriptPath) => { 11021 promiseArray.push(createScriptTag(scriptPath)); 11022 }); 11023 return promiseArray; 11024 } 11025 11026 /** 11027 * Creates a Script Tag, appends and executes it. 11028 * While creating a new Promise or waiting for a previou Promise the Script has already been requested. 11029 * 11030 * @param scriptPath the Path of the script used for the src Attribute 11031 * @param instanceName the name of this instance used for logging 11032 * @returns {Promise<unknown>} a promise that ensures that the Script is ready to use when resolved 11033 */ 11034 function createScriptTag(scriptPath, instanceName) { 11035 let promise; 11036 if (state.promises[scriptPath]) { 11037 promise = state.promises[scriptPath]; 11038 } else { 11039 promise = new Promise(function (resolve, reject) { 11040 const $script = $('<script></script>').attr('src', scriptPath).attr('charSet', 'UTF-8'); 11041 $script. 11042 prop('async', false). 11043 on('load', function () { 11044 resolve({ scriptPath, action: 'DOM load' }); 11045 }); 11046 document.body.appendChild($script[0]); 11047 11048 }); 11049 state.promises[scriptPath] = promise; 11050 } 11051 return promise; 11052 } 11053 11054 cms.requireCMSComponent = function (componentName, $el) { 11055 const instanceName = 'cms.requireCMSComponent-' + state.instanceCount++; 11056 const deferred = $.Deferred(); 11057 let error; 11058 11059 if (cms.jsComponents.definitions[componentName]) { 11060 if (!$el || !$el.length) { 11061 error = new Error('Elemente nicht im DOM gefunden. CMS-Komponente wird nicht geladen'); 11062 deferred.reject(error); 11063 } else { 11064 requireGenericCMSComponent(componentName, instanceName). 11065 then(() => deferred.resolve($el)). 11066 catch((err) => { 11067 deferred.reject(err); 11068 console.error(instanceName, `CMS-Komponente ${componentName} für Elemente`, $el, 11069 'konnte nicht eingebunden werden, es gab folgenden Fehler', err); 11070 }); 11071 } 11072 } else { 11073 console.error(instanceName, `CMS-Komponente ${componentName} ist nicht definiert, und kann daher nicht eingebunden werden`); 11074 } 11075 11076 return deferred; 11077 }; 11078 11079})(jQuery, cms); 11080 11081 /* Ende cms_requireCMSComponent */ 11082 /* Start cms_responsiveListener */ 11083 /*! --GSBDocStart 11084 * @name: @cms/cms_responsive_listener 11085 * @version: 3.1.0 11086 * @description: Diese Bibliothek wird zur Unterstützung von responsiven Breakpoints in GSB Modulen verwendet. 11087 * --CMSDocEnd 11088*/"use strict"; 11089(function ($) { 11090 if (!$.cms) { 11091 $.cms = {}; 11092 } 11093 11094 11095 $.cms.responsiveListener = function (pluginBase) { 11096 var base = this; 11097 this.base = base; 11098 this.pluginBase = pluginBase; 11099 11100 // Add a reverse reference to the DOM object 11101 this.base.breakpoints = []; 11102 this.base.breakpointSettings = []; 11103 this.base.activeBreakpoint = null; 11104 this.base.windowWidth = 0; 11105 11106 base.init = function () { 11107 //Da die Lib keine eigenen Options hat, Options vom Plugin holen 11108 base.options = pluginBase.options; 11109 base.originalOptions = base.options; 11110 this.base.options = base.options; 11111 this.base.originalOptions = base.originalOptions; 11112 base.initResponsive(); 11113 base.checkResponsive(); 11114 base.initEvents(); 11115 }; 11116 11117 11118 /** 11119 * Initialisiert die Events. 11120 */ 11121 $.cms.responsiveListener.prototype.initEvents = function () { 11122 var $window = $(window), 11123 onResize = function () { 11124 if ($(window).width() !== base.windowWidth) { 11125 clearTimeout(base.windowDelay); 11126 base.windowDelay = window.setTimeout(function () { 11127 base.windowWidth = $(window).width(); 11128 base.checkResponsive(); 11129 }, 100); 11130 } 11131 }; 11132 $window.on('resize', onResize); 11133 $window.on('orientationchange', function () { 11134 base.checkResponsive(); 11135 }); 11136 }; 11137 11138 // Run initializer 11139 base.init(); 11140 }; 11141 11142 11143 /** 11144 * Initialisiert die Datenstrukturen fuer die responsiven Ueberpruefungen. 11145 */ 11146 $.cms.responsiveListener.prototype.initResponsive = function () { 11147 var breakpoint, 11148 responsiveSettings = this.base.options.responsive || null; 11149 11150 if (responsiveSettings && responsiveSettings.length > -1) { 11151 for (breakpoint in responsiveSettings) { 11152 if (responsiveSettings.hasOwnProperty(breakpoint)) { 11153 if (typeof responsiveSettings[breakpoint].breakpoint === 'string') { 11154 const emBreakPoint = parseInt(responsiveSettings[breakpoint].breakpoint) * (parseInt(window.getComputedStyle($('html')[0], null).getPropertyValue('font-size')) / 0.625); 11155 this.base.breakpoints.push(emBreakPoint); 11156 // Save with pixelValue as propertyname and not the original em-string. 11157 // Computed Properties are used to identify the breakpointSettings for the targetBreakp
11157oint, which is used as the propertyname and is always in Pixel. 11158 this.base.breakpointSettings[emBreakPoint] = responsiveSettings[breakpoint]; 11159 } else { 11160 this.base.breakpoints.push(responsiveSettings[breakpoint].breakpoint); 11161 this.base.breakpointSettings[responsiveSettings[breakpoint].breakpoint] = responsiveSettings[breakpoint]; 11162 } 11163 } 11164 } 11165 this.base.breakpoints.sort(function (a, b) { 11166 return b - a; 11167 }); 11168 } 11169 }; 11170 11171 11172 /** 11173 * Ueberprueft, ob eine Aenderung der Einstellungen durchgefuehrt werden muss. Dies ist dann der Fall, wenn 11174 * sich die Breite des Viewports(window-Objekt) geaendert hat und mindestens einen der angegebenen Breakpoints 11175 * unterschreitet. Ausschlaggebend fuer die Aenderungen ist der letzte konfigurierte Breakpoint, dessen Breite 11176 * unterschritten wird. 11177 * 11178 */ 11179 $.cms.responsiveListener.prototype.checkResponsive = function () { 11180 var breakpoint, 11181 targetBreakpoint, 11182 respondToWidth = $(window).width(); 11183 11184 // Case: "responsive : [{...},{...}]" value of the given options is not empty. 11185 if (this.base.originalOptions.responsive && 11186 this.base.originalOptions.responsive.length > -1 && 11187 this.base.originalOptions.responsive !== null) { 11188 11189 targetBreakpoint = null; 11190 11191 // Resets the options to original if the window width is greater than the greatest breakpoint. 11192 if (this.base.activeBreakpoint !== null && respondToWidth >= this.base.breakpoints[0]) { 11193 this.base.activeBreakpoint = null; 11194 this.pluginBase.options = this.base.originalOptions; 11195 } 11196 11197 // Looks for the first breakpoint value greater than the screen width. 11198 for (breakpoint in this.base.breakpoints) { 11199 if (this.base.breakpoints.hasOwnProperty(breakpoint)) { 11200 if (respondToWidth < this.base.breakpoints[breakpoint]) { 11201 targetBreakpoint = this.base.breakpoints[breakpoint]; 11202 this.base.highestResolution = false; 11203 } 11204 } 11205 } 11206 11207 // In case no breakpoint value is larger than the current window width, terminate. 11208 if (this.base.highestResolution) { 11209 return; 11210 } 11211 11212 if (targetBreakpoint !== null) { 11213 if (this.base.activeBreakpoint !== null) {// Case: targetBreakpoint was found and a breakpoint is already active. 11214 if (targetBreakpoint !== this.base.activeBreakpoint) {// Merges breakpoint specific options and plugin options to the options that should currently apply. 11215 this.base.activeBreakpoint = targetBreakpoint; 11216 this.pluginBase.options = $.extend({}, 11217 this.base.originalOptions, 11218 this.base.breakpointSettings[targetBreakpoint]); 11219 this.base.triggerRefresh(); 11220 } 11221 } else {// Case: targetBreakpoint was found and no breakpoint is active 11222 this.base.activeBreakpoint = targetBreakpoint; 11223 this.pluginBase.options = $.extend({}, 11224 this.base.originalOptions, 11225 this.base.breakpointSettings[targetBreakpoint]); 11226 this.base.triggerRefresh(); 11227 } 11228 } else { 11229 if (this.base.activeBreakpoint !== null) {// Case: targetBreakpoint was NOT found but a breakpoint is active 11230 this.base.activeBreakpoint = null; 11231 this.base.options = this.base.originalOptions; 11232 this.base.triggerRefresh(); 11233 } else {// Case: targetBreakpoint was NOT found and no breakpoint is active 11234 this.base.highestResolution = true; 11235 this.base.triggerRefresh(); 11236 } 11237 } 11238 } else if (this.base.originalOptions.onRefresh && 11239 this.base.originalOptions.onRefresh.length > -1 && 11240 this.base.originalOptions.onRefresh !== null) {// Case: Only base options but not the "responsive: [{...},{...}]" Array filled. 11241 if (this.base.highestResolution) { 11242 return; 11243 } 11244 this.base.triggerRefresh(); 11245 this.base.highestResolution = true; 11246 } 11247 }; 11248 11249 11250 /** 11251 * Loest die Aktualisierung des Scripts aus. 11252 */ 11253 $.cms.responsiveListener.prototype.triggerRefresh = function () { 11254 if (typeof this.pluginBase.options.onRefresh === 'function') { 11255 this.pluginBase.options.onRefresh.call(this.pluginBase); 11256 } 11257 }; 11258 11259 $.fn.cms_responsiveListener = function (pluginBase) { 11260 return this.each(function () { 11261 new $.cms.responsiveListener(pluginBase); 11262 }); 11263 }; 11264})(jQuery); 11265 11266 /* Ende cms_responsiveListener */ 11267 /* Start cms_checkDependencies */ 11268 /*! --GSBDocStart 11269 * @name: @gsb/gsb_check_dependencies 11270 * @version: 1.0.1 11271 * @description: Lib to execute code that depends on other internal modules - only if that module has already been loaded 11272 * --GSBDocEnd 11273*/"use strict"; 11274var gsb; 11275gsb = gsb || {}; 11276//uses gsb.warn and gsb.error 11277//needs to be loaded AFTER jquery 11278(function ($) { 11279 "use strict"; 11280 function checkDependencies(dependencyNames, callback) { 11281 var allOK = true;
11282 dependencyNames.forEach(function (name) { 11283 var propertyName, 11284 dependency, 11285 warning; 11286 //future-proofing: initially, we will only support GSB Modules 11287 if (/^gsb\./.test(name)) { 11288 propertyName = String(name).replace(/\./g, '_'); 11289 dependency = $.fn[propertyName]; 11290 warning = "Callback dependent on module '" + name + "' detected, but module could not be found."; 11291 } 11292 if (dependency === undefined || dependency === null) { 11293 allOK = false; 11294 if (warning && (typeof gsb_logDependenciesWarning !== 'undefined' ? gsb_logDependenciesWarning : true)) { 11295 gsb.warn(warning); 11296 } else if (!warning) { 11297 gsb.error("Callback dependent on module '" + name + "' detected, but the module's type could not be determined from its name."); 11298 } 11299 } 11300 }); 11301 if (allOK) { 11302 /* future-proofing: callback 'arguments' and 'this' may be specified whenever 11303 * we decide on a concept that can handle modules which are 11304 * not jQuery-plugins (and ideally, one that can handle both) 11305 */ 11306 callback.call(null); 11307 } 11308 } 11309 11310 gsb.checkDependencies = checkDependencies; 11311})(jQuery); 11312 11313 /* Ende cms_checkDependencies */ 11314 /* Start js.cookie */ 11315 "use strict"; /*! js-cookie v3.0.5 | MIT */ 11316; 11317(function (global, factory) { 11318 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 11319 typeof define === 'function' && define.amd ? define(factory) : ( 11320 global = typeof globalThis !== 'undefined' ? globalThis : global || self, function () { 11321 var current = global.Cookies; 11322 var exports = global.Cookies = factory(); 11323 exports.noConflict = function () {global.Cookies = current;return exports;}; 11324 }()); 11325})(void 0, function () {'use strict'; 11326 11327 /* eslint-disable no-var */ 11328 function assign(target) { 11329 for (var i = 1; i < arguments.length; i++) { 11330 var source = arguments[i]; 11331 for (var key in source) { 11332 target[key] = source[key]; 11333 } 11334 } 11335 return target; 11336 } 11337 /* eslint-enable no-var */ 11338 11339 /* eslint-disable no-var */ 11340 var defaultConverter = { 11341 read: function (value) { 11342 if (value[0] === '"') { 11343 value = value.slice(1, -1); 11344 } 11345 return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent); 11346 }, 11347 write: function (value) { 11348 return encodeURIComponent(value).replace( 11349 /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, 11350 decodeURIComponent 11351 ); 11352 } 11353 }; 11354 /* eslint-enable no-var */ 11355 11356 /* eslint-disable no-var */ 11357 11358 function init(converter, defaultAttributes) { 11359 function set(name, value, attributes) { 11360 if (typeof document === 'undefined') { 11361 return; 11362 } 11363 11364 attributes = assign({}, defaultAttributes, attributes); 11365 11366 if (typeof attributes.expires === 'number') { 11367 attributes.expires = new Date(Date.now() + attributes.expires * 864e5); 11368 } 11369 if (attributes.expires) { 11370 attributes.expires = attributes.expires.toUTCString(); 11371 } 11372 11373 name = encodeURIComponent(name). 11374 replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent). 11375 replace(/[()]/g, escape); 11376 11377 var stringifiedAttributes = ''; 11378 for (var attributeName in attributes) { 11379 if (!attributes[attributeName]) { 11380 continue; 11381 } 11382 11383 stringifiedAttributes += '; ' + attributeName; 11384 11385 if (attributes[attributeName] === true) { 11386 continue; 11387 } 11388 11389 // Considers RFC 6265 section 5.2: 11390 // ... 11391 // 3. If the remaining unparsed-attributes contains a %x3B (";") 11392 // character: 11393 // Consume the characters of the unparsed-attributes up to, 11394 // not including, the first %x3B (";") character. 11395 // ... 11396 stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]; 11397 } 11398 11399 return document.cookie = 11400 name + '=' + converter.write(value, name) + stringifiedAttributes; 11401 } 11402 11403 function get(name) { 11404 if (typeof document === 'undefined' || arguments.length && !name) { 11405 return; 11406 } 11407 11408 // To prevent the for loop in the first place assign an empty array 11409 // in case there are no cookies at all. 11410 var cookies = document.cookie ? document.cookie.split('; ') : []; 11411 var jar = {}; 11412 for (var i = 0; i < cookies.length; i++) { 11413 var parts = cookies[i].split('='); 11414 var value = parts.slice(1).join('='); 11415 11416 try { 11417 var found = decodeURIComponent(parts[0]); 11418 jar[found] = converter.read(value, found); 11419
11420 if (name === found) { 11421 break; 11422 } 11423 } catch (e) {} 11424 } 11425 11426 return name ? jar[name] : jar; 11427 } 11428 11429 return Object.create( 11430 { 11431 set, 11432 get, 11433 remove: function (name, attributes) { 11434 set( 11435 name, 11436 '', 11437 assign({}, attributes, { 11438 expires: -1 11439 }) 11440 ); 11441 }, 11442 withAttributes: function (attributes) { 11443 return init(this.converter, assign({}, this.attributes, attributes)); 11444 }, 11445 withConverter: function (converter) { 11446 return init(assign({}, this.converter, converter), this.attributes); 11447 } 11448 }, 11449 { 11450 attributes: { value: Object.freeze(defaultAttributes) }, 11451 converter: { value: Object.freeze(converter) } 11452 } 11453 ); 11454 } 11455 11456 var api = init(defaultConverter, { path: '/' }); 11457 /* eslint-enable no-var */ 11458 11459 return api; 11460 11461}); 11462 11463 /* Ende js.cookie */ 11464(function cmsJavaScriptModules(){ //prevents "use strict" statement from "leaking" 11465 /* Start cms_autosuggest */ 11466 /*! --GSBDocStart 11467 * @name: @cms/cms_autosuggest 11468 * @version: 6.0.0 11469 * @description: Module for accessible autocompletion in search forms 11470 * --CMSDocEnd 11471*/"use strict"; 11472cms.makeCMSModule("cms.autosuggest", { 11473 init: function (el, options, actionUrl) { 11474 const base = this; 11475 11476 // BoxCounter 11477 base.boxNumber = ++base.allInstances.boxCount; 11478 // Such-Textfeld 11479 const selectors = base.options.selectors; 11480 base.$input = base.$el.find(selectors.input).first(); 11481 base.$submit = base.$el.find(selectors.submit).first(); 11482 if (base.$submit.length === 0) { 11483 base.$submit = base.$el.find('input[type=image]:first'); 11484 } 11485 // Aktuelle Anfrage 11486 base.reqQuery = false; 11487 // Anfragen Cachen 11488 base.queries = []; 11489 // Aktuelle Position 11490 base.activeIndex = NaN; 11491 11492 if (base.options.mode === "fetch") { 11493 // eslint-disable-next-line no-param-reassign -- Kompatibilität mit alten Aufruf beihalten 11494 actionUrl = base.$el.attr('data-autosuggest-form') || actionUrl; 11495 11496 if (!actionUrl) { 11497 throw new Error("Das Attribut data-autosuggest-form muss auf dem Basis-Element gesetzt werden"); 11498 } 11499 11500 base.actionUrl = actionUrl; 11501 } else if (base.options.mode === "datalist") { 11502 const optionListId = base.$input.attr('list'); 11503 if (!optionListId) { 11504 throw new Error("Das Attribut list muss auf dem Input-Element gesetzt werden"); 11505 } 11506 const optionList = optionListId ? base.$el.find(`#${optionListId}`) : $(); 11507 if (optionListId && optionList.length < 1) { 11508 throw new Error("Das Datalist-Element mit der ID " + optionListId + " existiert nicht"); 11509 } 11510 const categoryListId = optionList.attr('data-type-label-list-id'); 11511 const categoryList = categoryListId ? base.$el.find(`#${categoryListId}`) : $(); 11512 if (categoryListId && categoryList.length < 1) { 11513 throw new Error("Das Datalist-Element mit der ID " + categoryListId + " existiert nicht"); 11514 } 11515 base.$input.removeAttr('list'); 11516 11517 base.dataList = [].reduce.call(optionList.find('option'), (data, opt) => { 11518 const optText = opt.innerText; 11519 const category = opt.getAttribute('data-type-label'); 11520 const pairs = data[category] || []; 11521 data[category] = pairs.concat([{ 11522 name: optText, 11523 value: opt.value 11524 }]).sort((a, b) => a.name - b.name); 11525 11526 return data; 11527 }, {}); 11528 11529 base.options.typeLabels = [].reduce.call(categoryList.find('option'), (labels, opt) => { 11530 labels[opt.value] = opt.innerText; 11531 return labels; 11532 }, {}); 11533 } 11534 11535 // AutoSuggest-Box vorbereiten und positionieren 11536 if (base.options.markup.box) { 11537 base.$box = $(base.options.markup.box). 11538 insertAfter(base.$input); 11539 const description = base.$el.attr('data-autosuggest-box-description'); 11540 if (typeof description !== "undefined") { 11541 const descId = base.generateID(); 11542 $("<span></span>"). 11543 text(description). 11544 addClass(base.options.classes.description). 11545 attr({ 11546 id: descId, 11547 hidden: 'hidden' 11548 }). 11549 insertAfter(base.$input);
11550 base.$box.attr('aria-describedby', descId); 11551 } else { 11552 throw new Error("Attribut data-autosuggest-box-description muss auf dem Basis-Element gesetzt werden"); 11553 } 11554 } else if (base.options.selectors.box) { 11555 base.$box = base.$el.find(base.options.selectors.box); 11556 } 11557 base.$box. 11558 attr({ 11559 id: base.$box.attr("id") || `searchAutoSuggestBox${base.boxNumber}`, 11560 hidden: 'hidden' 11561 }); 11562 11563 // Browser-Auto-Vervollständigung deaktivieren 11564 base.$input.attr('autocomplete', 'off'); 11565 11566 base.makeAccessible(); 11567 base.bindEvents(); 11568 }, 11569 allInstances: { 11570 boxCount: 0 11571 }, 11572 makeAccessible: function () { 11573 const base = this; 11574 11575 base.$input.attr({ 11576 'role': base.$input.attr('role') || 'combobox', 11577 'aria-haspopup': 'listbox', 11578 'aria-owns': base.$box.attr('id'), 11579 'aria-expanded': 'false', 11580 'aria-autocomplete': 'list', 11581 'aria-activedescendant': null, 11582 'aria-controls': base.$box.attr('id') 11583 }); 11584 11585 base.$labels = $(base.$input.prop('labels')).each(function () { 11586 const $label = $(this); 11587 $label.attr('id', $label.attr('id') || base.generateID()); 11588 }); 11589 const labelList = base.$labels.toArray().map(function (label) { 11590 return $(label).attr('id'); 11591 }).join(' '); 11592 11593 base.$box.attr({ 11594 role: base.$box.attr('role') || 'listbox', 11595 'aria-labelledby': labelList || null 11596 }); 11597 }, 11598 bindEvents: function () { 11599 const base = this; 11600 11601 // Tastaturbefehle abfangen 11602 base.$input.on('keydown', base, base.onKeyDown); 11603 11604 // Bubbling von Mousedown-Event verhindern (Kompatibilität mit cms_simple_toggle) 11605 base.$input.on('mousedown', (ev) => ev.stopPropagation()); 11606 11607 // Bei Eingabe von mehr als zwei Zeichen Liste abrufen 11608 base.$input.on('keyup', base, base.onKeyUp); 11609 11610 base.$el.on(`close.${base.eventName}`, base, function (ev) { 11611 ev.stopPropagation(); 11612 ev.data.showSuggestionBox(false); 11613 }); 11614 base.$el.on(`open.${base.eventName}`, base, function (ev) { 11615 ev.stopPropagation(); 11616 ev.data.showSuggestionBox(true); 11617 }); 11618 11619 base.$el. 11620 on(`notEnoughCharacters.${base.eventName} noResults.${base.eventName}`, base, function (ev) { 11621 ev.stopPropagation(); 11622 ev.data.$el.trigger(`close.${base.eventName}`, base); 11623 }). 11624 on(`showResults.${base.eventName}`, base, function (ev) { 11625 ev.stopPropagation(); 11626 ev.data.$el.trigger(`open.${base.eventName}`, base); 11627 }); 11628 base.$el.on(`focusout.${base.eventName}`, base, function (ev) { 11629 ev.data.$el.trigger(`close.${base.eventName}`, base); 11630 }); 11631 base.$box.on('mousedown', function (ev) { 11632 ev.stopPropagation(); 11633 ev.preventDefault(); 11634 }); 11635 if (base.options.mode === "datalist" && base.options.datalist.openOnFocus) { 11636 base.$el.on(`focusin.${base.eventName}`, base, function (ev) { 11637 ev.data.$input.trigger('keyup', base); 11638 ev.data.$el.trigger(`showResults.${base.eventName}`, base); 11639 }); 11640 } 11641 }, 11642 onKeyDown: function (ev) { 11643 const base = ev.data; 11644 let trigger = false, 11645 activeOpt, 11646 link; 11647 switch (ev.key) { 11648 case "Enter": 11649 trigger = true; 11650 break; 11651 case "Down": // IE/Edge 11652 case "ArrowDown": 11653 ev.preventDefault(); 11654 base.selectNextSuggestion(); 11655 break; 11656 case "Up": // IE/Edge 11657 case "ArrowUp": 11658 ev.preventDefault(); 11659 base.selectPrevSuggestion(); 11660 break; 11661 case "Esc": // IE/Edge 11662 case "Escape": 11663 if (!base.$box.is('[hidden]')) { 11664 base.showSuggestionBox(false); 11665 ev.stopPropagation(); 11666 } 11667 break; 11668 default:break; 11669 } 11670 if (trigger) { 11671 activeOpt = base.$box.find('[role=option]').eq(base.activeIndex); 11672 if (activeOpt && activeOpt.length > 0) { 11673 base.$input.val(activeOpt.first().attr('data-input')); 11674 } 11675 if (base.options.submitOnSelect) { 11676 if (activeOpt.is(`.${base.options.classes.hasLink}`)) { 11677 ev.preventDefault(); //prevent form submission 11678 //jQuery does not call the native .click() on <a> elements 11679 link = activeOpt.find('a')[0]; 11680 if (link && typeof link.click === "function") { 11681 link.click(); 11682 } 11683 } else { 11684 base.triggerSubmit(activeOpt); 11685 } 11686 } else if (activeOpt.length > 0) { 11687 ev.preventDefault(); 11688 } 11689 ev.data.$el.trigger(`close.${base.eventName}`, base); 11690 } 11691 }, 11692 onKeyUp: function (ev) { 11693 const base = ev.data; 11694 let go = true; 11695 switch (ev.key) { 11696 case "Enter": 11697 return; 11698 case "Esc": // IE/Edge 11699 case "Escape": 11700 return; 11701 case "Down": // IE/Edge 11702 case "ArrowDown": 11703 case "Up": // IE/Edge 11704 case "ArrowUp": 11705 go = !base.$box.is(':visible'); 11706 break; 11707 default:break; 11708 } 11709 11710 if (go) { 11711 if (base.options.mode === "datalist") { 11712 if (base.$input.val().length >= base.options.minInputLength || base.options.datalist.openOnFocus) { 11713 base.filterListData(base.$input.val()); 11714 } else { 11715 base.$el.trigger(`notEnoughCharacters.${base.eventName}`, base); 11716 } 11717 } else if (base.options.mode === "fetch") { 11718 if (base.$input.val().length >= base.options.minInputLength) { 11719 base.query(base.$input.val()); 11720 } else { 11721 base.$el.trigger(`notEnoughCharacters.${base.eventName}`, base); 11722 } 11723 } 11724 } 11725 }, 11726 filterListData: function (value) { 11727 const base = this, 11728 queryResult = {}; 11729 11730 if (typeof value === "string") { 11731 Object.entries(base.dataList).forEach(([key, pairs]) => { 11732 const matchingPairs = pairs.filter((pair) => base.options.datalist.filter(pair, value)); 11733 if (matchingPairs.length) { 11734 queryResult[key] = matchingPairs; 11735 } 11736 }); 11737 } 11738 11739 base.showSuggestions(queryResult); 11740 }, 11741 query: function (value) { 11742 const base = this; 11743 base.reqQuery = value; 11744 if (typeof base.queries[base.reqQuery] === "undefined") { 11745 $.ajax({ 11746 url: base.actionUrl, 11747 dataType: 'json', 11748 data: { 11749 'userQuery': value 11750 }, 11751 error: function (jqXHR, textStatus, errorThrown) { 11752 // eslint-disable-next-line no-console -- Explizite Fehlerausgabe 11753 console.error(`AutoSuggest.base.query() > error=AJAX Fehler beim Abruf der JSON-Resource ${base.actionUrl}: ${textStatus} :: ${errorThrown}`); 11754 }, 11755 success: function (data) { 11756 base.queries[value] = data; 11757 if (base.reqQuery === value) { 11758 base.showSuggestions(data); 11759 } 11760 } 11761 }); 11762 } else { 11763 base.showSuggestions(base.queries[base.reqQuery]); 11764 } 11765 }, 11766 showSuggestions: function (data) { 11767 const base = this;
11768 let count = 0; 11769 const createSublist = Boolean(base.options.markup.typedOption); 11770 base.$box.empty(); 11771 Object.keys(data).forEach(function (typeName) { 11772 const typeLabel = base.options.typeLabels[typeName], 11773 typedData = data[typeName] || []; 11774 let optionContainer, 11775 optionLabel, 11776 typedOption, 11777 dummy; 11778 if (typeLabel && typedData.length) { 11779 if (createSublist) { 11780 dummy = $("<div/>"); 11781 typedOption = $(base.options.markup.typedOption).appendTo(dummy); 11782 optionLabel = dummy.find(base.options.selectors.typeLabel). 11783 attr({ 11784 "id": optionLabel ? optionLabel.attr("id") || base.generateID() : base.generateID(), 11785 "data-cms-suggestion-type": typeName 11786 }). 11787 text(typeLabel); 11788 optionContainer = dummy.find(base.options.selectors.typedContainer). 11789 attr({ 11790 'aria-labelledby': optionLabel.attr('id') || null, 11791 'data-cms-suggestion-type': typeName 11792 }); 11793 11794 typedOption.appendTo(base.$box); 11795 } else { 11796 optionContainer = base.$el.find(base.options.selectors.typedContainer). 11797 filter(`[data-cms-suggestion-type="${typeName}"]`); 11798 if (data[typeName].length) { 11799 optionContainer.empty(); 11800 } 11801 } 11802 } 11803 if (!optionContainer || !optionContainer.length) { 11804 optionContainer = base.$box; 11805 } 11806 data[typeName].forEach(function (suggestion, index) { 11807 let option; 11808 if (suggestion) { 11809 count++; 11810 option = $(base.options.markup.option); 11811 option.html(base.options.markup.optionInner.call(base, suggestion, base.reqQuery)); 11812 option.attr({ 11813 "data-input": suggestion.name, 11814 id: option.attr("id") || base.generateID(), 11815 role: "option" 11816 }); 11817 11818 if (suggestion.link) { 11819 option.addClass('has-link'); 11820 option.wrapInner($("<a/>").attr({ 11821 href: suggestion.link, 11822 tabindex: -1 11823 })); 11824 } 11825 option.on('click', base, base.onSuggestionClick); 11826 option.appendTo(optionContainer); 11827 } 11828 }); 11829 }); 11830 if (count > 0) { 11831 base.$el.trigger(`showResults.${base.eventName}`, base); 11832 } else { 11833 base.$el.trigger(`noResults.${base.eventName}`, base); 11834 } 11835 }, 11836 onSuggestionClick: function (ev) { 11837 const base = ev.data, 11838 opt = $(ev.currentTarget); 11839 if (!opt.is(`.${base.options.classes.hasLink}`)) { 11840 ev.preventDefault(); // if old markup is used (not recommended) 11841 base.$input.val(opt.attr('data-input')); 11842 if (base.options.submitOnSelect) { 11843 base.triggerSubmit(opt); 11844 } 11845 base.$el.trigger(`close.${base.eventName}`, base); 11846 } 11847 }, 11848 showSuggestionBox: function (show) { 11849 const base = this; 11850 11851 if (show) { 11852 if (!base.specialTrigger(`beforeShow.${base.eventName}`)) { 11853 return; 11854 } 11855 base.$input.attr("aria-expanded", "true"); 11856 base.$box.add(base.$el.find(base.options.selectors.description)). 11857 attr({ 11858 hidden: null, 11859 'aria-hidden': null 11860 }); 11861 let boxOffsetTop = base.$box.offset().top - $(window).scrollTop(); 11862 base.$box.css({ maxHeight: 'calc(100vh - ' + boxOffsetTop + 'px)', overflow: 'auto' }); 11863 } else { 11864 if (!base.specialTrigger(`beforeHide.${base.eventName}`)) { 11865 return; 11866 } 11867 base.$input.attr("aria-expanded", "false"); 11868 base.$box.add(base.$el.find(base.options.selectors.description)). 11869 attr({ 11870 hidden: 'hidden', 11871 'aria-hidden': null 11872 }); 11873 } 11874 11875 base.activeIndex = NaN; 11876 base.$input.attr("aria-activedescendant", null); 11877 }, 11878 selectNextSuggestion: function () { 11879 const base = this, 11880 n = base.$box.find('[role=option]').length; // the number of suggestions 11881 if (n > 0) { 11882 if (isNaN(base.activeIndex) || base.activeIndex >= n - 1) { 11883 base.activeIndex = 0; 11884 } else if (base.activeIndex < n - 1) { 11885 base.activeIndex++; 11886 } 11887 base.selectSuggestion(); 11888 } 11889 }, 11890 selectPrevSuggestion: function () { 11891 const base = this, 11892 n = base.$box.find('[role=option]').length; 11893 if (n > 0) { 11894 if (isNaN(base.activeIndex) || base.activeIndex <= 0) { 11895 base.activeIndex = n - 1; 11896 } else if (base.activeIndex > 0) { 11897 base.activeIndex--; 11898 } 11899 base.selectSuggestion(); 11900 } 11901 }, 11902 selectSuggestion: function () { 11903 const base = this, 11904 suggestions = base.$box.find('[role=option]'), 11905 activeSuggestion = suggestions.eq(base.activeIndex); 11906 suggestions. 11907 removeClass('active'). 11908 attr('aria-selected', 'false'); 11909 activeSuggestion. 11910 addClass('active'). 11911 attr('aria-selected', 'true'); 11912 base.$input.attr({ 11913 'aria-activedescendant': activeSuggestion.attr('id') 11914 }); 11915 11916 if (!base.isInVisibleSuggestionBox(activeSuggestion)) { 11917 $(activeSuggestion)[0].scrollIntoView({ behavior: 'smooth', block: 'nearest' }); 11918 } 11919 }, 11920 isInVisibleSuggestionBox: function (element) { 11921 const base = this; 11922 let isInVisibleSuggestionBox; 11923 const elementHeight = $(element).outerHeight(); 11924 const elementTop = $(element).offset().top; 11925 const elementBottom = elementTop + elementHeight; 11926 const boxHeight = base.$box.outerHeight(); 11927 const boxTop = base.$box.offset().top; 11928 const boxBottom = boxTop + boxHeight; 11929 if (elementHeight >= boxHeight) { 11930 isInVisibleSuggestionBox = elementBottom - 1 / 2 * elementHeight < boxBottom && elementTop + 1 / 2 * elementHeight > boxTop; 11931 } else { 11932 isInVisibleSuggestionBox = elementBottom < boxBottom && elementTop > boxTop; 11933 } 11934 return isInVisibleSuggestionBox; 11935 }, 11936 triggerSubmit: function (activeSuggestion) { 11937 const base = this; 11938 if (activeSuggestion && activeSuggestion.length > 0) { 11939 if (base.$submit.length > 0) { 11940 base.$submit.click(); 11941 } else { 11942 const form = base.$input.prop('form'); 11943 if (form) { 11944 form.submit(); 11945 } 11946 } 11947 } 11948 }, 11949 // triggers event on base.$el 11950 // returns false if event is cancelled
11951 specialTrigger: function (evStr, ev) { 11952 const base = this; 11953 let namespaces = evStr.split('.'); 11954 const type = namespaces.shift(); 11955 namespaces = namespaces.sort(); 11956 // eslint-disable-next-line new-cap -- Event ist Teil von jQuery 11957 const event = $.Event(type, { 11958 namespace: namespaces.join('.'), 11959 relatedEvent: ev || null 11960 }); 11961 base.$el.trigger(event, base); 11962 return !event.isDefaultPrevented(); 11963 }, 11964 defaultOptions: { 11965 mode: "fetch", 11966 datalist: { 11967 filter: function (pair, value) { 11968 const lcValue = value.toLowerCase(); 11969 return typeof pair.value === "string" && pair.value.toLowerCase().indexOf(lcValue) !== -1; 11970 }, 11971 openOnFocus: false 11972 }, 11973 minInputLength: 2, 11974 submitOnSelect: true, 11975 typeLabels: {}, 11976 selectors: { 11977 box: null, 11978 description: '.js-autosuggest-description', 11979 input: "input[type=text], input[type=search]", 11980 submit: "input[type=submit], button[type=submit]", 11981 typeLabel: ".c-autosuggest__headline", 11982 typedContainer: ".c-autosuggest__sublist" 11983 }, 11984 markup: { 11985 box: "<ul class='c-autosuggest__list'></ul>", 11986 option: "<li class='c-autosuggest__item'></li>", 11987 optionInner: function (suggestion) { 11988 return suggestion.name; 11989 }, 11990 typedOption: 11991 "<li class='c-autosuggest__item'><h3 class='c-autosuggest__headline'></h3><ul class='c-autosuggest__sublist'></ul></li>" 11992 }, 11993 classes: { 11994 description: 'c-autosuggest__description js-autosuggest-description', 11995 hasLink: 'has-link' 11996 } 11997 } 11998}); 11999 12000 /* Ende cms_autosuggest */ 12001 /* Start cms_cookiebanner */ 12002 /*! --GSBDocStart 12003 * @name: @cms/cms_cookiebanner 12004 * @version: 3.1.0 12005 * @description: Das neue Cookiebanner: 12006 * --CMSDocEnd 12007*/"use strict"; 12008cms.makeCMSModule('cms.cookiebanner', { 12009 init: function () { 12010 const base = this; 12011 if (!base.isCookiesEnabled()) { 12012 return; 12013 } 12014 base.setCSSHeight(base); 12015 12016 base.el.addEventListener('open', () => base.open(base)); 12017 base.el.addEventListener('close', () => base.close(base)); 12018 base.el.addEventListener('consentToAll', () => base.consentToAll(base)); 12019 base.el.addEventListener('rejectToAll', () => base.rejectToAll(base)); 12020 // Manuelle Ãffnung initialisieren 12021 document.querySelector(base.options.selectors.disableAutoOpenIfPresent)?.addEventListener('click', function () { 12022 base.el.dispatchEvent(new Event('open')); 12023 }); 12024 // Automatische Ãffnung initialisieren 12025 if (!document.cookie.match(`${base.options.cookies.necessary.on}`) && !document.querySelector(base.options.selectors.disableAutoOpenIfPresent)) { 12026 base.el.dispatchEvent(new Event('open')); 12027 } 12028 // Allen Zustimmen initialisieren 12029 base.el.querySelector(base.options.selectors.consentToAll)?.addEventListener('click', function () { 12030 base.el.addEventListener('afterConsentToAll', () => { 12031 base.el.dispatchEvent(new Event('close')); 12032 }, { once: true }); 12033 base.el.dispatchEvent(new Event('consentToAll')); 12034 }); 12035 // Allen Ablehnen initialisieren 12036 base.el.querySelector(base.options.selectors.rejectToAll)?.addEventListener('click', function () { 12037 base.el.addEventListener('afterRejectToAll', () => { 12038 base.el.dispatchEvent(new Event('close')); 12039 }, { once: true }); 12040 base.el.dispatchEvent(new Event('rejectToAll')); 12041 }); 12042 // SchlieÃung initialisieren 12043 document.querySelector(base.options.selectors.close)?.addEventListener('click', function () { 12044 base.el.dispatchEvent(new Event('close')); 12045 }); 12046 // Label-Wechsel initialisieren 12047 base.el.querySelectorAll(base.options.selectors.checkboxes).forEach( 12048 (el) => el.addEventListener('change', (ev) => base.change(ev.target)) 12049 ); 12050 // Resizes setzen die Höhe als CSS-Variable 12051 window.addEventListener('resize', () => base.setCSSHeight(base)); 12052 ['change', 'toggle', 'afterOpen', 'afterClose'].forEach((eventType) => { 12053 base.el.addEventListener(eventType, () => base.setCSSHeight(base)); 12054 }); 12055 base.el.querySelectorAll('details').forEach((el) => el.addEventListener('toggle', () => base.setCSSHeight(base))); 12056 }, 12057 //überprüft, ob der Browser Cookies erlaubt 12058 isCookiesEnabled: function () { 12059 try { 12060 document.cookie = 'cookietest=1'; 12061 const ret = document.cookie.includes('cookietest='); 12062 document.cookie = 'cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT'; 12063 const isBrave = !!navigator.brave; 12064 return ret && !isBrave; 12065 } 12066 catch (e) { 12067 return false;
12068 } 12069 }, 12070 //Setzt einen einzelnen Cookie mit sinnvollen Standards. Ohne expires läuft der Cookie sofort ab 12071 setCookie: function (cookie, 12072 expires = 'expires=Thu, 01 Jan 1970 00:00:01 GMT', 12073 path = 'path=/', 12074 secure = 'Secure=true', 12075 sameSite = 'SameSite=Strict') { 12076 document.cookie = `${cookie}; ${expires}; ${path}; ${secure}; ${sameSite}`; 12077 }, 12078 // Setzt den Cookie als String oder ruft die assoziierte Function auf 12079 setCookies: function () { 12080 const base = this; 12081 for (const [cookiename, cookiefunction] of Object.entries(base.options.cookies)) { 12082 const input = base.el.querySelector(`[data-banner-cookie-name=${cookiename}]`)?.querySelector('input'); 12083 if (input && input.checked) { 12084 const cookie = cookiefunction.on; 12085 if (typeof cookie === 'function') { 12086 cookie(base); 12087 } else { 12088 if (cookie === 'matomo') { 12089 base.matomo(); 12090 } else { 12091 const d = new Date(); 12092 d.setTime(d.getTime() + base.options.durationInDays * 24 * 60 * 60 * 1000); 12093 const expires = `expires=${d.toUTCString()};`; 12094 base.setCookie(cookie, expires); 12095 } 12096 } 12097 } else { 12098 const cookie = cookiefunction.off; 12099 if (typeof cookie === 'function') { 12100 cookie(base); 12101 } else { 12102 if (cookie === 'matomo') { 12103 base.matomoOff(); 12104 } else { 12105 base.setCookie(cookie); 12106 } 12107 } 12108 } 12109 } 12110 }, 12111 // Erzeugt den Default Matomo-Token 12112 matomo: function () { 12113 const base = this; 12114 const d = new Date(); 12115 d.setTime(d.getTime() + base.options.durationInDays * 24 * 60 * 60 * 1000); 12116 const expires = `expires=${d.toUTCString()};`; 12117 base.setCookie('matomoTracking=true', expires); 12118 base.setCookie('matomoConsent=true', expires); 12119 }, 12120 matomoOff: function () { 12121 const base = this; 12122 base.setCookie('matomoTracking=true'); 12123 base.setCookie('matomoConsent=true'); 12124 }, 12125 initCheckedStatus: function (base) { 12126 for (const [cookiename, cookiefunction] of Object.entries(base.options.cookies)) { 12127 const input = base.el.querySelector(`[data-banner-cookie-name=${cookiename}]`)?.querySelector('input'); 12128 if (input && !input.attributes.disabled) { 12129 if (typeof cookiefunction.check === 'function') { 12130 input.checked = cookiefunction.check(); 12131 input.dispatchEvent(new Event('change')); 12132 } else { 12133 if (typeof cookiefunction.on !== 'function') { 12134 if (cookiefunction.on !== 'matomo') { 12135 input.checked = document.cookie.match(`${cookiefunction.on}`); 12136 input.dispatchEvent(new Event('change')); 12137 } else { 12138 input.checked = document.cookie.match(`matomoTracking=true|matomoConsent=true`); 12139 input.dispatchEvent(new Event('change')); 12140 } 12141 } 12142 } 12143 } 12144 } 12145 base.el.querySelectorAll('input[checked]').forEach((el) => { 12146 el.checked = true; 12147 }); 12148 }, 12149 open: function (base) { 12150 base.el.dispatchEvent(new Event('beforeOpen'));
12151 // Input checked-Status aktualisieren 12152 base.initCheckedStatus(base); 12153 if (base.options.modal) { 12154 document.querySelector(base.options.selectors.dialog).showModal(); 12155 } else { 12156 document.querySelector(base.options.selectors.dialog).show(); 12157 } 12158 base.el.dispatchEvent(new Event('afterOpen')); 12159 }, 12160 close: function (base) { 12161 base.el.dispatchEvent(new Event('beforeClose')); 12162 base.setCookies(); 12163 base.el.close(); 12164 base.el.dispatchEvent(new Event('afterClose')); 12165 }, 12166 change: function (el) { 12167 el.dispatchEvent(new Event('beforeChange', { bubbles: true })); 12168 const label = document.querySelector(`[for=${el.id}],[id=${el.attributes['aria-labelledby']}]`); 12169 if (label && label.attributes['data-label-on'] && label.attributes['data-label-off']) { 12170 label.innerText = el.checked ? label.attributes['data-label-on'].value : label.attributes['data-label-off'].value; 12171 } 12172 el.dispatchEvent(new Event('afterChange', { bubbles: true })); 12173 }, 12174 consentToAll: function (base) { 12175 base.el.dispatchEvent(new Event('beforeConsentToAll')); 12176 base.el.querySelectorAll(base.options.selectors.checkboxes).forEach((el) => { 12177 el.checked = true; 12178 el.dispatchEvent(new Event('change')); 12179 }); 12180 base.el.dispatchEvent(new Event('afterConsentToAll')); 12181 }, 12182 rejectToAll: function (base) { 12183 base.el.dispatchEvent(new Event('beforeRejectToAll')); 12184 base.el.querySelectorAll(base.options.selectors.checkboxes).forEach((el) => { 12185 el.checked = false; 12186 el.dispatchEvent(new Event('change')); 12187 }); 12188 base.el.dispatchEvent(new Event('afterRejectToAll')); 12189 }, 12190 setCSSHeight: function (base) { 12191 base.el.dispatchEvent(new Event('beforeSetCSSHeight')); 12192 document.querySelector('body').style.setProperty('--cookiebanner-height', `${base.el.offsetHeight}px`); 12193 base.el.dispatchEvent(new Event('afterSetCSSHeight')); 12194 }, 12195 defaultOptions: { 12196 selectors: { 12197 dialog: '#cookiebanner', 12198 disableAutoOpenIfPresent: '.js-cookiebanner-opener', 12199 close: '.js-cookiebanner-button-confirm-selection', 12200 consentToAll: '.js-cookiebanner-button-consent-to-all', 12201 rejectToAll: '.js-cookiebanner-button-reject-to-all', 12202 checkboxes: 'input[type=checkbox]' 12203 }, 12204 durationInDays: 30, 12205 modal: true, 12206 cookies: { 12207 necessary: { 12208 on: 'cmsbanner=closed', 12209 off: (base) => { 12210 const d = new Date(); 12211 d.setTime(d.getTime() + base.options.durationInDays * 24 * 60 * 60 * 1000); 12212 const expires = `expires=${d.toUTCString()};`; 12213 base.setCookie('cmsbanner=closed', expires); 12214 } 12215 } 12216 } 12217 } 12218}); 12219 12220 /* Ende cms_cookiebanner */ 12221 /* Start cms_consent_reload */ 12222 /** 12223 * @name cms_consent_reload 12224 * @version 1.0.0 12225 * @see {@link http://semver.org|Semantic Versioning} 12226 * @author anuebel 12227 * 12228 * @desc Lädt den eigentlichen Inhalt eines Bereichs erst dann, wenn eine Zustimmung erteilt wurde. 12229 * 12230 * Das Modul ist in Bezug auf seine nachzuladenden Inhalte agnostisch und kann daher an allen Stellen verwendet werden, wo ein Inhalt 12231 * erst nach der Zustimmung des Nutzers nachgeladen werden soll. Es müssen folgende Voraussetzungen erfüllt werden: 12232 * 12233 * 1. Ein Element ist über ein Attribut data-consent-reload-trigger-container erreichbar (initial dargestellter Bereich) 12234 * 2. Ein Element ist über ein Attribut data-consent-reload-trigger erreichbar (Auslöser für das Nachladen) 12235 * 3. Ein Element ist über ein Attribut data-consent-reload-target erreichbar 12236 * und der Wert des Attributs enthält die URL zum nachzuladenden Bereich 12237 * 12238 * Optionen: 12239 * <ul> 12240 * <li>cookieName - der Name des Session-Cookie, durch den sich die Zustimmung des Nutzers gemerkt wird(Default: cms_consent)</li> 12241 * </ul> 12242 * 12243 * 12244 * Benötigt "js-cookie": "3.0.5", 12245 * 12246 * 12247 * @requires {@link external:jQuery} 12248 * 12249 * @example 12250 * $('.js-consent-reload').cms_consent_reload(); 12251 */"use strict"; 12252cms.makeCMSModule("cms.consent_reload", { 12253 consentGiven: false, 12254 init: function () { 12255 this.$consentTriggerContainer = $(this.options.triggerContainer, this.$el); 12256 if (!this.$consentTriggerContainer.length) { 12257 cms.error('%o: Kein Trigger-Container-Element \'' + this.options.triggerContainer + '\' gefunden', this.$el); 12258 return; 12259 } 12260 12261 this.$consentTrigger = $(this.options.reloadContainer, this.$el); 12262 if (!this.$consentTrigger.length) { 12263 cms.error('%o: Kein Trigger-Element \'' + this.options.reloadContainer + '\' gefunden', this.$el); 12264 return; 12265 } 12266 12267 this.$consentTarget = $(this.options.reloadTarget, this.$el); 12268 if (!this.$consentTarget.length) { 12269 cms.error('%o: Kein Target-Element \'' + this.options.reloadTarget + '\' gefunden', this.$el); 12270 return; 12271 } 12272 12273 this.consentTargetURL = this.$consentTarget.data('consent-reload-target'); 12274 if (!this.consentTargetURL) { 12275 console.error('%o: Keine URL für nachzuladendes Ziel gefunden', this.$el); 12276 return; 12277 } 12278 12279 this.consentCookieHost = this.$consentTriggerContainer.data('consent-reload-cookie-host'); 12280 if (!this.consentCookieHost) { 12281 console.log('%o: Kein Cookie-Host für nachzuladendes Ziel gefunden', this.$el); 12282 return; 12283 } 12284 12285 this.completeCookieName = this.consentCookieHost ? this.options.cookieName : this.options.cookieName; 12286 12287 if (Cookies.get(this.completeCookieName)) { 12288 this.embedConsentTarget(); 12289 } else { 12290 this.$el.on(`consent.${this.eventName}`, this, this.onConsent);
12291 this.$consentTrigger.on('click' + this.instanceNamespace, () => { 12292 this.$el.trigger(`consent.${this.eventName}`); 12293 }); 12294 } 12295 }, 12296 12297 successfulResponseCallback: function (response) { 12298 this.$consentTriggerContainer.remove(); 12299 this.$consentTarget.html(response); 12300 this.$el.addClass('is-allowed-and-replaced'); 12301 }, 12302 12303 erroneousResponseCallback: function (jqXHR, textStatus, errorThrown) { 12304 cms.error('Fehler bei der Ermittlung des nachzuladenden Ziels: %o', errorThrown); 12305 }, 12306 12307 embedConsentTarget: function () { 12308 $.ajax({ 12309 url: this.consentTargetURL, 12310 success: this.successfulResponseCallback, 12311 error: this.erroneousResponseCallback, 12312 context: this 12313 }); 12314 }, 12315 12316 onConsent: function (ev) { 12317 const base = ev.data; 12318 ev.stopPropagation(); 12319 if (!base.consentGiven) { 12320 base.consentGiven = true; 12321 base.$el.trigger(`afterConsent.${base.eventName}`); 12322 base.rememberConsentGiven(); 12323 base.embedConsentTarget(); 12324 } 12325 }, 12326 12327 rememberConsentGiven: function () { 12328 Cookies.set(this.completeCookieName, 'accepted', { expires: 28 }); 12329 }, 12330 12331 defaultOptions: { 12332 cookieName: 'cms_consent', 12333 triggerContainer: '[data-consent-reload-trigger-container]', 12334 reloadContainer: '[data-consent-reload-trigger]', 12335 reloadTarget: '[data-consent-reload-target]' 12336 } 12337}); 12338 12339 /* Ende cms_consent_reload */ 12340 /* Start cms_dialog */ 12341 /*! --GSBDocStart 12342 * @name: @cms/cms_dialog 12343 * @version: 2.2.2 12344 * @description: [//]: # (Diesen und folgende Kommentare auf keinen Fall löschen!) [//]: # (Nur so akzeptiert license-checker die Lizenz) [//]: # (SEE LICENSE IN LICENSE-INTERNAL.txt) [//]: # (https://license-internal.txt) 12345 * --CMSDocEnd 12346*/"use strict"; 12347cms.makeCMSModule('cms.dialog', { 12348 init: function () { 12349 const base = this; 12350 12351 const dialog = base.el; 12352 const $dialog = base.$el; 12353 const id = $dialog.attr('id'); 12354 $(`[data-dialog-open-modal=${id}]`).on('click', function () { 12355 dialog.showModal(); 12356 $dialog.trigger(`afterOpen`, base); 12357 }); 12358 const $popoverOpeners = $(`[data-dialog-open-popover=${id}]`).on('click', function (event) { 12359 const $opener = $(this); 12360 12361 cms.requireCMSComponent("bundle_popover", $dialog).done(function () { 12362 if ($opener.attr('aria-expanded') === 'true') { 12363 base.hidePopover(base); 12364 } else { 12365 base.showPopover(event.currentTarget, base); 12366 } 12367 12368 $dialog.trigger(`afterOpen`, base); 12369 }); 12370 }); 12371 if ($popoverOpeners.length) { 12372 base.initPopoverEvents(base); 12373 } 12374 $(`[data-dialog-open=${id}]`).on('click', function () { 12375 dialog.show(); 12376 $dialog.trigger(`afterOpen`, base); 12377 }); 12378 $(`[data-dialog-close=${id}]`).on('click', function () { 12379 dialog.close(); 12380 $dialog.find(base.options.selectors.mediaElementWrapper).each((index, el) => { 12381 el.pause(); 12382 }); 12383 $dialog.trigger(`afterClose`, base); 12384 }); 12385 12386 $dialog.on(`afterOpen${base.instanceNamespace}`, base, base.afterOpen); 12387 }, 12388 afterOpen: function (event) { 12389 const base = event.data; 12390 $(this).find(base.options.selectors.slideshowsToUpdate).trigger('update.slideshow'); 12391 base.options.updateCallbackAfterOpen(this); 12392 }, 12393 afterClose: function (event) { 12394 const base = event.data; 12395 base.options.updateCallbackAfterClose(this); 12396 }, 12397 initPopoverEvents: function (base) { 12398 const $dialog = base.$el; 12399 const id = $dialog.attr('id'); 12400 const $buttons = $(`[data-dialog-open-popover=${id}]`).attr('aria-expanded', 'false'); 12401 $dialog.on('keydown', (event) => { 12402 if (event.key === "Escape") { 12403 base.hidePopover(base); 12404 } 12405 }). 12406 on('focusout', (event) => { 12407 const focusedElement = event.relatedTarget; 12408 if (!$dialog.is(focusedElement) && !$dialog.find(focusedElement).length && !($buttons.find(focusedElement).length || $buttons.is(focusedElement))) { 12409 base.hidePopover(base); 12410 } 12411 }); 12412 $(`[data-dialog-close=${id}]`).on('click', () => base.hidePopover(base)); 12413 }, 12414 updatePosition: function (button, popover) { 12415 const { autoPlacement, computePosition, shift, offset } = FloatingUIDOM; 12416 12417 computePosition(button, popover, { 12418 middleware: [ 12419 autoPlacement(), 12420 offset(10), 12421 shift()] 12422 12423 }).then(({ x, y }) => { 12424 $(popover).css('--popover-position-left', `${x}px`); 12425 $(popover).css('--popover-position-top', `${y}px`); 12426 }); 12427 }, 12428 showPopover: function (button, base) { 12429 const { autoUpdate } = FloatingUIDOM; 12430 12431 const $dialog = base.$el; 12432 const id = $dialog.attr('id'); 12433 const $buttons = $(`[data-dialog-open-popover=${id}]`);
12434 if ($buttons.attr('aria-expanded') === "false") { 12435 $buttons.attr('aria-expanded', true); 12436 $dialog.addClass(base.options.selectors.popoverIsShown); 12437 autoUpdate(button, base.el, () => base.updatePosition(button, base.el)); 12438 requestAnimationFrame(() => { 12439 if ($dialog.find('[data-dialog-close]').length) { 12440 $dialog.find('[data-dialog-close]').focus(); 12441 } else { 12442 $dialog.focus(); 12443 } 12444 $buttons.on('focusout', (event) => { 12445 const focusedElement = event.relatedTarget; 12446 if (!$dialog.is(focusedElement) && !$dialog.find(focusedElement).length && !($buttons.find(focusedElement).length || $buttons.is(focusedElement))) { 12447 base.hidePopover(base); 12448 } 12449 }); 12450 }); 12451 } 12452 }, 12453 hidePopover(base) { 12454 const $dialog = base.$el; 12455 const id = $dialog.attr('id'); 12456 const $buttons = $(`[data-dialog-open-popover=${id}]`); 12457 $buttons.attr('aria-expanded', false); 12458 $dialog.find(base.options.selectors.mediaElementWrapper).each((index, el) => { 12459 el.pause(); 12460 }); 12461 $dialog.removeClass(base.options.selectors.popoverIsShown); 12462 $buttons.off('focusout'); 12463 $buttons.focus(); 12464 }, 12465 defaultOptions: { 12466 selectors: { 12467 slideshowsToUpdate: '.js-slideshow-dialog', 12468 mediaElementWrapper: 'mediaelement-wrapper', 12469 popoverIsShown: 'popover-is-shown' 12470 }, 12471 updateCallbackAfterOpen: function () {}, 12472 updateCallbackAfterClose: function () {} 12473 } 12474 12475}); 12476 12477 /* Ende cms_dialog */ 12478 /* Start cms_dynamic_file_uploader */ 12479 "use strict";cms.makeCMSModule("cms.dynamic_file_uploader", { 12480 12481 init: function () { 12482 const base = this; 12483 12484 base.fileCount = 1; 12485 base.initButtons(); 12486 base.initSubmit(); 12487 }, 12488 12489 initButtons: function () { 12490 const base = this; 12491 12492 base.$el.find(base.options.selectors.addFileButton).on('click', function (e) { 12493 e.preventDefault(); 12494 12495 const newInput = $(` 12496 <div class="${base.options.fileInputClasses}"> 12497 <input type="file" name="${base.options.fileInputName}${base.fileCount}" accept="${base.options.inputAcceptValue}"> 12498 </div> 12499 `); 12500 base.$el.find(base.options.selectors.fileInputsWrapper).append(newInput); 12501 base.fileCount++; 12502 base.$el.find(base.options.selectors.removeFileButton).show(); 12503 if (base.fileCount >= base.options.maxFileCount) { 12504 base.$el.find(base.options.selectors.addFileButton).hide(); 12505 } 12506 }); 12507 12508 base.$el.find(base.options.selectors.removeFileButton).on('click', function (e) { 12509 e.preventDefault(); 12510 12511 const inputs = base.$el.find(base.options.selectors.fileInput); 12512 if (inputs.length > 1) { 12513 inputs.last().remove(); 12514 base.fileCount--; 12515 if (base.fileCount <= 1) { 12516 base.$el.find(base.options.selectors.removeFileButton).hide(); 12517 } 12518 base.$el.find(base.options.selectors.addFileButton).show(); 12519 } 12520 }); 12521 }, 12522 12523 initSubmit: function () { 12524 const base = this; 12525 12526 base.$el.on('submit', function (e) { 12527 e.preventDefault(); 12528 12529 const $fileFieldset = base.$el.find(base.options.selectors.fileFieldset); 12530 const $errorList = base.$el.find(base.options.selectors.errorList); 12531 $errorList.empty(); 12532 12533 let totalSize = 0; 12534 let hasInvalidFileType = false;
12535 12536 $(`${base.options.selectors.fileInput} input[type="file"]`).each(function () { 12537 const file = this.files[0]; 12538 if (file) { 12539 totalSize += file.size; 12540 if (!base.options.allowedTypes.includes(file.type)) { 12541 $errorList.append(`<li>${FILE_UPLOAD_INVALID_FILE_TYPE} ${file.name}</li>`); 12542 } 12543 } 12544 }); 12545 12546 let hasInvalidSize = totalSize > base.options.maxTotalFileSize; 12547 let hasErrors = hasInvalidFileType || hasInvalidSize; 12548 if (hasErrors) { 12549 if (hasInvalidSize) { 12550 $errorList.append(`<li>${FILE_UPLOAD_INVALID_FILE_SIZE}</li>`); 12551 } 12552 $fileFieldset.get(0).scrollIntoView({ behavior: "smooth" }); 12553 } else { 12554 this.submit(); 12555 } 12556 }); 12557 }, 12558 12559 defaultOptions: { 12560 fileInputName: 'file-', 12561 allowedTypes: ['application/pdf', 'text/plain', 'image/jpeg', 'image/png', 'image/bmp'], 12562 inputAcceptValue: 'application/pdf,text/plain,image/jpeg,image/png,image/bmp', 12563 maxTotalFileSize: 10 * 1024 * 1024, // 10 MB 12564 maxFileCount: 6, // 10 MB 12565 fileInputClasses: 'c-file-inputs__input js-file-input', 12566 selectors: { 12567 fileInputsWrapper: '.js-file-inputs-wrapper', 12568 fileInput: '.js-file-input', 12569 addFileButton: '.js-file-inputs-add-file', 12570 removeFileButton: '.js-file-inputs-remove-file', 12571 fileFieldset: '.js-file-inputs-fieldset', 12572 errorList: '.js-file-inputs-error-list' 12573 } 12574 } 12575}); 12576 12577 /* Ende cms_dynamic_file_uploader */ 12578 /* Start cms_fancy_selects */ 12579 /*! --GSBDocStart 12580 * @name: @cms/cms_fancy_selects 12581 * @version: 5.0.0 12582 * @description: Erzeugt für jedes enthaltene `<select>` ein Widget, welches dieses `<select>` steuert. 12583 * --CMSDocEnd 12584*/"use strict"; 12585cms.makeCMSModule("cms.fancy_selects", { 12586 init: function () { 12587 if (this.arePreconditionsMet()) { 12588 this.transformSelects(); 12589 this.bindSelectEvents(); 12590 this.bindListEvents(); 12591 this.makeFancy(); 12592 this.makeAccessible(); 12593 } 12594 }, 12595 arePreconditionsMet() { 12596 var base = this; 12597 var conditionsMet = true; 12598 var multiselectElements = []; 12599 var optgroupElements = []; 12600 var messageText; 12601 12602 base.$el.find(this.options.selectors.select).each(function (i, select) { 12603 var $select = $(select); 12604 if ($select.is('[multiple], [aria-multiselectable]') || $select.attr('size') > 1) { 12605 multiselectElements.push(select); 12606 } 12607 if ($select.find('optgroup').length) { 12608 optgroupElements.push(select); 12609 } 12610 }); 12611 12612 if (multiselectElements.length) { 12613 conditionsMet = false; 12614 messageText = `${base.moduleName}: Mindestens ein verarbeitetes <select> sieht eine Mehrfachauswahl vor. `; 12615 messageText += "Diese Eigenschaft wird nicht unterstützt. Die Initialisierung des Moduls wird abgebrochen. "; 12616 messageText += "Um diesen Fehler zu beheben, muss entweder die Option selectors.select angepasst werden oder "; 12617 messageText += "die Attribute 'multiple', 'size' und 'aria-multiselectable' von den <select>s entfernt werden."; 12618 console.error(messageText, multiselectElements); 12619 } 12620 12621 if (optgroupElements.length) { 12622 conditionsMet = false; 12623 messageText = `${base.moduleName}: Mindestens ein verarbeitetes <select> enthält ein <optgroup> Element. `; 12624 messageText += "Dieses Element wird nicht unterstützt. Die Initialisierung des Moduls wird abgebrochen. "; 12625 messageText += "Um diesen Fehler zu beheben, muss entweder die Option selectors.select angepasst werden oder "; 12626 messageText += "die <optgroup> Elemente entfernt werden."; 12627 console.error(messageText, optgroupElements); 12628 } 12629 12630 return conditionsMet; 12631 }, 12632 makeAccessible: function () { 12633 var base = this; 12634 base.uis.forEach(function (ui) { 12635 var listId = base.generateID(), 12636 activeDescendant = ui.opts.filter('[aria-selected=true]'); 12637 12638 ui.opts.each(function () { 12639 $(this).attr('id', base.generateID()); 12640 }); 12641 ui.errMsg.each(function () { 12642 $(this).attr('id', $(this).attr('id') || base.generateID()); 12643 }); 12644 $(ui.select.prop('labels')).each(function () { 12645 $(this).attr('id', $(this).attr('id') || base.generateID()); 12646 }); 12647 12648 if (ui.select.attr('aria-label')) { 12649 base.addLabelTo(ui.select, ui.select.attr('aria-label')); 12650 ui.select.attr('aria-label', null); 12651 } 12652 12653 ui.list.attr({ 12654 role: "listbox", 12655 id: listId, 12656 'aria-labelledby': base.getLabelIDs(ui, null) || null, 12657 'aria-describedby': base.getDescriptionIDs(ui) || null 12658 }); 12659 ui.heading.attr({ 12660 role: 'combobox', 12661 'aria-owns': listId, 12662 'aria-controls': listId, 12663 'aria-labelledby': base.getLabelIDs(ui, null) || null, 12664 'aria-describedby': base.getDescriptionIDs(ui) || null, 12665 'aria-haspopup': 'listbox', 12666 'aria-activedescendant': activeDescendant.attr('id') || '', 12667 'aria-required': typeof ui.select.attr('required') !== "undefined" || Boolean(ui.select.attr('aria-required')), 12668 'aria-expanded': 'false', 12669 'title': ui.select.attr('title') || null 12670 }); 12671 }); 12672 base.$el.trigger('initialized.' + base.eventName); 12673 }, 12674 addLabelTo: function (controlElem, labelText) { 12675 var base = this, 12676 id = base.generateID(), 12677 labelledby = controlElem.attr('aria-labelledby'), 12678 ariaLabels = !labelledby ? [] : labelledby.trim().split(/\s+/), 12679 newlyCreatedLabel; 12680 12681 newlyCreatedLabel = $("<span/>"). 12682 attr({ 12683 id: id, 12684 hidden: 'hidden' 12685 }). 12686 text(labelText); 12687 ariaLabels.push(id); 12688 12689 controlElem. 12690 attr('aria-labelledby', ariaLabels.join(' ')). 12691 before(newlyCreatedLabel); 12692 }, 12693 getLabelIDs: function (ui, activeDescendant) { 12694 var base = this, 12695 ids = {}, 12696 labels = $(ui.select.prop('labels')), 12697 ariaLabels = ui.select.attr('aria-labelledby') || ''; 12698 [].forEach.call(labels.add(activeDescendant), function (label) { 12699 var labelId = $(label).attr('id'); 12700 if (labelId) { 12701 ids[labelId.trim()] = true; 12702 } 12703 }); 12704 ariaLabels.split('\s+').forEach(function (id) { 12705 if (id) { 12706 ids[id] = true; 12707 } 12708 }); 12709 return Object.keys(ids).join(' '); 12710 }, 12711 getDescriptionIDs: function (ui) { 12712 var base = this, 12713 ids = {}, 12714 ariaDescriptions = ui.select.attr('aria-describedby') || ''; 12715 ariaDescriptions.split(/\s+/g).forEach(function (id) { 12716 if (id) { 12717 ids[id] = true; 12718 } 12719 }); 12720 ui.errMsg.filter(':visible').map(function (i, msg) { 12721 var id = $(msg).attr('id') || base.generateID(); 12722 ids[id] = true; 12723 }); 12724 return Object.keys(ids).join(' '); 12725 }, 12726 transformSelects: function () { 12727 var base = this; 12728 base.selects = base.$el.find('select'); 12729 base.uis = $.map(base.selects, function (sel) { 12730 var select = $(sel), 12731 labels = $(sel.labels), 12732 originalSelectId = select.attr('id'), 12733 newSelectId = 'replacedSelect_' + originalSelectId, 12734 wrapper,heading,list,ui, 12735 i,count; 12736 select. 12737 attr('id', newSelectId). 12738 addClass(base.options.classes.replacedSelect); 12739 wrapper = $(base.options.selectors.wrapper, base.el).insertAfter(select); 12740 list = wrapper.find(base.options.selectors.list); 12741 count = select.find('option').length; 12742 for (i = 0; i < count; i++) { 12743 list.append(base.options.markup.listItem); 12744 } 12745 12746 heading = wrapper.find(base.options.selectors.heading); 12747 ui = { 12748 select: select, 12749 wrapper: wrapper, 12750 heading: heading.attr('id', originalSelectId), 12751 list: list, 12752 opts: list.find('li'), 12753 errMsg: select.siblings(base.options.selectors.errorMessage) 12754 }; 12755 labels.each(function (i, label) { 12756 $(label).attr('for', newSelectId); 12757 }); 12758 12759 base.transformOptions(ui); 12760 base.updateValidityStatus(ui); 12761 return ui; 12762 }); 12763 }, 12764 transformOptions: function (ui) { 12765 var base = this, 12766 select = ui.select, 12767 options = select.find('option'), 12768 selectedIndex = select.prop('selectedIndex'), 12769 selectedOption = options.eq(selectedIndex > -1 ? selectedIndex : NaN), 12770 heading = ui.heading, 12771 list = ui.list; 12772 heading.text(selectedOption.text()); 12773 options.each(function (i) { 12774 var opt = $(this), 12775 isSelected = opt.is(selectedOption); 12776 ui.opts.eq(i). 12777 attr('role', "option"). 12778 attr('aria-disabled', opt.attr('disabled') ? "true" : "false"). 12779 attr('aria-selected', isSelected ? "true" : "false"). 12780 attr('data-value', opt.val()). 12781 text(opt.text()); 12782 }); 12783 }, 12784 bindListEvents: function () { 12785 var base = this; 12786 base.uis.forEach(function (ui) { 12787 ui.wrapper. 12788 on('keydown', { base: base, ui: ui }, base.arrowNavigation). 12789 on('keydown', { base: base, ui: ui }, base.closeOnEscape); 12790 ui.list. 12791 on('mousedown', base.preventFocusOut). 12792 on('mouseup', { base: base, ui: ui }, base.directSelect); 12793 }); 12794 }, 12795 closeOnEscape: function (ev) { 12796 if (ev.key === "Escape" || ev.key === "Esc") { 12797 ev.preventDefault(); 12798 $(this).trigger('close.simple_toggle'); 12799 } 12800 }, 12801 arrowNavigation: function (ev) { 12802 var base = ev.data && ev.data.base, 12803 ui = ev.data && ev.data.ui, 12804 activeOption = ui.opts.filter('[aria-selected=true]'),
12805 activeIndex = ui.opts.index(activeOption), 12806 option; 12807 switch (ev.key) { 12808 case "Down": 12809 case "ArrowDown": 12810 ui.wrapper.trigger('open.simple_toggle'); 12811 option = base.findOption(ui, activeIndex, 'next'); 12812 break; 12813 case "Up": 12814 case "ArrowUp": 12815 ui.wrapper.trigger('open.simple_toggle'); 12816 option = base.findOption(ui, activeIndex, 'prev'); 12817 break; 12818 default: 12819 return; 12820 } 12821 if (option && option.length && !option.is(activeOption)) { 12822 base.selectOption(ui, option); 12823 } 12824 ev.preventDefault(); 12825 ev.stopPropagation(); 12826 }, 12827 findOption: function (ui, activeIndex, criterion) { 12828 var base = this, 12829 opts = ui.opts, 12830 opt, 12831 i,l; 12832 if (!opts.not('[aria-disabled=true]').length) { 12833 return $(); 12834 } 12835 for (i = 1, l = opts.length; i <= l; i++) { 12836 if (criterion === 'next') { 12837 opt = opts.eq((activeIndex + i) % l); 12838 } else if (criterion === 'prev') { 12839 opt = opts.eq(activeIndex - i); 12840 } 12841 if (opt.not('[aria-disabled=true]').length) { 12842 return opt; 12843 } 12844 } 12845 return $(); 12846 }, 12847 selectOption: function (ui, opt) { 12848 var base = this, 12849 option = $(opt), 12850 optionId = option.attr('id'); 12851 ui.select. 12852 val(option.attr('data-value')). 12853 trigger('change'); 12854 base.transformOptions(ui); 12855 base.scrollBoxTo(ui, option); 12856 ui.heading. 12857 attr('aria-activedescendant', optionId). 12858 focus(); 12859 }, 12860 scrollBoxTo: function (ui, option) { 12861 const base = this; 12862 if (ui.list.length && option.length) { 12863 base.scrollIntoViewOneLevel(ui.list[0], option[0]); 12864 } 12865 }, 12866 scrollIntoViewOneLevel: function (scrollContainer, scrollChild) { 12867 const containerRect = scrollContainer.getBoundingClientRect(); 12868 const childRect = scrollChild.getBoundingClientRect(); 12869 12870 const bottomDiff = childRect.bottom - containerRect.bottom; 12871 const topDiff = containerRect.top - childRect.top; 12872 12873 if (bottomDiff > 0) {// child is hidden below container 12874 scrollContainer.scrollBy(0, bottomDiff); 12875 } 12876 if (topDiff > 0) {// child is hidden above container 12877 scrollContainer.scrollBy(0, -topDiff); 12878 } 12879 }, 12880 directSelect: function (ev) { 12881 var base = ev.data.base, 12882 ui = ev.data.ui, 12883 opt = $(ev.target); 12884 if (opt.is(':not([aria-disabled=true])')) { 12885 base.selectOption(ui, opt); 12886 } 12887 }, 12888 makeFancy: function () { 12889 var base = this; 12890 12891 base.uis.forEach(function (ui) { 12892 ui.wrapper. 12893 cms_simple_toggle({ 12894 closer: '', 12895 opener: ui.heading, 12896 item: ui.list, 12897 showClass: 'is-expanded', 12898 hideClass: 'is-collapsed' 12899 }). 12900 on('focusout', base.onFocusOut) 12901 //as the "parent" widget, we don't want any of these to bubble 12902 .on('close.simple_toggle.cms open.simple_toggle.cms toggle.simple_toggle.cms', base, base.preventBubbling); 12903 ui.opts. 12904 on('mouseup', base.triggerCloseOpt); 12905 ui.heading.addClass(base.options.classes.isFancy); 12906 }); 12907 }, 12908 onFocusOut: function (ev) { 12909 var wrapper = $(this), 12910 rel = ev.relatedTarget; 12911 if (!rel || !wrapper.find(rel).length) { 12912 wrapper.trigger('close.simple_toggle'); 12913 } 12914 }, 12915 preventBubbling: function (ev) { 12916 ev.stopPropagation(); 12917 }, 12918 preventFocusOut: function (ev) { 12919 ev.preventDefault(); 12920 }, 12921 triggerCloseOpt: function (ev) { 12922 var opt = $(this); 12923 if (opt.is(':not([aria-disabled=true])')) { 12924 opt.trigger('close.simple_toggle'); 12925 } 12926 }, 12927 bindSelectEvents: function () { 12928 var base = this; 12929 base.uis.forEach(function (ui) { 12930 ui.select.on('invalid change', { base: base, ui: ui }, base.validate); 12931 }); 12932 }, 12933 validate: function (ev) { 12934 var base = ev.data.base, 12935 ui = ev.data.ui, 12936 select = ui.select[0]; 12937 base.updateValidityStatus(ui); 12938 if (!select.validity.valid) { 12939 setTimeout(function () { 12940 var activeElement = $(document.activeElement), 12941 isActiveElementAfterSelect = select.compareDocumentPosition(activeElement[0]) === Node.DOCUMENT_POSITION_FOLLOWING, 12942 isActiveElementFancy = activeElement.hasClass(base.options.classes.isFancy), 12943 isActiveElementSubmit = activeElement.is('[type=submit]'); 12944 if (isActiveElementSubmit || !isActiveElementFancy && isActiveElementAfterSelect) { 12945 ui.heading.focus(); 12946 } 12947 }, 0); 12948 } 12949 },
12950 updateValidityStatus: function (ui) { 12951 var base = this, 12952 select = ui.select[0], 12953 errMsgs = ui.select.siblings(base.options.selectors.errorMessage), 12954 hasStickyErrorMessage; 12955 if (select.validity.valid) { 12956 hasStickyErrorMessage = Boolean(errMsgs.filter(base.options.selectors.stickyErrorMessage).length); 12957 ui.heading.attr('aria-invalid', hasStickyErrorMessage ? null : false); 12958 errMsgs.not(base.options.selectors.stickyErrorMessage).attr('aria-hidden', true); 12959 } else { 12960 ui.heading.attr('aria-invalid', true); 12961 errMsgs.not(base.options.selectors.stickyErrorMessage).attr('aria-hidden', false); 12962 } 12963 ui.heading.attr('aria-describedby', base.getDescriptionIDs(ui) || null); 12964 }, 12965 defaultOptions: { 12966 cycle: true, 12967 selectors: { 12968 select: 'select', 12969 wrapper: //Markup der neuen fancy Selectbox 12970 '<div class=\'c-fancy-selects__select\'>' + 12971 '<p class=\'c-fancy-selects__heading\' tabindex=\'0\'></p>' + 12972 '<ul class=\'c-fancy-selects__list\'></ul>' + 12973 '</div>', 12974 heading: '.c-fancy-selects__heading', // Selektor des Kopfelementes, in dem der aktuell ausgewählte Eintrag angezeigt wird 12975 list: '.c-fancy-selects__list', // Selektor der Liste mit Einträgen 12976 errorMessage: '.formError, .js-clientsidevalidation-errmsg', // Selektor der Fehlermeldungen 12977 stickyErrorMessage: '.formError' // Selektor der Fehlermeldungen, bei denen aria-hidden Attribut nicht gesetzt wird 12978 }, 12979 markup: { 12980 listItem: "<li class='c-fancy-selects__item'/>" 12981 }, 12982 classes: { 12983 isFancy: 'js-is-fancy', 12984 replacedSelect: 'c-fancy-selects__replaced-select' 12985 } 12986 } 12987}); 12988 12989 /* Ende cms_fancy_selects */ 12990 /* Start cms_filter_list */ 12991 'use strict'; 12992cms.makeCMSModule('cms.result_list_filter', { 12993 init: function () { 12994 const base = this; 12995 base.allInstances.instCount++; 12996 base.instNS = '.inst' + base.allInstances.instCount + '.' + base.eventName; 12997 base.prepareElements(); 12998 base.registerEventListeners(); 12999 }, 13000 13001 prepareElements: function () { 13002 const base = this; 13003 base.$input = base.$el.find(base.options.selectors.input); // should find one 13004 base.$select = base.$el.find(base.options.selectors.select); // should find one or none 13005 base.$items = base.$el.find(base.options.selectors.item); 13006 base.$resultCount = base.$el.find(base.options.selectors.resultCount); // should find one or none 13007 }, 13008 13009 registerEventListeners: function () { 13010 const base = this; 13011 base.$input.on('input', base, base.handleInput); 13012 base.$select.on('change', base, base.handleSelect); 13013 base.$el.find(base.options.selectors.inputClearButton).on('click', base, base.clearInput); 13014 }, 13015 13016 clearInput: function (e) { 13017 const base = e.data; 13018 const selectValue = base.$select.length ? base.$select[0].value : ''; 13019 base.$input.val(''); 13020 base.$el.find(base.options.selectors.inputClearButton).removeClass('is-dirty'); 13021 base.$el.find(base.options.selectors.resultCount).addClass("aural"); 13022 base.$el.find(base.options.selectors.item).each((index, item) => { 13023 item.innerHTML = item.innerHTML.replace(/<\/?mark>/g, ''); 13024 }); 13025 base.filterResultList('', selectValue); 13026 base.updateDisplay(''); 13027 }, 13028 13029 handleInput: function (e) { 13030 const base = e.data; 13031 const inputValue = this.value; 13032 const selectValue = base.$select.length ? base.$select[0].value : ''; 13033 13034 if (inputValue !== '') { 13035 base.$el.find(base.options.selectors.inputClearButton).addClass('is-dirty'); 13036 } else { 13037 base.$el.find(base.options.selectors.inputClearButton).removeClass('is-dirty'); 13038 base.filterResultList(inputValue, selectValue); 13039 base.updateDisplay(inputValue); 13040 } 13041 13042 if (inputValue.length >= 3) { 13043 base.$el.find(base.options.selectors.resultCount).removeClass("aural"); 13044 base.filterResultList(inputValue, selectValue); 13045 base.updateDisplay(inputValue); 13046 13047 base.$el.find(base.options.selectors.item).each((index, item) => { 13048 item.innerHTML = item.innerHTML.replace(/<\/?mark>/g, ''); 13049 item.innerHTML = item.innerHTML.replace(new RegExp(inputValue + "(?=[^>]*<)", 'igm'), '<mark>$&</mark>'); 13050 }); 13051 } else { 13052 base.$el.find(base.options.selectors.resultCount).addClass("aural"); 13053 base.$el.find(base.options.selectors.item).each((index, item) => { 13054 item.innerHTML = item.innerHTML.replace(/<\/?mark>/g, ''); 13055 }); 13056 } 13057 }, 13058 13059 handleSelect: function (e) { 13060 const base = e.data; 13061 const selectValue = this.value; 13062 const filterValue = base.$input[0].value; 13063 base.$items.each(function (i, item) { 13064 const $item = $(item); 13065 13066 if (base.passesSelectCheck($item, selectValue) && base.passesFilterCheck($item, filterValue)) { 13067 base.showItem($item); 13068 } else { 13069 base.hideItem($item); 13070 } 13071 13072 base.removeAuralClass($item); 13073 }); 13074 13075 base.updateDisplay(filterValue); 13076 }, 13077 13078 passesSelectCheck: function ($item, selectValue) { 13079 const base = this; 13080 return !selectValue || selectValue === 'default' || !$item.attr(base.options.attributes.dataDocumentCategory) || $item.attr(base.options.attributes.dataDocumentCategory).toLowerCase() === selectValue.toLowerCase(); 13081 }, 13082 13083 updateDisplay: function (inputValue) { 13084 const base = this; 13085 const hasDisplayElements = !!base.$resultCount.length; 13086 if (hasDisplayElements) { 13087 const $clone = base.$resultCount.clone(false); 13088 $clone.find(base.options.selectors.displayCount).text(base.$items.filter('.' + base.options.classes.show).length); 13089 $clone.find(base.options.selectors.displayTerm).text(inputValue); 13090 base.$resultCount.html($clone.html()); 13091 } 13092 }, 13093 13094 filterResultList: function (inputValue, selectValue) { 13095 const base = this; 13096 base.$items.each(function (i, item) { 13097 const $item = $(item); 13098 base.filterItem($item, inputValue, selectValue); 13099 }); 13100 }, 13101 13102 filterItem: function ($item, inputValue, selectValue) { 13103 const base = this; 13104 if (base.passesFilterCheck($item, inputValue) && base.passesSelectCheck($item, selectValue)) { 13105 base.showItem($item); 13106 } else { 13107 base.hideItem($item); 13108 } 13109 base.removeAuralClass($item); 13110 }, 13111 13112 passesFilterCheck: function ($item, inputValue) { 13113 const base = this; 13114 const filterTerms = $item.attr(base.options.attributes.dataFilterTerms).split(','); 13115 return !!filterTerms.filter(function (filterTerm) { 13116 return filterTerm.toLowerCase().includes(inputValue.toLowerCase()); 13117 }).length; 13118 }, 13119 13120 showItem: function ($item) { 13121 const base = this; 13122 $item.removeClass(base.options.classes.hide); 13123 $item.addClass(base.options.classes.show); 13124 }, 13125 13126 hideItem: function ($item) { 13127 const base = this; 13128 $item.removeClass(base.options.classes.show); 13129 $item.addClass(base.options.classes.hide); 13130 }, 13131 13132 removeAuralClass: function ($item) { 13133 // the lazy-showing mechanism in the init.js uses an 'aural' class for showing items and hiding items 13134 // to avoid the items we want to show we need to remove the oral class from the items we need to show 13135 // if the filter shows items that are after items that are yet hidden by the lazy-showing mechanism, the lazy-loading breaks with the current implementation 13136 // therefore it is easiest to remove the lazy-showing 'aural' class and show all results once a filter value has been used 13137 $item.removeClass('aural'); 13138 }, 13139 13140 allInstances: { 13141 instCount: 0 13142 }, 13143 13144 defaultOptions: { 13145 attributes: { 13146 dataFilterTerms: 'data-result-list-filter-terms', 13147 dataDocumentCategory: 'data-result-list-filter-document-category' 13148 }, 13149 classes: {
13150 show: 'is-shown', 13151 hide: 'is-hidden' 13152 }, 13153 selectors: { 13154 item: '.js-result-list-filter-item', 13155 input: '.js-result-list-filter-input', 13156 resultCount: '.js-result-list-filter-display', 13157 displayCount: '.js-result-list-filter-display-count', 13158 displayTerm: '.js-result-list-filter-display-term', 13159 select: '.js-result-list-filter-select', 13160 inputClearButton: '.js-result-list-input-clear' 13161 } 13162 13163 } 13164}); 13165 13166 /* Ende cms_filter_list */ 13167 /* Start cms_flip_card */ 13168 /*! --GSBDocStart 13169 * @name: @cms/cms_flip_card 13170 * @version: 3.0.0 13171 * @description: A module that handles focus and toggle for flip card components. 13172 * --CMSDocEnd 13173*/"use strict"; 13174cms.makeCMSModule('cms.flip_card', { 13175 init: function () { 13176 const base = this; 13177 base.allInstances.instCount++; 13178 base.instNS = '.inst' + base.allInstances.instCount + base.eventName; 13179 base.$back = base.$el.find(base.options.selectors.back); 13180 base.$buttons = base.$el.find(base.options.selectors.buttons); 13181 base.$front = base.$el.find(base.options.selectors.front); 13182 13183 base.backupTabindexIfNecessary(base.$front.add(base.$back)); 13184 base.setActive('front'); 13185 13186 base.$buttons.on('click', base, base.toggleCard); 13187 }, 13188 13189 setActive: function (str) { 13190 const base = this; 13191 13192 if (str === 'front') { 13193 base.$front.attr({ 13194 'aria-hidden': false, 13195 'tabindex': 0 13196 }); 13197 base.$back.attr({ 13198 'aria-hidden': true, 13199 'tabindex': -1 13200 }); 13201 13202 base.restoreTabindex(base.$front); 13203 // base.getFocusables(base.$front).attr('tabindex', 0); 13204 13205 base.backupTabindexIfNecessary(base.$back); 13206 base.getFocusables(base.$back).attr('tabindex', -1); 13207 } else if (str === 'back') { 13208 base.$back.attr({ 13209 'aria-hidden': false, 13210 'tabindex': 0 13211 }); 13212 base.$front.attr({ 13213 'aria-hidden': true, 13214 'tabindex': -1 13215 }); 13216 13217 base.restoreTabindex(base.$back); 13218 // base.getFocusables(base.$back).attr('tabindex', 0); 13219 13220 base.backupTabindexIfNecessary(base.$front); 13221 base.getFocusables(base.$front).attr('tabindex', -1); 13222 } 13223 }, 13224 13225 backupTabindexIfNecessary($container) { 13226 const base = this; 13227 const backupAttr = base.options.attributes.tabindexBackup; 13228 const $focusables = base.getFocusables($container); 13229 13230 $focusables.each((i, el) => { 13231 const $el = $(el); 13232 const isNecessary = $el.attr(backupAttr) === undefined; 13233 if (isNecessary) { 13234 $el.attr(backupAttr, $el.attr('tabindex') || ''); 13235 } 13236 }); 13237 }, 13238 13239 restoreTabindex($container) { 13240 const base = this; 13241 const backupAttr = base.options.attributes.tabindexBackup; 13242 const $focusables = base.getFocusables($container); 13243 13244 $focusables.each((i, el) => { 13245 const $el = $(el); 13246 const backupValue = $el.attr(backupAttr); 13247 if (backupValue === '') { 13248 $el.removeAttr('tabindex'); 13249 } else if (backupValue !== undefined) { 13250 $el.attr('tabindex', backupValue); 13251 } 13252 }); 13253 }, 13254 13255 getFocusables($container) { 13256 const base = this; 13257 const focusableOptions = base.options.selectors.focusable; 13258 let $focusables = $(); 13259 13260 if (focusableOptions && focusableOptions.forEach) { 13261 focusableOptions.forEach((selector) => { 13262 $focusables = $focusables.add($container.find(selector)); 13263 }); 13264 } 13265 13266 return $focusables; 13267 }, 13268 13269 toggleCard: function (event) { 13270 const base = event.data; 13271 13272 base.$el.toggleClass(base.options.classes.flipped); 13273 13274 if (!base.$el.hasClass(base.options.classes.flipped)) { 13275 base.setActive('front'); 13276 base.$front.focus(); 13277 } else { 13278 base.setActive('back'); 13279 base.$back.focus(); 13280 } 13281 }, 13282 13283 allInstances: { 13284 instCount: 0 13285 }, 13286 13287 defaultOptions: { 13288 attributes: { 13289 tabindexBackup: 'data-tabindex' 13290 }, 13291 classes: { 13292 flipped: 'is-flipped' 13293 }, 13294 selectors: { 13295 back: '.js-flip-card-back', 13296 buttons: '.js-flip-card-button', //Buttons that shall activate the flip toggle. 13297 front: '.js-flip-card-front', 13298 // Selectors for elements within the front and back side of the card of which this module should make sure they are not 13299 // focusable and tabbable after flipping. 13300 focusable: [ 13301 '[tabindex]', 13302 'a[href]', 13303 'audio', 13304 'button', 13305 'input', 13306 'select', 13307 'textarea', 13308 'video'] 13309 13310 } 13311 } 13312}); 13313 13314 /* Ende cms_flip_card */ 13315 /* Start cms_responsivetables */ 13316 /*! --GSBDocStart 13317 * @name: @cms/cms_responsivetables 13318 * @version: 7.0.0 13319 * @description: CMS-Plugin zum Wrappen von Tabellen fuer die mobile Darstellung 13320 * --CMSDocEnd 13321*/"use strict"; 13322cms.makeCMSModule('cms.responsiveTables', { 13323 init: function () { 13324 const base = this; 13325 13326 base.responsiveTables = base.$el.find('table').map(function () { 13327 const $table = $(this).wrap('<div class="' + base.options.classes.responsiveTable + '"></div>'); 13328 const $respTable = $table.parent(); 13329 if (base.options.way === 'scroll') { 13330 $respTable.wrap('<div class="' + base.options.classes.responsiveTableWrapper + '"></div>'); 13331 const $respWrapper = $respTable.parent(); 13332 $respTable.on('scroll.responsivetables.cms', base, base.handleScroll); // adding scroll listener to responsiveTable 13333 base.initClasses($respWrapper, $table, base.options.copyClassesFromTableToWrapper); 13334 } 13335 base.initClasses($respTable, $table, base.options.copyClassesFromTableToInnerDiv); 13336 return $respTable[0]; 13337 }); 13338 base.lastResize = Date.now() - base.options.throttle; 13339 base.onResize(); 13340 $(window).on('resize', base, base.onResize); 13341 }, 13342 13343 initClasses: function ($element, $table, option) { 13344 if (option) { 13345 if (option.include) { 13346 $element.addClass(option.include); 13347 } 13348 if (option.inherit) { 13349 $element.addClass($table.attr('class')); 13350 } 13351 if (option.exclude) { 13352 $element.removeClass(option.exclude); 13353 } 13354 } 13355 }, 13356 13357 onResize: function (ev) { 13358 const base = ev ? ev.data : this; 13359 if (Date.now() >= base.lastResize + base.options.throttle) { 13360 base.responsiveTables.trigger('scroll.responsivetables.cms'); 13361 base.lastResize = Date.now(); 13362 } 13363 }, 13364 13365 // adds classes to <div class="responsiveTableWrapper"></div> 13366 handleScroll: function (ev) { 13367 const base = ev.data; 13368 const respElem = this; 13369 const $respWrapper = $(respElem).parent(); 13370 const scrollRight = respElem.scrollWidth - respElem.clientWidth - respElem.scrollLeft; 13371 if (respElem.scrollLeft > 0) { 13372 $respWrapper.addClass(base.options.classes.scrollLeft); 13373 } else { 13374 $respWrapper.removeClass(base.options.classes.scrollLeft); 13375 } 13376 if (scrollRight > 0) { 13377 $respWrapper.addClass(base.options.classes.scrollRight); 13378 } else { 13379 $respWrapper.removeClass(base.options.classes.scrollRight); 13380 } 13381 }, 13382 13383 defaultOptions: { 13384 way: 'scroll', 13385 throttle: 50, 13386 copyClassesFromTableToInnerDiv: { 13387 exclude: '', 13388 include: '', 13389 inherit: false 13390 }, 13391 copyClassesFromTableToWrapper: { 13392 exclude: '', 13393 include: '', 13394 inherit: false 13395 }, 13396 classes: { 13397 scrollLeft: 'is-scroll-left', 13398 scrollRight: 'is-scroll-right', 13399 responsiveTable: 'l-responsive-table__inner', 13400 responsiveTableWrapper: 'l-responsive-table' 13401 } 13402 } 13403}); 13404 13405 /* Ende cms_responsivetables */ 13406 /* Start cms_scroll_control */ 13407 /*! --GSBDocStart 13408 * @name: @cms/cms_scroll_control 13409 * @version: 2.0.0 13410 * @description: A module that handles scrolling for anchor-links on click and on pageload 13411 * --CMSDocEnd 13412*/"use strict"; 13413cms.makeCMSModule('cms.scroll_control', { 13414 13415 init: function () { 13416 const base = this; 13417 if (base.options.scrollOnPageLoad) { 13418 base.scrollOnPageLoad(); 13419 } 13420 if (base.options.scrollOnAnchorLinkClick) { 13421 base.$el.find(base.options.selectors.anchorLinks).on('click', base, base.scrollOnAnchorLinkClick); 13422 } 13423 }, 13424 13425 /** 13426 * Function that triggers on page load and scrolls to the element with the id given in the link, if the url contains 13427 * an element id. 13428 **/ 13429 scrollOnPageLoad: function () { 13430 const base = this; 13431 if (window.location.hash) { 13432 const $elementToScrollTo = $('#' + $.escapeSelector(window.location.hash.substring(1))).not(base.options.selectors.excludeFromScrollOnPageLoad); 13433 if ($elementToScrollTo.length) { 13434 if (history.scrollRestoration) { 13435 history.scrollRestoration = 'manual'; 13436 } 13437 setTimeout(function () { 13438 base.animatedScroll($elementToScrollTo); 13439 }, 13440 // if cookiebanner is visible 13441 $(base.options.selectors.cookiebanner).is(':visible') ? base.options.cookiebannerAnimationDuration + 50 : 0); 13442 } 13443 } 13444 }, 13445 13446 /** 13447 * Function that that is registered to the click event of selected anchor-links. 13448 * 13449 * @param {event} e - Event that is fired on click of an anchor link. 13450 * 13451 **/ 13452 scrollOnAnchorLinkClick: function (e) { 13453 const base = e.data; 13454 if (this.origin === window.location.origin && this.pathname === window.location.pathname && this.search === window.location.search) { 13455 e.preventDefault(); 13456 const hash = $(e.currentTarget).attr('href'); 13457 history.pushState({}, '', hash); 13458 const id = hash.substring(hash.indexOf('#')); 13459 const $elementToScrollTo = $(id.replaceAll('.', '\\.')); 13460 base.animatedScroll($elementToScrollTo); 13461 } 13462 }, 13463 13464 /** 13465 * Calculates the height of all overlays, adds them and returns the result. 13466 * 13467 * @return {number} height - Height of overlays in pixel. 13468 * 13469 **/ 13470 getOverlaysHeight: function () { 13471 const base = this; 13472 let height = 0; 13473 $(base.options.selectors.overlays).each(function (index, element) { 13474 height = height + $(element).outerHeight(true); 13475 }); 13476 return height; 13477 }, 13478 13479 /** 13480 * Scrolls to the Element $elementToScrollTo including the given offset in options.scrollOffset 13481 * 13482 * @param {object} $target - Element that should be scrolled into view. 13483 * 13484 **/ 13485 animatedScroll: function ($elementToScrollTo) { 13486 const base = this; 13487 const scrollOffset = base.options.scrollOffset; 13488 let offset = 0; 13489 13490 if (typeof scrollOffset === 'number') { 13491 offset = scrollOffset || 0; 13492 } else if (typeof scrollOffset === 'function') { 13493 offset = scrollOffset.call(base, $elementToScrollTo) || 0; 13494 } 13495 13496 if ($elementToScrollTo.length > 0) { 13497 base.$el.css('scroll-behavior', 'auto'); // jquery animiertes Scrollen funktioniert nicht korrekt mit scroll-behavior: 'smooth' 13498 let overlaysHeight = base.getOverlaysHeight() + offset; 13499 base.$el.clearQueue().stop().animate({ 13500 scrollTop: $elementToScrollTo.offset().top - overlaysHeight 13501 }, base.options.scrollAnimationDuration, 'linear', 13502 13503 function () {//erster Callback nach erster Scroll Animation 13504 // ensure that the last scroll event (used by e.g. cms_shrinkheader) from the previous scrolling animation has been fired and the overlaysHeight has been properly updated 13505 requestAnimationFrame(function () { 13506 overlaysHeight = base.getOverlaysHeight() + offset; 13507 base.$el.clearQueue().stop().animate({ 13508 // Rescroll um Overlay Ãnderungen abzufangen 13509 scrollTop: $elementToScrollTo.offset().top - overlaysHeight 13510 }, base.options.scrollAnimationDuration / 2, 'linear', function () { 13511 requestAnimationFrame(function () {// zweiter Callback nach zweiter Scroll Animation 13512 base.$el.css('scroll-behavior', ''); // Scroll Verhalten Manipulation entfernen 13513 if (!$elementToScrollTo.is($('[tabindex]'))) { 13514 $elementToScrollTo.attr('tabindex', -1); // tabindex="-1" hinzufügen um das Element per Javascript fokussierbar zu machen, falls es nicht bereits einen tabindex hat 13515 } 13516 $elementToScrollTo[0].focus({ preventScroll: true }); // nicht per Browser scrollen, da wir bereits mit JavaScript an die korrekte Stelle gescrollt haben 13517 }); 13518 }); 13519 }); 13520 }); 13521 } 13522 }, 13523 13524 defaultOptions: { 13525 cookiebannerAnimationDuration: 1800, // same as gsb_banner animationSpeed 13526 scrollAnimationDuration: 200, 13527 scrollOnPageLoad: true, 13528 scrollOnAnchorLinkClick: true, 13529 scrollOffset: function (referenceElement) { 13530 return 0; 13531 }, 13532 selectors: { 13533 anchorLinks: 'a[href*="#"]:not(.tabs-list a,[href="#"])', 13534 excludeFromScrollOnPageLoad: '.js-accordion-hashControlled .js-accordion-entry', 13535 cookiebanner: '', // use valid selector if the cookiebanner is displayed at the top of the page, positioned relative, pushing the contents down during the animation. 13536 overlays: '.js-header.is-sticky' 13537 } 13538 } 13539}); 13540 13541 /* Ende cms_scroll_control */ 13542 /* Start cms_simple_toggle */ 13543 /*! --GSBDocStart 13544 * @name: @cms/cms_simple_toggle 13545 * @version: 6.0.0 13546 * @description: Vielfältig einsetzbare Ein- und Ausblendefunktion 13547 * --CMSDocEnd 13548*/"use strict"; 13549cms.makeCMSModule('cms.simple_toggle', { 13550 init: function () { 13551 const base = this; 13552 13553 base.closer = $(base.options.closer, base.el); 13554 base.opener = $(base.options.opener, base.el); 13555 base.openerToFocusOnClose = null; 13556 base.items = $(base.options.item, base.el); 13557 base.isOpenInitially = base.opener.hasClass(base.options.activeClass); 13558 base.isOpen = base.isOpenInitially; 13559 base.backupAttributes(); 13560 13561 base.$el.cms_responsiveListener(base); 13562 }, 13563 13564 initialize: function () { 13565 const base = this; 13566 13567 if (!base.options.uninit) { 13568 base.setupOpenerAndItems(); 13569 base.setupEventListeners(); 13570 base.insertCloser(); 13571 } else { 13572 base.uninit(); 13573 } 13574 }, 13575 13576 backupAttributes: function () { 13577 const base = this; 13578 const openerListAttr = typeof base.options.openerListAttr === 'string' ? base.options.openerListAttr : ''; 13579 13580 base.items.each(function (i, el) { 13581 const item = $(el); 13582 item.attr('data-persistent-role', item.attr('role') || ''); 13583 if (openerListAttr) { 13584 item.attr('data-persistent-' + openerListAttr, item.attr(openerListAttr) || ''); 13585 } 13586 }); 13587 13588 base.opener.attr({ 13589 'data-persistent-role': base.opener.attr('role') || '', 13590 'data-persistent-tabindex': base.opener.attr('tabindex') || '',
13591 ['data-persistent-' + base.options.openerStatusAttr]: base.opener.attr(base.options.openerStatusAttr) || '', 13592 ['data-persistent-' + base.options.itemListAttr]: base.opener.attr(base.options.itemListAttr) || '' 13593 }); 13594 }, 13595 13596 restoreAttributes: function () { 13597 const base = this; 13598 const openerListAttr = typeof base.options.openerListAttr === 'string' ? base.options.openerListAttr : ''; 13599 13600 base.items.each(function (i, el) { 13601 const item = $(el); 13602 item.attr('role', item.attr('data-persistent-role') || null); 13603 if (openerListAttr) { 13604 item.attr(openerListAttr, item.attr('data-persistent-' + openerListAttr) || null); 13605 } 13606 }); 13607 13608 base.opener.attr({ 13609 role: base.opener.attr('data-persistent-role') || null, 13610 tabindex: base.opener.attr('data-persistent-tabindex') || null, 13611 [base.options.openerStatusAttr]: base.opener.attr('data-persistent-' + base.options.openerStatusAttr) || null, 13612 'aria-hidden': null, 13613 [base.options.itemListAttr]: base.opener.attr('data-persistent-' + base.options.itemListAttr) || null 13614 }); 13615 }, 13616 13617 setupOpenerAndItems: function () { 13618 const base = this; 13619 const openerListAttr = typeof base.options.openerListAttr === 'string' ? base.options.openerListAttr : ''; 13620 const useAriaLabelledBy = openerListAttr.toLowerCase() === 'aria-labelledby'; 13621 $().add(base.opener).add(base.items).each(function () { 13622 $(this).attr('id', $(this).attr('id') || base.generateID()); 13623 }); 13624 base.items.each(function (i, el) { 13625 const item = $(el); 13626 item.attr('role', item.attr('role') || 'region'); 13627 13628 if (base.isOpen) { 13629 $(this).addClass(base.options.showClass); 13630 $(this).removeClass(base.options.hideClass); 13631 } else { 13632 $(this).addClass(base.options.hideClass); 13633 $(this).removeClass(base.options.showClass); 13634 } 13635 13636 if (!useAriaLabelledBy || !item.attr('aria-label')) { 13637 base.addIdsToAttr(item, openerListAttr, base.opener); 13638 } 13639 }); 13640 13641 if (!base.opener.is('button')) { 13642 base.opener.attr('role', 'button').attr('tabindex', base.opener.attr('tabindex') || 0); 13643 } 13644 base.opener.attr(base.options.openerStatusAttr, base.isOpen); 13645 base.opener.addClass(base.isOpen ? base.options.activeClass : base.options.inactiveClass); 13646 base.items.attr('aria-hidden', !base.isOpen); 13647 base.addIdsToAttr(base.opener, base.options.itemListAttr, base.items); 13648 13649 if (base.opener.length && !$('body').find(base.opener).length) { 13650 base.$el[base.options.openerInsert](base.opener); 13651 } 13652 }, 13653 13654 setupEventListeners: function () { 13655 const base = this; 13656 const namespace = base.eventName; 13657 base.$el.on(`open.${namespace}`, base, base.open); 13658 base.$el.on(`toggle.${namespace}`, base, base.openerHandler); 13659 base.$el.on(`close.${namespace}`, base, base.close); 13660 $().add(base.opener).add(base.closer).add(base.items).on(`keydown.${namespace}`, base, base.escapeHandler); 13661 base.closer.on(`click.${namespace} keydown.${namespace}`, base, base.closerHandler); 13662 base.opener.on(`click.${namespace} keydown.${namespace}`, base, base.openerHandler); 13663 if (base.options.closeOnFocusout) { 13664 base.opener.add(base.items).on(`mousedown.${namespace} focusout.${namespace}`, base, base.focusoutHandler); 13665 } 13666 }, 13667 13668 insertCloser: function () { 13669 const base = this; 13670 if (base.closer.length && !$('body').find(base.closer).length) { 13671 if (base.items.length < 2) { 13672 base.items[base.options.closerInsert](base.closer); 13673 } else if (typeof base.options.closer === 'string') { 13674 base.items[base.options.closerInsert](base.options.closer); 13675 } else { 13676 base.$el[base.options.closerInsert](base.closer); 13677 } 13678 } 13679 }, 13680 13681 addIdsToAttr: function ($elem, attrName, addElems) { 13682 const val = attrName ? $elem.attr(attrName) : ''; 13683 const oldIds = val ? val.trim().split(/\s+/g) : []; 13684 const ids = {}; 13685 if (attrName) { 13686 oldIds.forEach(function (id) { 13687 ids[id] = true; 13688 }); 13689 addElems.each(function () { 13690 ids[$(this).attr('id')] = true; 13691 }); 13692 $elem.attr(attrName, Object.keys(ids).join(' ')); 13693 } 13694 }, 13695 13696 openerHandler: function (ev) { 13697 const base = ev.data; 13698 if (!ev.key || ev.key === 'Spacebar' || ev.key === ' ' || ev.key === 'Enter') { 13699 ev.preventDefault(); 13700 if (base.opener.hasClass(base.options.activeClass)) { 13701 base.close(ev); 13702 } else { 13703 base.open(ev); 13704 if ($(ev.target).is(base.opener)) { 13705 base.openerToFocusOnClose = ev.target; 13706 } 13707 } 13708 } 13709 }, 13710 13711 closerHandler: function (ev) { 13712 const base = ev.data; 13713 if (!ev.key || ev.key === 'Spacebar' || ev.key === ' ' || ev.key === 'Enter') { 13714 ev.preventDefault(); 13715 base.close(ev); 13716 } 13717 }, 13718 13719 focusoutHandler: function (ev) { 13720 const base = ev ? ev.data : this; 13721 if (ev.type === 'mousedown') { 13722 // When the mousedown event occurs a focusout event follows. 13723 // If the mousedown event occurs on a non-focusable element, the new activeElement will be <body> which is outside the $box. 13724 ev.preventDefault(); // Kill all focusout events following the mousedown event to avoid closing the toggle item when mousedowning inside. 13725 // The suppressed possible focus change needs to be handled manually. 13726 const $closestOpener = $(ev.target).closest(base.opener); 13727 if ($closestOpener.length) { 13728 // If the clicked Element is focusable but inside the opener 13729 $closestOpener.trigger('focus'); // Set the focus on the opener 13730 } else { 13731 $(ev.target).trigger('focus'); // Set the focus to the element clicked. 13732 } 13733 // If the clicked element is focusable, it will trigger a focusout event where the new activeElement is inside opened menu. 13734 // This will be handled correctly for the focusout event. 13735 // If the clicked element is not focusable, then the focus will stay where it is and no unwanted focusout event will be triggered. 13736 } else { 13737 setTimeout(function () { 13738 if (!$(document.activeElement).closest(base.items.add(base.opener)).length) { 13739 // new activeElement is not inside the base.items 13740 base.close(null, true); 13741 } 13742 }, 0); 13743 } 13744 }, 13745 13746 escapeHandler: function (ev) { 13747 const base = ev ? ev.data : this; 13748 switch (ev.key) { 13749 case 'Esc': // IE/Edge 13750 case 'Escape': // W3C 13751 ev.preventDefault(); 13752 if (base.$el.find(base.items).hasClass(base.options.showClass)) { 13753 base.close(ev); 13754 } 13755 break; 13756 } 13757 }, 13758 13759 open: function (ev) { 13760 const base = ev ? ev.data : this; 13761 if (ev) { 13762 ev.preventDefault(); 13763 ev.stopPropagation(); 13764 }
13765 if (base.specialTrigger('beforeOpen.simple_toggle.cms', ev)) { 13766 base.isOpen = true; 13767 base.opener. 13768 addClass(base.options.activeClass). 13769 removeClass(base.options.inactiveClass). 13770 attr(base.options.openerStatusAttr, 'true'); 13771 base.items. 13772 addClass(base.options.showClass). 13773 removeClass(base.options.hideClass). 13774 attr('aria-hidden', 'false'); 13775 base.specialTrigger('afterOpen.simple_toggle.cms', ev); 13776 } 13777 }, 13778 13779 close: function (ev, preventFocusingOpener) { 13780 const base = ev ? ev.data : this; 13781 if (ev) { 13782 ev.preventDefault(); 13783 ev.stopPropagation(); 13784 } 13785 if (base.specialTrigger('beforeClose.simple_toggle.cms', ev)) { 13786 base.isOpen = false; 13787 base.opener. 13788 addClass(base.options.inactiveClass). 13789 removeClass(base.options.activeClass). 13790 attr(base.options.openerStatusAttr, 'false'); 13791 base.items. 13792 addClass(base.options.hideClass). 13793 removeClass(base.options.showClass). 13794 attr('aria-hidden', 'true'); 13795 if (base.openerToFocusOnClose) { 13796 if (!preventFocusingOpener) { 13797 $(base.openerToFocusOnClose).trigger('focus'); 13798 } 13799 base.openerToFocusOnClose = null; 13800 } 13801 base.specialTrigger('afterClose.simple_toggle.cms', ev); 13802 } 13803 }, 13804 13805 specialTrigger: function (evStr, ev) { 13806 var base = this, 13807 namespaces = evStr.split('.'), 13808 type = namespaces.shift(), 13809 event; 13810 namespaces = namespaces.sort(); 13811 event = $.Event(type, { 13812 namespace: namespaces.join('.'), 13813 relatedEvent: ev || null 13814 }); 13815 base.$el.trigger(event, base); 13816 return !event.isDefaultPrevented(); 13817 }, 13818 13819 uninit: function () { 13820 const base = this; 13821 13822 base.isOpen = base.isOpenInitially; 13823 13824 base.restoreAttributes(); 13825 13826 base.items. 13827 removeClass(base.options.hideClass). 13828 removeClass(base.options.showClass); 13829 13830 base.opener. 13831 removeClass(base.options.activeClass). 13832 removeClass(base.options.inactiveClass); 13833 13834 const apiEvents = ['open', 'toggle', 'close']; 13835 base.$el.off(apiEvents.map((s) => s + '.' + base.eventName).join(' ')); 13836 13837 const nativeEvents = ['click', 'mousedown', 'keydown', 'focusout']; 13838 const nativeEventsStr = nativeEvents.map((s) => s + '.' + base.eventName).join(' '); 13839 base.opener.off(nativeEventsStr); 13840 base.items.off(nativeEventsStr); 13841 base.closer.off(nativeEventsStr); 13842 }, 13843 13844 defaultOptions: { 13845 uninit: false, 13846 item: '.js-simple-toggle-item', 13847 openerListAttr: 'aria-labelledby', 13848 showClass: 'is-shown', 13849 hideClass: 'is-hidden', 13850 opener: '.js-simple-toggle-opener', 13851 openerInsert: 'prepend', 13852 openerStatusAttr: 'aria-expanded', 13853 itemListAttr: 'aria-controls', 13854 activeClass: 'active-control', 13855 inactiveClass: 'inactive-control', 13856 closer: '.js-simple-toggle-closer', //can also be html 13857 closerInsert: 'append', 13858 closeOnFocusout: false, 13859 respondToEvents: true, 13860 onRefresh: function () { 13861 this.initialize(); 13862 } 13863 } 13864}); 13865 13866 /* Ende cms_simple_toggle */ 13867 /* Start cms_slideshow_numbers */ 13868 /*! --GSBDocStart 13869 * @name: @cms/cms_slideshow_numbers 13870 * @version: 3.0.0 13871 * @description: Wrapper-Plugin für slick.js mit BITV-Anpassungen optimiert zur Ausgabe der aktuellen "Seite" 13872 * --CMSDocEnd 13873*/"use strict"; 13874cms.makeCMSModule('cms.slideshow_numbers', { 13875 13876 init: function () { 13877 const base = this; 13878 base.prepareReInitEventNamespace(); 13879 const allElementsUrl = base.$el.data('href'); 13880 if (allElementsUrl) { 13881 // Slides über XHR 13882 base.loadSlidesAndInitSlick(allElementsUrl); 13883 } else { 13884 // Slides im DOM 13885 if (base.hasEnoughSlides()) { 13886 base.addPlaceholderSlidesIfNecessary(); 13887 base.backupAttributes(); 13888 base.initSlick(); 13889 } else { 13890 base.afterInit(); 13891 } 13892 } 13893 }, 13894 13895 prepareReInitEventNamespace: function () { 13896 const base = this; 13897 const selector = base.$el.attr('class').replace(/(^ *| +)/g, '.'); 13898 const instanceIndex = $(selector).index(base.$el); 13899 base.reInitEventNamespace = selector + '-' + instanceIndex; 13900 }, 13901 13902 addPlaceholderSlidesIfNecessary: function () { 13903 const base = this, 13904 slickOptions = base.options.slickOptions, 13905 breakpoints = slickOptions && slickOptions.responsive; 13906 13907 var $slider = base.$el, 13908 slidesToScroll, 13909 slidesToShow; 13910
13911 // Finde den aktuellen Breakpoint 13912 const currentBreakpointValue = Math.max.apply(null, breakpoints.map((e) => { 13913 if (!slickOptions.mobileFirst) { 13914 return $(window).width() < e.breakpoint ? e.breakpoint : 0; 13915 } else { 13916 return $(window).width() > e.breakpoint ? e.breakpoint : 0; 13917 } 13918 })); 13919 13920 const currentBreakpoint = breakpoints.find((e) => e.breakpoint === currentBreakpointValue); 13921 13922 if (typeof currentBreakpoint !== 'undefined') { 13923 slidesToScroll = currentBreakpoint.settings.slidesToScroll; 13924 slidesToShow = currentBreakpoint.settings.slidesToShow; 13925 } else if (slickOptions.slidesToShow) { 13926 slidesToScroll = slickOptions.slidesToScroll; 13927 slidesToShow = slickOptions.slidesToShow; 13928 } 13929 13930 base.$el.find('.js-slide-placeholder').remove(); 13931 const $slides = $slider.children(base.options.slickOptions.slide); 13932 const slideCount = $slides.length; 13933 13934 if (slideCount > slidesToShow && slidesToScroll > 1) { 13935 let iPlaceholdersToAdd = slidesToShow - (sli
13935deCount - slidesToShow) % slidesToScroll; 13936 if (iPlaceholdersToAdd !== slidesToShow && iPlaceholdersToAdd > 0) { 13937 base.addPlaceholderSlides(iPlaceholdersToAdd); 13938 } 13939 } 13940 }, 13941 13942 addPlaceholderSlides: function (iPlaceholdersToAdd) { 13943 const base = this; 13944 for (let i = 0; i < iPlaceholdersToAdd; i++) { 13945 base.$el.append('<div class="js-slide js-slide-placeholder">'); 13946 } 13947 }, 13948 13949 hasEnoughSlides: function () { 13950 const base = this, 13951 slickOptions = base.options.slickOptions, 13952 breakpoints = slickOptions && slickOptions.responsive; 13953 // Wenn breakpointabhängige Ãberprüfung angefordert ist 13954 if (!base.options.initIfNotEnoughSlides && breakpoints) { 13955 // Finde den aktuellen Breakpoint 13956 const currentBreakpointValue = Math.max.apply(null, breakpoints.map((e) => { 13957 if (!slickOptions.mobileFirst) { 13958 return $(window).width() < e.breakpoint ? e.breakpoint : 0; 13959 } else { 13960 return $(window).width() > e.breakpoint ? e.breakpoint : 0; 13961 } 13962 })); 13963 13964 const currentBreakpoint = breakpoints.find((e) => e.breakpoint === currentBreakpointValue); 13965 13966 if (typeof currentBreakpoint !== 'undefined') { 13967 return base.$el.children().length > currentBreakpoint.settings.slidesToShow; 13968 } else if (slickOptions.slidesToShow) { 13969 return base.$el.children().length > slickOptions.slidesToShow; 13970 } 13971 } 13972 return base.$el.children().length > 1; 13973 }, 13974 13975 13976 /** 13977 * Lädt die anzuzeigenen Slides per XHR aus dem CMS-Content, fügt diese als Children des base.el ein und initialisiert dann slick. 13978 * @param allElementsUrl 13979 */ 13980 loadSlidesAndInitSlick: function (allElementsUrl) { 13981 const base = this; 13982 $.ajax({ 13983 url: allElementsUrl, 13984 context: base, 13985 success: base.onReceiveAllElements 13986 }); 13987 13988 }, 13989 13990 onReceiveAllElements: function (data) { 13991 const base = this; 13992 base.$el.html(data); 13993 if (base.hasEnoughSlides()) { 13994 base.addPlaceholderSlidesIfNecessary(); 13995 base.initSlick(); 13996 } else { 13997 base.afterInit(); 13998 } 13999 }, 14000 14001 afterInit: function () { 14002 const base = this; 14003 base.$el. 14004 addClass(base.options.classes.initialized). 14005 trigger('init.' + base.eventName, base); 14006 }, 14007 14008 initSlick: function () { 14009 const base = this; 14010 let slickOptions = base.options.slickOptions; 14011 slickOptions = base.handleNavigationArrows(slickOptions); 14012 slickOptions = base.handleNavigationDots(slickOptions); 14013 base.$el.on('beforeChange.slick', base, base.onSlickBeforeChange).unbind('afterChange.slick').on('afterChange.slick', base, base.onSlickAfterChange).unbind('init.slick').on('init.slick', base, base.onSlickInit).unbind('breakpoint.slick').on('breakpoint.slick', base, base.onSlickBreakpoint).unbind('destroy.slick').on('destroy.slick', base, base.onSlickDestroy); 14014 base.slick = base.$el.slick(slickOptions).slick('getSlick'); 14015 base.patchSlickHeightAnimation(); 14016 base.patchSlickGetLeft(); 14017 }, 14018 14019 14020 /** 14021 * Sorgt für eine bessere Animation der Höhe, wenn adaptiveHeight true gesetzt ist. 14022 */ 14023 patchSlickHeightAnimation: function () {//monkey-patch height anim in case slidesToShow > 1 14024 const base = this; 14025 $.extend(base.slick, { 14026 getActiveSlidesHeight: function () { 14027 let _ = this; 14028 if (base.options.isNavigationSlideshow) { 14029 _.recalculateActiveSlidesForNavigationSlideshow(); 14030 } 14031 let activeSlides = _.$slides.filter('.slick-active'); 14032 return Math.max(...activeSlides.map((i, el) => $(el).outerHeight())); 14033 }, 14034 recalculateActiveSlidesForNavigationSlideshow: function () { 14035 let _ = this, 14036 activeSlides = _.$slides.filter('.slick-active'); 14037 if (activeSlides.length < _.options.slidesToShow) { 14038 _.$slides.slice(-_.options.slidesToShow).addClass('slick-active'); 14039 } 14040 }, 14041 animateHeight: function () { 14042 let _ = this; 14043 if (_.options.adaptiveHeight === true && _.options.vertical === false) { 14044 _.$list.animate({ 14045 height: _.getActiveSlidesHeight() 14046 }, _.options.speed); 14047 } 14048 }, 14049 setHeight: function () { 14050 let _ = this; 14051 if (_.options.adaptiveHeight === true && _.options.vertical === false) { 14052 _.$list.css('height', _.getActiveSlidesHeight()); 14053 } 14054 } 14055 }); 14056 14057 }, 14058 14059 /** 14060 * Verhindert das "Verschwinden" von Slides, falls slideCount <= slidesToShow 14061 */ 14062 patchSlickGetLeft: function () {//monkey-patch getLeft in case slideCount <= slidesToShow 14063 const base = this, 14064 originalGetLeft = base.slick.getLeft; 14065 $.extend(base.slick, { 14066 getLeft: function () { 14067 let _ = this; 14068 if (_.slideCount <= _.options.slidesToShow) { 14069 return 0; 14070 } else { 14071 return originalGetLeft.apply(base.slick, arguments); 14072 } 14073 } 14074 }); 14075 14076 }, 14077 14078 patchSlickAccessibility: function (slick) { 14079 const base = this; 14080 base.slick = slick; 14081 14082 $.extend(base.slick, { 14083 initADA: function () { 14084 var _ = this; 14085 const numDotGroups = _.options.infinite ? Math.ceil(_.slideCount / _.options.slidesToScroll) : Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll) + 1;
14086 var tabControlIndexes = _.getNavigableIndexes().filter(function (val) { 14087 return val >= 0 && val < _.slideCount; 14088 }); 14089 14090 _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({ 14091 'aria-hidden': 'true' 14092 }); 14093 14094 if (_.$dots !== null) { 14095 _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function (i) { 14096 var slideControlIndex = tabControlIndexes.indexOf(i); 14097 var ariaAttributeName; 14098 14099 $(this).attr({ 14100 'role': 'tabpanel', 14101 'id': 'slick-slide' + _.instanceUid + i 14102 }); 14103 14104 14105 if (slideControlIndex !== -1) { 14106 ariaAttributeName = _.options.slidesToShow > 1 ? 'aria-labelledby' : 'aria-describedby'; 14107 $(this).removeAttr('aria-describedby'); 14108 $(this).attr(ariaAttributeName, 'slick-slide-control' + _.instanceUid + slideControlIndex); 14109 } 14110 }); 14111 14112 _.$dots.attr('aria-label', base.options.tablistAriaLabel).attr('role', 'tablist').find('li').each(function (i) { 14113 var mappedSlideIndex = tabControlIndexes[i]; 14114 14115 $(this).attr({ 14116 'role': 'presentation' 14117 }); 14118 14119 14120 $(this).find('button').first().attr({ 14121 'role': 'tab', 14122 'id': 'slick-slide-control' + _.instanceUid + i, 14123 'aria-controls': 'slick-slide' + _.instanceUid + mappedSlideIndex, 14124 'aria-label': i + 1 + ' / ' + numDotGroups, 14125 'aria-current': 'false', 14126 'tabindex': '-1' 14127 }); 14128 14129 }).eq(Math.ceil(_.currentSlide / _.options.slidesToScroll)).find('button').attr({ 14130 'aria-current': 'true', 14131 'tabindex': '0' 14132 }).end(); 14133 } 14134 14135 _.activateADA(); 14136 14137 base.accessible(); 14138 }, 14139 activateADA: function () { 14140 let _ = this; 14141 const focusable = base.options.selectors.focusable; 14142 const $activeSlides = _.$slideTrack.find('.slick-active, .slick-current'); 14143 $activeSlides.attr({ 'aria-hidden': 'false' }); 14144 $.each($activeSlides.find(focusable).not('[disabled]').not('[aria-disabled=\'true\']'), (i, e) => { 14145 $(e).attr('tabindex', !!$(e).data('tabindex-persistent') ? $(e).data('tabindex-persistent') : 0); 14146 }); 14147 } 14148 }); 14149 14150 14151 base.removeTabIndexFromSlides(); 14152 base.removeAriaSelectedFromDots(); 14153 }, 14154 14155 /** 14156 * Versteckt oder zeigt die Navigation an, abhängig davon, ob es ausreichend Slides für eine Slideshow gibt. 14157 * @param slick das Slick-Objekt 14158 */ 14159 showHideNavigation: function (slick) { 14160 const base = this; 14161 const numOfChildren = base.$el.find('.slick-slide').length || base.$el.children().not(base.options.navigation.selector).length; 14162 if (!slick.unslicked && slick.options.slidesToShow < numOfChildren) { 14163 base.$el.find(base.options.navigation.selector).show(); 14164 base.$el.addClass(base.options.classes.hasNavigation); 14165 } else { 14166 base.$el.find(base.options.navigation.selector).hide(); 14167 base.$el.removeClass(base.options.classes.hasNavigation); 14168 } 14169 }, 14170 14171 /** 14172 * Initialisiert das "cms_multimedia"-Modul, falls es in den Slides <video> oder <audio> Elemente gibt. 14173 */ 14174 initMultimedia: function () { 14175 const base = this; 14176 cms.requireCMSComponent('bundle_multimedia', base.$el.find('audio, video')). 14177 done(function ($media) { 14178 $media.cms_multimedia(base.options.multimediaOptions); 14179 // base.$el.find('.js-embed-youtube').cms_embed_youtube(); 14180 }); 14181 }, 14182 14183 handlePlayButton: function () { 14184 const base = this; 14185 const ops = base.options.navigation.autoplay; 14186 14187 if (base.options.slickOptions.autoplay && ops.createPlayButton) { 14188 let $parent = base.$el.find(base.options.navigation.selector); 14189 base.$playButton = $parent.find(ops.playButtonSelector); 14190 base.togglePlayButtonAttributes('paused', 'playing'); 14191 14192 base.$playButton. 14193 on('click ', base, base.togglePlayButtonState). 14194 on('focusin focusout', (e) => e.stopPropagation()); 14195 $parent.find('button').not(ops.playButtonSelector). 14196 on('focus', base, base.togglePlayButtonState); 14197 14198 base.$playButton.parent().removeAttr('hidden'); 14199 } else { 14200 let $parent = base.$el.find(base.options.navigation.selector); 14201 base.$playButton = $parent.find(ops.playButtonSelector); 14202 base.$playButton.remove(); 14203 } 14204 }, 14205 14206 togglePlayButtonState: function (ev) { 14207 const base = ev.data; 14208 const $playButton = base.$playButton; 14209 const state = $playButton.is('.playbutton-playing') || ev.type === 'focus' ? 'playing' : 'paused'; 14210 const targetState = state === 'playing' ? 'paused' : 'playing'; 14211 const $pagination = base.$el.find(base.options.pagination.selector); 14212 14213 base.togglePlayButtonAttributes(state, targetState); 14214 base.$el.slick(targetState === 'playing' ? 'slickPlay' : 'slickPause'); 14215 $pagination.attr('aria-live', !base.slick.paused ? 'off' : null); 14216 }, 14217 14218 togglePlayButtonAttributes: function (state, targetState) { 14219 const base = this; 14220 const ops = base.options.navigation.autoplay; 14221 const $playButton = base.$playButton; 14222 14223 $playButton. 14224 removeClass('playbutton-' + state). 14225 addClass('playbutton-' + targetState). 14226 attr('aria-label', ops[targetState].title). 14227 attr('title', ops[targetState].title); 14228 $playButton.find('img'). 14229 attr('src', ops[targetState].symbol). 14230 attr('alt', ops[targetState].title); 14231 }, 14232 14233 /** 14234 * Setzt den Tabindex von antabbaren Elementen auf nicht sichtbaren Slides auf -1, damit diese nicht angetabbt werden können. 14235 * @param slick das Slick-Objekt 14236 */ 14237 updateTabindex: function (slick) { 14238 const base = this; 14239 //Barrierefreiheit/Tabbing workaround 14240 const focusableItems = base.options.selectors.focusable; 14241 const buggedItems = base.options.selectors.bugged; 14242 if (!slick.unslicked) { 14243 slick.$slides.not('.slick-active').find(focusableItems).attr('tabindex', -1).end().find(buggedItems).hide(); 14244 slick.$slides.filter('.slick-active').find(focusableItems).attr('tabindex', 0).end().find(buggedItems).show(); 14245 } 14246 }, 14247 14248 14249 /** 14250 * Initialisiert die Paginierung 14251 * @param slick das Slick-Objekt 14252 */ 14253 updatePagination: function (slick, currentSlide) { 14254 const base = this; 14255 if (base.$el.find(base.options.pagination.selector)) { 14256 const $pagination = base.$el.find(base.options.pagination.selector); 14257 14258 $pagination. 14259 attr('role', 'status'). 14260 attr('aria-atomic', true). 14261 attr('aria-live', !base.slick.paused ? 'off' : null); 14262 14263 $pagination.empty(); 14264 const currentPage = (Math.floor(currentSlide / slick.options.slidesToScroll) + 1).toLocaleStr
14264ing(base.options.pagination.toLocaleStringLanguage, base.options.pagination.toLocaleStringOptions); 14265 const lastPage = (Math.ceil(slick.$slides.length / slick.options.slidesToScroll) - (slick.options.slidesToShow - slick.options.slidesToScroll)).toLocaleString(base.options.pagination.toLocaleStringLanguage, base.options.pagination.toLocaleStringOptions); 14266 if ($pagination.attr('data-wrapper-index')) { 14267 $pagination.append($($pagination.attr('data-wrapper-index')).html(currentPage)); 14268 } else { 14269 $pagination.append(' ' + currentPage + ' '); 14270 } 14271 $pagination.append($($pagination.attr('data-separator'))); 14272 if ($pagination.attr('data-wrapper-index')) { 14273 $pagination.append($($pagination.attr('data-wrapper-total')).html(lastPage)); 14274 } else { 14275 $pagination.append(' ' + lastPage + ' '); 14276 } 14277 } 14278 }, 14279 14280 /** 14281 * Setzt bzw. entfernt disabled und aria-disabled an die Arrows. 14282 * @param $arrow Selektor des Arrows 14283 */ 14284 updateNavigationArrow: function ($arrow) { 14285 if ($arrow) { 14286 var $arrowButton = $arrow.is('button') ? $arrow : $arrow.find('button'); 14287 if ($arrow.hasClass('slick-disabled')) { 14288 $arrowButton.prop('disabled', true); 14289 } else { 14290 $arrowButton.removeAttr('disabled'); 14291 } 14292 $arrow.removeAttr('aria-disabled'); // wird von Slick automatisch gesetzt, aber für uns nicht notwendig, also wird es wieder entfernt um den DOM möglichst sauber zu halten 14293 } 14294 }, 14295 14296 /** 14297 * Workaround für slider die mit einem anderen Slider durch 'asNavFor' kombiniert werden, und mit slidesToShow > 1 konfiguriert sind 14298 */ 14299 updateNavigationArrowBySlideCount: function ($arrow, setDisabledPredicate) { 14300 if ($arrow) { 14301 const $arrowButton = $arrow.is('button') ? $arrow : $arrow.find('button'); 14302 if (setDisabledPredicate) { 14303 $arrowButton.prop('disabled', true); 14304 } else { 14305 $arrowButton.removeAttr('disabled').removeClass('slick-disabled'); 14306 } 14307 $arrow.removeAttr('aria-disabled'); 14308 } 14309 }, 14310 14311 /** 14312 * Führt Manipulationen an den HTML-Attributen der Navigation durch, die für die Barrierefreiheit relevant sind. 14313 * @param slick das Slick-Objekt 14314 */ 14315 updateNavigation: function (slick) { 14316 const base = this; 14317 if (base.options.isNavigationSlideshow) { 14318 base.updateNavigationArrowBySlideCount(slick.$prevArrow, slick.currentSlide === 0); 14319 base.updateNavigationArrowBySlideCount(slick.$nextArrow, slick.currentSlide + 1 === slick.slideCount); 14320 } else { 14321 base.updateNavigationArrow(slick.$prevArrow); 14322 base.updateNavigationArrow(slick.$nextArrow); 14323 } 14324 14325 }, 14326 14327 /** 14328 * Fügt dem Wrapper Klassen hinzu, wenn sich die Slideshow am Anfang oder am Ende befindet. 14329 * @param slick das Slick-Objekt, das Informationen über den Zustand des Karussells enthält 14330 * @param nextSlide gibt an, ob ein folgendes Slide existiert 14331 */ 14332 updateSlideStatus: function (slick, nextSlide) { 14333 const base = this; 14334 const isAtStart = nextSlide === 0; 14335 if (isAtStart) { 14336 base.$el.closest(base.options.selectors.wrapper).find(base.options.selectors.removedContent).addClass(base.options.classes.isAtStart); 14337 } else { 14338 base.$el.closest(base.options.selectors.wrapper).find(base.options.selectors.removedContent).removeClass(base.options.classes.isAtStart); 14339 } 14340 }, 14341 14342 /** 14343 * Initialisiert die Navigationspfeile. Diese dürfen erst nach einem etwaigen Austausch des HTML ermittelt werden, 14344 * da sie ggf. mit ersetzt werden. In diesem Fall würden ansonsten die nachgeladene Pfeile nicht initialisiert. 14345 * @param slickOptions die Optionen, die an Slick übergeben werden 14346 */ 14347 handleNavigationArrows: function (slickOptions) { 14348 const base = this; 14349 var navigationArrowOptions = { 14350 nextArrow: base.$el.find(base.options.navigation.arrows.selectors.next), 14351 prevArrow: base.$el.find(base.options.navigation.arrows.selectors.prev) 14352 }; 14353 14354 return $.extend(slickOptions, navigationArrowOptions); 14355 }, 14356 14357 updateDotFocus: function () { 14358 const base = this; 14359 const dots = base.$el.find('.slick-dots'), 14360 activeDot = dots.find('.slick-active button'),
14361 focusedDot = dots.find('button').filter(document.activeElement); 14362 if (activeDot.length && focusedDot.length && !activeDot.is(focusedDot)) { 14363 activeDot[0].focus(); 14364 } 14365 }, 14366 14367 /** 14368 * Da die Navigation erst durch dieses Modul erstellt und in den DOM eingefügt wird, kann das jQuery-Element, welches der slick-Option 14369 * 'appendDots' übergeben wird, auch erst jetzt gefunden werden. 14370 * Also wird diese Option hier durch das jetzt auffindbare jQuery-Element überschrieben. 14371 * @param slickOptions die Optionen, die an Slick übergeben werden 14372 */ 14373 handleNavigationDots: function (slickOptions) { 14374 const base = this; 14375 slickOptions.appendDots = base.$el.find(base.options.navigation.selector); 14376 return slickOptions; 14377 }, 14378 14379 /** 14380 * non configurable fixes 14381 */ 14382 accessible: function () { 14383 const base = this; 14384 base.accessibilityFix(); 14385 base.cleanUpSlides(); 14386 base.$el.trigger('afterAccessible.' + base.eventName, base); 14387 14388 14389 }, 14390 14391 /** 14392 * Entfernt den tabindex der Slides. 14393 */ 14394 removeTabIndexFromSlides: function () { 14395 const base = this; 14396 base.$el.find('.slick-slide[tabindex]').each(function (index, element) { 14397 $(element).removeAttr('tabindex'); 14398 }); 14399 }, 14400 14401 backupAttributes: function () { 14402 const base = this; 14403 base.$el.find('[role]').addBack().not('[data-role-persistent]') // role auch für base.$el speichern 14404 .each(function (index, element) { 14405 let role = $(element).attr('role') || ''; 14406 $(element).attr('data-role-persistent', role.trim() || null); 14407 }); 14408 base.$el.find('[tabindex]').not('[data-tabindex-persistent]'). 14409 each(function (index, element) { 14410 let tabindex = $(element).attr('tabindex') || ''; 14411 $(element).attr('data-tabindex-persistent', tabindex.trim() || null); 14412 }); 14413 base.$el.find('[aria-live]').not('[data-aria-live-persistent]'). 14414 each(function (index, element) { 14415 let live = $(element).attr('aria-live') || ''; 14416 $(element).attr('data-aria-live-persistent', live.trim() || null); 14417 }); 14418 }, 14419 14420 restoreAttributes: function () { 14421 const base = this; 14422 base.$el.find('[data-role-persistent]').addBack() // role auch für base.$el wiederherstellen 14423 .each(function (index, element) { 14424 $(element).attr('role', $(element).attr('data-role-persistent') || null); 14425 }); 14426 base.$el.find('[data-tabindex-persistent]'). 14427 each(function (index, element) { 14428 $(element).attr('tabindex', $(element).attr('data-tabindex-persistent') || null); 14429 }); 14430 base.$el.find('[data-aria-live-persistent]'). 14431 each(function (index, element) { 14432 $(element).attr('aria-live', $(element).attr('data-aria-live-persistent') || null); 14433 }); 14434 }, 14435 14436 removeAriaSelectedFromDots: function () { 14437 const base = this; 14438 const slickDotsButtons = base.$el.find('.slick-dots').find('button'); 14439 slickDotsButtons.removeAttr('aria-selected'); 14440 }, 14441 14442 /** 14443 * Platziert die Navigation über der .slick-list im DOM. 14444 */ 14445 accessibilityFix: function () { 14446 const base = this; 14447 const slickDotsButtons = base.$el.find('.slick-dots').find('button'); 14448 const focusedDot = slickDotsButtons.filter(':focus'); 14449 const activeDot = slickDotsButtons.filter('.slick-active *'); 14450 14451 if (focusedDot.length) { 14452 if (!focusedDot.is(activeDot)) { 14453 activeDot.trigger('focus'); 14454 } 14455 } 14456 base.fixNavigationDOMPlacement(); 14457 base.updateAriaRoles(); 14458 }, 14459 14460 /** 14461 * Ergänzt am Wrapper-Element die Role list und an den Slides die Role listitem bzw. Role group 14462 */ 14463 updateAriaRoles: function () { 14464 const base = this; 14465 14466 const numOfChildren = base.$el.find('.slick-slide').length || base.$el.children().not(base.options.navigation.selector).length; 14467 if (!base.slick.unslicked && base.slick.options.slidesToShow < numOfChildren) { 14468 base.$el.attr('role', 'group'); 14469 base.$el.attr('aria-live', base.$el.attr('data-aria-live-persistent') || "polite"); 14470 } else { 14471 base.$el.attr('role', base.$el.attr('data-role-persistent') || null); 14472 } 14473 14474 if (base.options.ariaRole === 'list') { 14475 if (base.slick.$slides.length > 1 && base.slick.options.slidesToScroll > 1) { 14476 base.slick.$slideTrack.attr('role', 'list'); 14477 base.$el.find(base.options.slickOptions.slide).not('.js-slide-placeholder').attr('role', 'listitem'); 14478 } else { 14479 base.slick.$slideTrack.removeAttr('role'); 14480 base.$el.find(base.options.slickOptions.slide).not('.js-slide-placeholder').removeAttr('role'); 14481 } 14482 } 14483 base.$el.find('.js-slide-placeholder').attr('aria-hidden', 'true'); 14484 }, 14485 14486 /** 14487 * Platziert das Navigationelement als erstes Kind des base.$el, 14488 * damit die semantische Reihenfolge von Navigation und .slick-list BITV-konform ist. 14489 */ 14490 fixNavigationDOMPlacement: function () { 14491 const base = this; 14492 let $navigation = base.$el.find(base.options.navigation.selector); 14493 if ($navigation.length === 0) { 14494 $navigation = base.$el.siblings(base.options.navigation.selector); 14495 } 14496 if ($navigation.index()) { 14497 // Navigation muss erstes Kind der Slideshow sein 14498 $navigation.parent().prepend($navigation); 14499 } 14500 }, 14501 14502 /** 14503 * Säubert die Slides von Anpassungen, falls der Slider 'unslicked' wird. 14504 * Slick fügt den Slides einige Attribute hinzu, im Falle von 'unslick' entfernt Slick diese nicht wieder. 14505 */ 14506 cleanUpSlides: function () { 14507 const base = this, 14508 slick = base.slick; 14509 if (slick.unslicked) { 14510 slick.$slides. 14511 removeAttr('style'). 14512 removeAttr('aria-hidden'); 14513 base.restoreAttributes(); 14514 } 14515 }, 14516 14517 onSlickInit: function (event, slick) { 14518 const base = event.data; 14519 base.patchSlickAccessibility(slick); 14520 base.showHideNavigation(slick); 14521 base.handleNavigationArrows(slick.options); 14522 base.updateNavigation(slick); 14523 if (base.options.initializeMultimedia) { 14524 base.initMultimedia(); 14525 } 14526 base.handlePlayButton(slick); 14527 base.updatePagination(slick, 0); 14528 base.updateTabindex(slick); 14529 base.updateAriaRoles(slick); 14530 base.afterInit(); 14531 }, 14532 14533 onSlickBreakpoint: function (event, slick) { 14534 const base = event.data; 14535 base.showHideNavigation(slick); 14536 slick.$slider.slick('unslick'); 14537 base.addPlaceholderSlidesIfNecessary(); 14538 base.initSlick(); 14539 }, 14540 14541 onSlickBeforeChange: function (event, slick, currentSlide, nextSlide) { 14542 const base = event.data; 14543 14544 base.$el.attr('aria-busy', 'true'); 14545 14546 //ohne diese Anweisung kann die Höhenberechnung fehlschlagen 14547 //die "falschen" Elemente werden in updateTabindex wieder verborgen 14548 slick.$slides.find(base.options.selectors.bugged).show(); 14549 14550 if (base.options.setStartClass) { 14551 base.updateSlideStatus(slick, nextSlide); 14552 } 14553 }, 14554 14555 onSlickAfterChange: function (event, slick, currentSlide) { 14556 const base = event.data; 14557 base.updatePagination(slick, currentSlide); 14558 base.updateNavigation(slick); 14559 base.updateTabindex(slick); 14560 base.updateAriaRoles(slick); 14561 base.updateDotFocus(); 14562 14563 base.$el.attr('aria-busy', 'false'); 14564 }, 14565 14566 onSlickDestroy: function (event, slick) { 14567 const base = event.data; 14568 if (!base.unslickBreakpoint) { 14569 // this will only work correctly with just 1 breakpoint that has settings: 'unslick' in the init 14570 base.unslickBreakpoint = slick.breakpointSettings.findIndex((breakpoint) => breakpoint === 'unslick'); 14571 base.mobileFirst = slick.options.mobileFirst; 14572 } 14573 $(window).off('resize' + base.reInitEventNamespace, base.onSlickDestroyWindowResize).on('resize' + base.reInitEventNamespace, base, base.onSlickDestroyWindowResize); 14574 }, 14575 14576 onSlickDestroyWindowResize: function (event) { 14577 const base = event.data; 14578 if (base.mobileFirst) { 14579 if ($(window).width() <= base.unslickBreakpoint && !base.$el.hasClass('slick-initialized')) { 14580 base.slick = base.$el.slick(base.options.slickOptions).slick('getSlick'); 14581 $(window).off('resize' + base.reInitEventNamespace, base.onSlickDestroyWindowResize); 14582 } 14583 } else { 14584 if ($(window).width() > base.unslickBreakpoint && !base.$el.hasClass('slick-initialized')) { 14585 base.slick = base.$el.slick(base.options.slickOptions).slick('getSlick'); 14586 $(window).off('resize' + base.reInitEventNamespace, base.onSlickDestroyWindowResize); 14587 } 14588 } 14589 }, 14590 14591 /** 14592 * Die Standard-Optionen für das Plugin 14593 */ 14594 defaultOptions: { 14595 pagination: {
14596 selector: '.js-slideshow-pagination', 14597 toLocaleStringLanguage: $('html').attr('lang'), 14598 toLocaleStringOptions: {} // https://www.w3schools.com/jsref/jsref_tolocalestring_number.asp 14599 }, 14600 navigation: { 14601 selector: '.js-slideshow-navigation', // der Selector für die Navigation 14602 setStartClass: false, 14603 arrows: { 14604 selectors: { 14605 next: '.js-slideshow-navigation-next', // der Selector für den 'Weiter' Pfeil, muss den Klassen im XHR der Navigation entsprechen 14606 prev: '.js-slideshow-navigation-prev' // der Selector für den 'Zurück' Pfeil, muss den Klassen im XHR der Navigation entsprechen 14607 } 14608 }, 14609 autoplay: { 14610 createPlayButton: true, 14611 playButtonSelector: '.js-slideshow-navigation-play', 14612 playing: { 14613 title: typeof PAUSE !== 'undefined' ? PAUSE : 'Animation stoppen', 14614 symbol: typeof PAUSEIMG !== 'undefined' ? PAUSEIMG : '/assets/icons/isb/close.svg' 14615 }, 14616 paused: { 14617 title: typeof PLAY !== 'undefined' ? PLAY : 'Animation starten', 14618 symbol: typeof PLAYIMG !== 'undefined' ? PLAYIMG : '/assets/icons/isb/play.svg' 14619 } 14620 } 14621 }, 14622 selectors: { 14623 wrapper: '.js-stage-slider', // Ein Ancestor von base.$el, in dem Element .removedContent gefunden werden kann 14624 removedContent: '.js-stage_slider-headline', // Element, das die Klasse isAtStart bekommt, wenn sich die Slideshow an Anfang befindet. 14625 focusable: 'a, [tabindex], textarea, input, select, button, video, object', 14626 bugged: 'video:not(.consent-required video), object' // Vermutung: Sind trotz tabindex === -1 fokussierbar 14627 }, 14628 classes: { 14629 initialized: 'js-slideshow-initialized', // Nötig insb. dann, wenn Slick nicht aufgerufen wird, weil !hasEnoughSlides() gilt 14630 isAtStart: 'is-shown' // Die Klasse, die dem Element removedContent hinzugefügt wird, wenn sich die Slideshow an Anfang befindet. 14631 }, 14632 slickOptions: { 14633 // https://github.com/kenwheeler/slick#settings verfügbare Optionen und Defaults 14634 // appendDots: wird von diesem Modul überschrieben und kann nicht durch die init.js gesetzt werden 14635 // nextArrow: wird von diesem Modul überschrieben durch options.arrowNavigation.selectors.next und kann nicht durch die init.js gesetzt werden 14636 // prevArrow: wird von diesem Modul überschrieben durch options.arrowNavigation.selectors.next und kann nicht durch die init.js gesetzt werden 14637 slide: ':not(.js-slideshow-navigation)', // Da der Navigationcontainer bei der Initialisierung von slick ein Sibling der Slides ist, muss dieser hier explizit ausgenommen werden 14638 infinite: false 14639 }, 14640 14641 multimediaOptions: {}, // Optionen für die initialisierung von cms_multimedia, falls es videos in der slideshow gibt (ungetestet), 14642 initIfNotEnoughSlides: true, 14643 initializeMultimedia: true, 14644 isNavigationSlideshow: false, // Gibt an, ob es sich um eine Thumbnail-Slideshow handelt, die mit asNavFor verknüpft ist (Sonderbehandlung beim Aktivieren/Deaktivieren von Navigation-Arrows und Höhenberechnung) 14645 ariaRole: '', 14646 14647 tablistAriaLabel: typeof SHOW_PAGE !== 'undefined' ? SHOW_PAGE : 'Seite anzeigen' 14648 } 14649}); 14650 14651 /* Ende cms_slideshow_numbers */ 14652 /* Start cms_toggle */ 14653 /*! --GSBDocStart 14654 * @name: @cms/cms_toggle 14655 * @version: 6.0.0 14656 * @description: [//]: # (Diesen und folgende Kommentare auf keinen Fall löschen!) [//]: # (Nur so akzeptiert license-checker die Lizenz) [//]: # (SEE LICENSE IN LICENSE-INTERNAL.txt) [//]: # (https://license-internal.txt) 14657 * --CMSDocEnd 14658*/"use strict"; 14659cms.makeCMSModule('cms.toggle', { 14660 14661 init: function () { 14662 const base = this; 14663 14664 base.validateOptions(); 14665 base.activeMode = base.options.mode; 14666 14667 if (base.options.richtext) { 14668 base.addRichtextContainer(); 14669 } else { 14670 if (base.$el.data('href')) { 14671 $.get(base.$el.data('href'), function (data) { 14672 base.$el.html(data); 14673 base.onMarkupComplete(); 14674 }); 14675 } else { 14676 base.onMarkupComplete(); 14677 } 14678 } 14679 }, 14680 14681 validateOptions: function () { 14682 const base = this, 14683 breakpointOptions = base.options.responsive || []; 14684
14685 [base.options].concat(breakpointOptions).forEach((options) => { 14686 if ('accordion' in options) { 14687 throw new Error( 14688 "Die Option 'accordion' ist obsolet." + 14689 " Stattdessen muss die Option 'mode' mit Wert 'accordion' gesetzt werden." + 14690 " Diese Option ist auch in Breakpoints erlaubt." 14691 ); 14692 } 14693 if ('tab' in options) { 14694 throw new Error( 14695 "Die Option 'tab' ist obsolet." + 14696 " Stattdessen muss die Option 'mode' mit Wert 'tabs' gesetzt werden." + 14697 " Diese Option ist auch in Breakpoints erlaubt." 14698 ); 14699 } 14700 }); 14701 }, 14702 14703 findAllUsedModes: function () { 14704 const base = this, 14705 modes = {}, 14706 breakpointOptions = base.options.responsive || []; 14707 14708 [base.options].concat(breakpointOptions).forEach((options) => { 14709 if (options.mode) { 14710 modes[options.mode] = true; 14711 } 14712 }); 14713 14714 return Object.keys(modes); 14715 }, 14716 14717 /** 14718 * @method onMarkupComplete 14719 * @desc Initialisierung des Scripts 14720 */ 14721 onMarkupComplete: function () { 14722 const base = this; 14723 14724 if (!base.$el.hasClass('cms-toggle')) { 14725 if (base.activeMode !== 'none') { 14726 base.reinitToggle(); 14727 } 14728 14729 base.$el.cms_responsiveListener(base); 14730 } 14731 }, 14732 14733 reinitToggle: function () { 14734 const base = this; 14735 14736 if (!base.$el.hasClass('cms-toggle')) { 14737 base.$el.addClass('cms-toggle'); 14738 base.addClasses(); 14739 base.addClickfunction(); 14740 base.makeAccessible(); 14741 base.accKeyboardCtrl(); 14742 14743 if (base.options.hashControlled) { 14744 base.addHashHandler(); 14745 } 14746 } 14747 }, 14748 14749 switchAccordingToMode: function () { 14750 const base = this; 14751 14752 base.$el.attr('data-togglemode', base.options.mode); 14753 14754 if (base.activeMode === 'none' && base.options.mode !== 'none') { 14755 base.reinitToggle(); 14756 } 14757 base.activeMode = base.options.mode; 14758 14759 if (base.options.autoplay && !base.autoplayInitialized) { 14760 base.autoplay(); 14761 } 14762 14763 if (base.options.autoplay) { 14764 base.autoplayStart(); 14765 } else { 14766 base.autoplayStop(); 14767 } 14768 14769 if (base.options.mode === 'accordion') { 14770 base.switchToAccordion(); 14771 } else if (base.options.mode === 'tabs') { 14772 base.switchToTabs(); 14773 } else if (base.options.mode === 'none') { 14774 base.switchToNone(); 14775 } 14776 }, 14777 14778 14779 14780 /** 14781 * @method addClasses 14782 * @desc Zugehörigkeit der Ãberschriften festlegen 14783 */ 14784 addClasses: function () { 14785 var base = this; 14786 14787 let tabControls = base.$el.find(base.options.tabControls); 14788 if (tabControls.length) { 14789 let activeTabControl = tabControls.filter('.active-control'); 14790 let activeTabIndex = $.inArray(activeTabControl[0], tabControls); 14791 if (activeTabIndex === -1) { 14792 activeTabIndex = 0; 14793 } 14794 tabControls.each(function (index) { 14795 $(this).addClass(base.options.switchPanelClass + index); 14796 14797 if (index === activeTabIndex) { 14798 $(this).addClass('active-control'); 14799 } else { 14800 $(this).addClass('inactive-control'); 14801 } 14802 }); 14803 base.$el.find(base.options.elements).each(function (index) { 14804 $(this).addClass(base.options.switchPanelClass + index); 14805 14806 if (index === activeTabIndex) { 14807 $(this).addClass(base.options.panelOpenedClass); 14808 } else { 14809 $(this).addClass(base.options.panelClosedClass); 14810 } 14811 }); 14812 } 14813 14814 // Accordion hat bei start geöffnete Elemente 14815 var hasOpendElements = false; 14816 14817 if (base.$el.find(base.options.heading).filter('.active-control').length > 0) { 14818 hasOpendElements = true; 14819 } 14820 14821 base.$el.find(base.options.heading).each(function () { 14822 if (!$(this).is('button') || !$(this).is('a')) { 14823 if (base.options.accordionPanelHeight) { 14824 var height = 0; 14825 $(this).next().find('>').each(function () { 14826 height += $(this).outerHeight(true); 14827 }); 14828 $(this).next().height(height); 14829 } 14830 14831 if (base.options.allOpen && base.options.mode === 'accordion') {//TODO: Genauer prüfen 14832 base.show($(this).next()); 14833 $(this).addClass('active-control'); 14834 } else if (hasOpendElements) { 14835 if (!$(this).hasClass('active-control')) { 14836 $(this).addClass('inactive-control'); 14837 base.hide($(this).next()); 14838 } else { 14839 base.show($(this).next()); 14840 } 14841 } else { 14842 $(this).addClass('inactive-control'); 14843 base.hide($(this).next()); 14844 } 14845 } 14846 14847 base.changeAccordionHeadingTitle($(this)); 14848 }); 14849 }, 14850 14851 /** 14852 * @method addClickfunction 14853 * @desc Click Events hinzufügen 14854 */ 14855 addClickfunction: function () { 14856 var base = this; // Accordion 14857 14858 base.$el.on('click.cms_toggle keydown.cms_toggle', base.options.heading, function (e) { 14859 if (e.type === 'click' || e.which === 13) { 14860 e.preventDefault(); 14861 e.stopPropagation(); 14862 base.clickedElem = $(this); 14863 base.changeStateAccordion(); 14864 base.clickedElem = null; 14865 } 14866 }).find(base.options.accordionElementsStopPropagation).on('click.cms_toggle keydown.cms_toggle', function (e) { 14867 e.stopPropagation(); 14868 }); 14869 14870 base.$el.on('activateTab.cms_toggle', base.options.tabControls, function () { 14871 base.clickedElem = $(this); 14872 base.changeStateTab(); 14873 $(this).focus(); 14874 }); // Autoplay muss deaktiviert sein, da die Events focusin und focu
14874sout im Firefox derzeit nocht nicht implementiert 14875 // sind bzw. noch bugs enthalten 14876 14877 if (base.options.changeOnHover && !base.options.autoplay) { 14878 base.$el.on('mouseenter.cms_toggle touchend.cms_toggle', base.options.tabControls, function () { 14879 $(this).trigger('activateTab'); 14880 }).on('click.cms_toggle', base.options.tabControls, function (e) { 14881 e.preventDefault(); 14882 e.stopPropagation(); 14883 }); 14884 } else { 14885 base.$el.on('click.cms_toggle', base.options.tabControls, function (ev) { 14886 ev.preventDefault(); 14887 ev.stopPropagation(); 14888 $(this).trigger('activateTab'); 14889 }).on('focusin.cms_toggle', base.options.tabControls, function (ev, stop) { 14890 if (ev.relatedTarget && !base.$el.find(ev.relatedTarget).length) { 14891 ev.stopPropagation(); 14892 $(this).trigger('activateTab'); 14893 } 14894 }); 14895 } 14896 }, 14897 14898 addHashHandler: function () { 14899 var base = this, 14900 initialHash = location.hash || '#', 14901 hashedElemIndex; 14902 14903 if (history.scrollRestoration) { 14904 history.scrollRestoration = 'manual'; 14905 } 14906 14907 base.initialTabControl = base.$el.find(base.options.tabControls).filter('.active-control'); 14908 if (!base.initialTabControl.length) { 14909 base.initialTabControl = base.initialTabControl.end().first(); 14910 } 14911 base.initialAccordionHeadings = base.$el.find(base.options.heading).filter('.active-control'); 14912 14913 if (initialHash !== '#') { 14914 hashedElemIndex = base.contentPanels.index(base.contentPanels.filter(initialHash)); 14915 if (hashedElemIndex !== -1) { 14916 base.initialTabControl = base.tabs.eq(hashedElemIndex); 14917 base.initialAccordionHeadings = base.headings.eq(hashedElemIndex); 14918 } 14919 } 14920 14921 base.initialStatus = base.initialAccordionHeadings.length ? 'initiallyOpen' : 'closed'; 14922 base.initialHash = initialHash; 14923 base.lastHash = base.initialHash; 14924 base.lastStatus = base.initialStatus; 14925 base.initialState = $.extend({}, history.state, { 14926 status: base.initialStatus, 14927 hash: base.initialHash 14928 }); 14929 history.replaceState(base.initialState, document.title); 14930 $(window).on('cms-hash-push.cms_toggle', function (ev, who, hash, status) { 14931 if (base !== who && (base.lastStatus !== status || base.lastHash !== hash)) { 14932 base.onPopState(status); 14933 base.lastStatus = status; 14934 base.lastHash = hash; 14935 } 14936 }).on('popstate.cms_toggle', function (ev) { 14937 var state = history.state, 14938 status = state && state.status, 14939 hash = location.hash, 14940 hashIsValidSelector = hash && hash !== '#', 14941 contentElement; 14942 base.clickedElem = null; 14943 14944 if (hashIsValidSelector) { 14945 contentElement = base.contentPanels.filter(hash); 14946 if (contentElement.length) { 14947 base.show(contentElement); 14948 } 14949 if (status === 'closed' || status === 'opened' || status === 'initiallyOpen') { 14950 status = state.status; 14951 base.onPopState(status); 14952 base.lastStatus = status; 14953 base.lastHash = hash || '#'; 14954 } 14955 } 14956 }).on('hashchange.cms_toggle', function (ev) { 14957 var url = ev.originalEvent && ev.originalEvent.newURL || '', 14958 hash = '#' + (url.split('#')[1] || ''); 14959 14960 if (hash !== base.lastHash) { 14961 let contentElement = base.contentPanels.filter(hash); 14962 if (contentElement.length) { 14963 if (hash !== '#' && contentElement.is('[hidden]')) { 14964 base.changeStateHash(hash, 'opened', true); 14965 base.onPopState('opened'); 14966 base.lastHash = hash; 14967 } else if (base.options.mode === 'tabs' || base.options.accordionCloseOther) { 14968 base.changeStateHash(base.lastHash, 'closed', true); 14969 base.onPopState('closed'); 14970 base.lastHash = hash; 14971 } 14972 } 14973 } 14974 }); 14975 }, 14976 14977 getHeadingFromHash: function (hash) { 14978 var base = this, 14979 hashIsValidSelector = hash && hash !== '#', 14980 contentElement = hashIsValidSelector ? base.contentPanels.filter(hash) : $(), 14981 index = contentElement.prop('cms_aria_index'); 14982 return index > -1 ? base.headings.eq(index) : $(); 14983 }, 14984
14985 getTabFromHash: function (hash) { 14986 var base = this, 14987 hashIsValidSelector = hash && hash !== '#', 14988 contentElement = hashIsValidSelector ? base.contentPanels.filter(hash) : $(), 14989 index = contentElement.prop('cms_aria_index'); 14990 return index > -1 ? base.tabs.eq(index) : $(); 14991 }, 14992 14993 getHashFromLink: function (link) { 14994 var id = String(link.attr('href')).split('#')[1] || ''; 14995 return '#' + id; 14996 }, 14997 14998 scrollToElement: function ($elementToScrollTo) { 14999 const base = this; 15000 const $html = $('html'); 15001 let offset = 0; 15002 15003 const scrollOffset = base.options.scrolling.scrollOffset; 15004 15005 if (typeof scrollOffset === 'number') { 15006 offset = scrollOffset || 0; 15007 } else if (typeof scrollOffset === 'function') { 15008 offset = scrollOffset.call(base, $elementToScrollTo) || 0; 15009 } 15010 15011 if ($elementToScrollTo.length > 0) { 15012 $html.css('scroll-behavior', 'auto'); // jquery animiertes Scrollen funktioniert nicht korrekt mit scroll-behavior: 'smooth' 15013 let overlaysHeight = base.getOverlaysHeight() + offset; 15014 15015 $html.clearQueue().stop().animate({ 15016 scrollTop: $elementToScrollTo.offset().top - overlaysHeight 15017 }, base.options.scrolling.scrollAnimationDuration, 'linear', 15018 15019 function () {//erster Callback nach erster Scroll Animation 15020 // ensure that the last scroll event (used by e.g. cms_shrinkheader) from the previous scrolling animation has been fired and the overlaysHeight has been properly updated 15021 requestAnimationFrame(function () { 15022 overlaysHeight = base.getOverlaysHeight() + offset; 15023 $html.clearQueue().stop().animate({ 15024 // Rescroll um Overlay Ãnderungen abzufangen 15025 scrollTop: $elementToScrollTo.offset().top - overlaysHeight 15026 }, base.options.scrolling.scrollAnimationDuration / 2, 'linear', function () { 15027 requestAnimationFrame(function () {// zweiter Callback nach zweiter Scroll Animation 15028 $html.css('scroll-behavior', ''); // Scroll Verhalten Manipulation entfernen 15029 if (!$elementToScrollTo.is($(base.options.tabbables))) { 15030 $elementToScrollTo.attr('tabindex', -1); // tabindex="-1" hinzufügen um das Element per Javascript fokussierbar zu machen, falls es nicht bereits einen tabindex hat 15031 } 15032 $elementToScrollTo[0].focus({ preventScroll: true }); // nicht per Browser scrollen, da wir bereits mit JavaScript an die korrekte Stelle gescrollt haben 15033 }); 15034 }); 15035 }); 15036 }); 15037 } 15038 }, 15039 15040 getOverlaysHeight: function () { 15041 const base = this; 15042 let height = 0; 15043 $(base.options.scrolling.scrollOverlaySelector).each(function (index, element) { 15044 height = height + $(element).outerHeight(); 15045 }); 15046 return height; 15047 }, 15048 15049 15050 onPopState: function (status) { 15051 var base = this, 15052 clickedElem = base.clickedElem || $(), 15053 hash, 15054 prevStatus; 15055 hash = history.state.hash; 15056 prevStatus = history.state.status; 15057 base.popStateTriggered = true; 15058 15059 if (base.options.mode === 'tabs') { 15060 if (status === 'opened' && hash !== '#') { 15061 clickedElem = base.getTabFromHash(hash); 15062 } else if (status === 'initiallyOpen' || hash === '#') { 15063 clickedElem = base.initialTabControl; 15064 } 15065 /* else { 15066 //do nothing if status === "closed" && hash !== "#" 15067 }*/ 15068 15069 15070 if (clickedElem.length) { 15071 base.clickedElem = clickedElem; 15072 base.changeStateTab(Boolean(base.$el.find(document.activeElement).length)); 15073 } 15074 } else if (base.options.mode === 'accordion') { 15075 if (status === 'initiallyOpen') { 15076 //only possible on first load 15077 //TODO: Open ALL initial headings, not just the first 15078 clickedElem = base.initialAccordionHeadings; 15079 } else if (status === 'opened') { 15080 if (prevStatus !== 'initiallyOpen' || !base.hasActiveTab(hash)) { 15081 clickedElem = base.getHeadingFromHash(hash); 15082 } 15083 } 15084 15085 if (clickedElem.length) { 15086 base.clickedElem = clickedElem; 15087 base.changeStateAccordion('opened'); 15088 if (!base.options.scrolling.scrollToControlElementAfterOpen && base.options.hashControlled) { 15089 // scroll per JS when hashControlled when it is not automatically scrolling after opening 15090 setTimeout(function () { 15091 // wait for other accordions to properly close first, if accordionCloseOther is true 15092 base.scrollToElement(clickedElem.is('button, a') ? clickedElem : clickedElem.find(base.buttons)); 15093 }, base.options.accordionCloseOther ? base.options.accordionAnimationDuration : 0); 15094 } 15095 } 15096 } 15097 15098 base.popStateTriggered = false;
15099 }, 15100 15101 changeStateHash: function (newHash, status, replace) { 15102 var base = this, 15103 hash = location.hash || '#', 15104 hashLess = location.href.split('#')[0], 15105 newStatus, 15106 globalState; 15107 // backwards compatibility; not strictly necessary as outside code isn't supposed to call this 15108 if (typeof newHash !== 'string' && $(newHash).is('[href]')) { 15109 base.changeStateHash(base.getHashFromLink(newHash), ...[].slice.call(arguments, 1)); 15110 return; 15111 } 15112 15113 globalState = $.extend({}, history.state); 15114 globalState.hash = newHash; 15115 globalState.status = status; 15116 15117 if (!base.popStateTriggered && !replace) { 15118 if (base.options.mode === 'tabs') { 15119 if (hash !== newHash) { 15120 history.pushState(globalState, document.title, hashLess + newHash); 15121 $(window).trigger('cms-hash-push', [base, newHash, status]); 15122 base.lastHash = newHash; 15123 base.lastStatus = status; 15124 } 15125 } else if (base.options.mode === 'accordion') { 15126 if (status === 'closed') { 15127 history.pushState(globalState, document.title, hashLess + '#'); 15128 $(window).trigger('cms-hash-push', [base, '#', status]); 15129 base.lastHash = '#'; 15130 base.lastStatus = status; 15131 } else { 15132 history.pushState(globalState, document.title, hashLess + newHash); 15133 $(window).trigger('cms-hash-push', [base, newHash, status]); 15134 base.lastHash = newHash; 15135 base.lastStatus = status; 15136 } 15137 } 15138 } else if (replace) { 15139 history.replaceState(globalState, document.title); 15140 } 15141 }, 15142 15143 hasActiveTab: function (hash) { 15144 var base = this, 15145 tab = base.getTabFromHash(hash); 15146 return Boolean(tab.filter('.active-control').length); 15147 }, 15148 15149 /** 15150 * @method changeStateAccordion 15151 * @param {Object} elem - Geklicktes Element 15152 * @desc Passt den title des headingElements je Status an (geöffnet/geschlossen) 15153 */ 15154 changeAccordionHeadingTitle: function (elem) { 15155 var base = this; 15156 15157 if (elem.hasClass('active-control') && base.options.accordionHeadingTitleOpened) { 15158 elem.attr('title', base.options.accordionHeadingTitleOpened); 15159 } else if (!elem.hasClass('active-control') && base.options.accordionHeadingTitleClosed) { 15160 elem.attr('title', base.options.accordionHeadingTitleClosed); 15161 } 15162 }, 15163 15164 /** 15165 * @method changeStateAccordion 15166 * @desc Open-/Close-States Accordion 15167 */ 15168 changeStateAccordion: function (targetStatus) { 15169 var base = this, 15170 contentElement, 15171 button, 15172 singleOpen, 15173 status; 15174 15175 if (base.options.accordionElementToOpen) { 15176 contentElement = $(base.options.accordionElementToOpen); 15177 } else { 15178 contentElement = base.clickedElem.next(); 15179 } 15180 15181 button = base.buttons.eq(contentElement.prop('cms_aria_index'))[0]; 15182 singleOpen = !base.options.accordionCloseOther; 15183 15184 if (base.clickedElem.hasClass('inactive-control') || targetStatus === 'opened') { 15185 if (base.options.accordionCloseOther && !base.options.accordionElementToOpen) { 15186 var activeControl = base.$el.find(base.options.heading).not(base.clickedElem).filter('.active-control'); 15187 base.animationAccordion(activeControl.next(), 'close', function () { 15188 if (base.options.scrolling.scrollToControlElementAfterOpen) { 15189 base.scrollToElement($(button)); 15190 } 15191 }); 15192 activeControl.removeClass('active-control').addClass('inactive-control'); 15193 } 15194 if (base.clickedElem.hasClass('inactive-control')) { 15195 base.clickedElem.removeClass('inactive-control').addClass('active-control'); 15196 base.animationAccordion(contentElement, 'open', function () { 15197 base.aria.updateAria(button, true, singleOpen); 15198 }); 15199 } 15200 if (!base.options.accordionCloseOther && !base.options.accordionElementToOpen) { 15201 if (base.options.scrolling.scrollToControlElementAfterOpen) { 15202 base.scrollToElement($(button)); 15203 } 15204 } 15205 15206 status = 'opened'; 15207 } else if (!base.options.accordionCloseOther || !base.options.accordionNoClose || targetStatus === 'closed') { 15208 base.clickedElem.removeClass('active-control').addClass('inactive-control'); 15209 base.animationAccordion(contentElement, 'close', function () { 15210 base.aria.updateAria(button, false, singleOpen); 15211 }); 15212 status = 'closed'; 15213 } 15214 15215 if (base.options.hashControlled) { 15216 if (contentElement.attr('id')) { 15217 base.changeStateHash('#' + contentElement.attr('id'), status, false); 15218 } else { 15219 console.error(base.module, 'contentElement', contentElement, 'without id inside a hash-controlled Accordion'); 15220 } 15221 } 15222 15223 base.changeAccordionHeadingTitle(base.clickedElem); 15224 15225 }, 15226 15227 /** 15228 * @method changeStateTab 15229 * @desc Open-/Close-States Tab 15230 */ 15231 changeStateTab: function (hasFocus) { 15232 var base = this, 15233 panelToOpen = base.$el.find(base.options.tabContainer).find('.' + base.getSwitchPanelClass(base.clickedElem)), 15234 panelToClose; 15235 15236 if (base.clickedElem.hasClass('inactive-control')) { 15237 panelToClose = base.$el.find('.' + base.options.panelOpenedClass); 15238 base.aria.updateAria(base.clickedElem[0], true, false); 15239 panelToClose.removeClass(base.options.panelOpenedClass).addClass(base.options.panelClosedClass); 15240 base.$el.find(base.options.tabControls).filter('.active-control').removeClass('active-control').addClass('inactive-control'); 15241 panelToOpen.removeClass(base.options.panelClosedClass).addClass(base.options.panelOpenedClass); 15242 base.clickedElem.removeClass('inactive-control').addClass('active-control'); 15243 base.animationTab(panelToClose, panelToOpen); 15244 if (base.options.hashControlled) { 15245 base.changeStateHash('#' + panelToOpen.attr('id'), 'opened'); 15246 } 15247 } 15248 15249 if (hasFocus) { 15250 base.clickedElem.focus(); 15251 } 15252 }, 15253 15254 show: function ($elements) { 15255 var base = this, 15256 customShow = base.options.show; 15257 15258 if (typeof customShow !== 'function') { 15259 $elements.show(); 15260 } else {
15261 $elements.toArray().forEach(customShow); 15262 } 15263 }, 15264 15265 hide: function ($elements) { 15266 var base = this, 15267 customHide = base.options.hide; 15268 15269 if (typeof customHide !== 'function') { 15270 $elements.hide(); 15271 } else { 15272 $elements.toArray().forEach(customHide); 15273 } 15274 }, 15275 15276 /** 15277 * @method animationAccordion 15278 * @desc Animation für OpenClose des Accordions 15279 * 15280 * @param elem {Object} Element welches animiert werden soll 15281 * @param type Art der Animation - {string} open / close 15282 */ 15283 animationAccordion: function (elem, type, callback) { 15284 var base = this; 15285 15286 if (type === 'open') { 15287 elem.hide().animate({ height: 'toggle' }, { duration: base.options.accordionAnimationDuration }).promise().done(callback, function () { 15288 base.show(this); 15289 15290 if (base.options.accordionElementToOpen) { 15291 base.addA11y(elem); 15292 } 15293 base.$el.trigger('afterAnimationOpen.toggle.cms', $(elem).prev()); 15294 }); 15295 } else { 15296 elem.show().animate({ height: 'toggle' }, { duration: base.options.accordionAnimationDuration }).promise().done(callback, function () { 15297 base.hide(this); 15298 base.$el.trigger('afterAnimationClose.toggle.cms', $(elem).prev()); 15299 }); 15300 } 15301 }, 15302 15303 /** 15304 * @method animationTab 15305 * @desc Animation für OpenClose des Tabs 15306 * 15307 * @param panelToClose {Object} Element welches animiert werden soll (ausblenden) 15308 * @param panelToOpen {Object} Element welches animiert werden soll (einblenden) 15309 */ 15310 animationTab: function (panelToClose, panelToOpen) { 15311 var base = this; 15312 15313 if (base.options.animateTab) { 15314 panelToClose.fadeOut('slow', function () { 15315 panelToOpen.fadeIn('slow', function () { 15316 base.show(this); 15317 }); 15318 }); 15319 } else { 15320 base.hide(panelToClose); 15321 base.show(panelToOpen); 15322 15323 if (typeof base.options.afterChange === 'function') { 15324 base.options.afterChange.call($(this), base.$el); 15325 } 15326 } 15327 }, 15328 15329 /** 15330 * @method autoplay 15331 * @desc Autoplay 15332 */ 15333 autoplay: function () { 15334 var base = this; 15335 15336 if (base.$el.find('> button').length === 0) { 15337 var button = document.createElement('button'); 15338 button.className = 'paused'; 15339 var image = document.createElement('img'); 15340 image.src = base.options.playButtonImagePlaying; 15341 image.alt = base.options.playButtonAltTextPlaying; // playbutton = base.$el.append($(button).append(image)); 15342 } 15343 15344 base.playbutton = base.$el.find('button.paused'); 15345 base.playbutton.on('click autoplayStart', function (e) { 15346 e.preventDefault(); 15347 e.stopPropagation(); 15348 15349 if (base.playbutton.hasClass('paused')) { 15350 $(this).removeClass('paused').addClass('played'); 15351 base.autoplayStart(); 15352 base.changeStatePlayPause(base.options.playButtonImagePlaying, base.options.playButtonAltTextPlaying); 15353 base.isPaused = false; 15354 15355 if (e.type !== 'autoplayStart') { 15356 //Damit nach Starten des Autoplays nicht nochmal autoplayStart von mouseleave aufgerufen wir 15357 base.isClicked = true; 15358 } 15359 } else { 15360 $(this).addClass('paused').removeClass('played'); 15361 base.autoplayStop(); 15362 base.changeStatePlayPause(base.options.playButtonImagePaused, base.options.playButtonAltTextPaused); 15363 base.isPaused = true; 15364 } 15365 }); 15366 15367 // Stop bei Hover 15368 if (base.options.pauseOnHover) { 15369 base.$el.on('mouseenter mouseleave', function (e) { 15370 if (!base.isPaused) { 15371 if (e.type === 'mouseenter') { 15372 base.autoplayStop(); 15373 } else { 15374 if (base.playbutton.hasClass('played') && !base.isClicked) { 15375 base.autoplayStart(); 15376 } 15377 15378 base.isClicked = false; 15379 } 15380 } 15381 }); 15382 } 15383 15384 //play bei start 15385 if (base.options.playOnLoad) { 15386 base.playbutton.trigger('autoplayStart'); 15387 } 15388 15389 base.autoplayInitialized = true; 15390 }, 15391 15392 /** 15393 * @method autoplayStart 15394 * @desc Autoplay start 15395 */ 15396 autoplayStart: function () { 15397 var base = this; 15398 base.rotation = setInterval(function () { 15399 var tabControls = base.$el.find(base.options.tabControls), 15400 activeTab = tabControls.find('active-control'), 15401 activeIndex = tabControls.index(activeTab), 15402 lastIndex = tabControls.length - 1; //Wenn letzter Tab, wieder beim ersten anfangen 15403 15404 if (activeIndex >= lastIndex) { 15405 tabControls.first().click(); 15406 } else { 15407 tabControls.eq(activeIndex + 1).click(); 15408 } 15409 }, base.options.autoSpeed); 15410 }, 15411 15412 /** 15413 * @method autoplayStop 15414 * @desc Autoplay stop 15415 */ 15416 autoplayStop: function () { 15417 var base = this; 15418 clearInterval(base.rotation); 15419 }, 15420 15421 makeAccessible: function () { 15422 var base = this, 15423 tabControlContainer, 15424 tabListHeading, 15425 tabs, 15426 headings, 15427 clonedHeadings, 15428 buttons, 15429 contentPanels; 15430 15431 if (!base.aria) { 15432 tabControlContainer = base.$el.find(base.options.tabControlContainer); 15433 tabListHeading = base.$el.find(base.options.tabListHeading); 15434 15435 if (!tabListHeading.length) { 15436 tabListHeading = tabControlContainer.prev(base.options.semanticHeading); 15437 } 15438 15439 tabs = base.$el.find(base.options.tabControls); 15440 headings = base.$el.find(base.options.heading); 15441 contentPanels = base.$el.find(base.options.elements); 15442 15443 if (base.findAllUsedModes().includes('tabs')) { 15444 clonedHeadings = headings.filter(base.options.semanticHeading).map(function (i, originalHeading) { 15445 const clonedHeading = $(document.createElement(originalHeading.tagName)); 15446 clonedHeading. 15447 html($(originalHeading).html()). 15448 addClass(base.options.clonedHeadingClass). 15449 prependTo(contentPanels.eq(i)); 15450 return clonedHeading[0]; 15451 }); 15452 } else { 15453 clonedHeadings = $(); 15454 } 15455 15456 buttons = headings.map(function () { 15457 var heading = $(this), 15458 links, 15459 button; 15460 15461 if (!heading.is('button, a')) { 15462 links = heading.find('a'); 15463 if (links.length) { 15464 button = links.first(). 15465 attr('role', 'button'); 15466 } else { 15467 button = $('<button/>').append(heading.contents()); 15468 heading.append(button); 15469 heading.attr('data-transformedbytoggle', 'true'); 15470 } 15471 } else { 15472 button = heading; 15473 } 15474 15475 return button[0]; 15476 }); 15477 base.tabs = tabs; 15478 base.headings = headings; 15479 base.clonedHeadings = clonedHeadings; 15480 base.contentPanels = contentPanels; 15481 base.buttons = buttons; 15482 base.aria = cms.aria(base.el, {}, $.extend({}, base.ariaParams, { 15483 types: { 15484 tabListHeading: tabListHeading, 15485 tabControlContainer: tabControlContainer, 15486 button: buttons, 15487 content: contentPanels, 15488 tab: tabs 15489 } 15490 })); 15491 15492 headings.each(function (i) { 15493 if ($(this).hasClass('active-control')) { 15494 base.aria.updateAria(buttons[i], true, true); 15495 base.show(contentPanels.eq(i)); 15496 } 15497 }); 15498 tabs.each(function (i) { 15499 if ($(this).hasClass('active-control')) { 15500 base.aria.updateAria(tabs[i], true, true); 15501 base.show(contentPanels.eq(i)); 15502 } 15503 }); 15504 15505 tabs.parentsUntil(tabControlContainer).attr('role', 'none'); 15506 } 15507 }, 15508 15509 ariaParams: { 15510 initial: [{ 15511 _type: 'tabListHeading', 15512 id: function id(base) { 15513 return base.generateID(); 15514 } 15515 }, {
15516 _type: 'tabControlContainer', 15517 role: 'tablist', 15518 'aria-labelledby': function ariaLabelledby(base) { 15519 if (base.types['tabControlContainer'].eq(0).attr('aria-label')) { 15520 return null; //delete labelledby 15521 } else if (base.types['tabControlContainer'].eq(0).attr('aria-labelledby')) { 15522 return undefined; //do nothing 15523 } else { 15524 return base.types['tabListHeading'].eq(0).attr('id') || null; 15525 } 15526 } 15527 }, { 15528 _type: 'content', 15529 role: function role(base, index) { 15530 return base.types['content'].eq(index).attr('role') || 'tabpanel'; 15531 }, 15532 id: function id(base, index) { 15533 return base.types['content'].eq(index).attr('id') || base.generateID(); 15534 } 15535 }, { 15536 _type: 'tab', 15537 role: 'tab', 15538 id: function id(base) { 15539 return base.generateID(); 15540 }, 15541 'aria-controls': function ariaControls(base, index) { 15542 return base.types['content'].eq(index).attr('id'); 15543 }, 15544 'href': function href(base, index) { 15545 var tab = base.types['tab'].eq(index), 15546 contId = base.types['content'].eq(index).attr('id'), 15547 hashLess = location.href.split('#')[0]; 15548 if (tab.is('a')) { 15549 return tab.attr('href') || hashLess + '#' + contId; 15550 } else { 15551 return null; 15552 } 15553 } 15554 }, { 15555 _type: 'button', 15556 id: function id(base) { 15557 return base.generateID(); 15558 }, 15559 'aria-controls': function ariaControls(base, index) { 15560 return base.types['content'].eq(index).attr('id'); 15561 } 15562 }, { 15563 _type: 'content', 15564 'aria-labelledby': function ariaLabelledby(base, index) { 15565 return base.types['tab'].eq(index).attr('id') || base.types['button'].eq(index).attr('id'); 15566 } 15567 }], 15568 toggles: { 15569 tab: { 15570 'aria-selected': ['true', 'false'], 15571 tabindex: [0, -1] 15572 }, 15573 button: { 15574 'aria-expanded': ['true', 'false'] 15575 }, 15576 content: { 15577 hidden: [null, 'hidden'] 15578 } 15579 } 15580 }, 15581 15582 //focuses next tabbable element outside the widget 15583 focusNextTabbable: function () { 15584 var base = this, 15585 allTabbables = $(base.options.tabbables).not('[tabindex=-1]'), 15586 lastIndex = allTabbables.length - 1, 15587 tabbablesInside = base.$el.find(base.options.tabbables).not('[tabindex=-1]'), 15588 firstIndexOutside = allTabbables.index(tabbablesInside.last()) + 1; 15589 allTabbables.eq(firstIndexOutside > lastIndex ? 0 : firstIndexOutside).focus(); 15590 }, 15591 15592 //focuses previous tabbable element outside the widget 15593 focusPrevTabbable: function () { 15594 var base = this, 15595 allTabbables = $(base.options.tabbables).not('[tabindex=-1]'), 15596 tabbablesInside = base.$el.find(base.options.tabbables).not('[tabindex=-1]'), 15597 firstIndexOutside = allTabbables.index(tabbablesInside.first()) - 1; 15598 allTabbables.eq(firstIndexOutside < 0 ? -1 : firstIndexOutside).focus(); 15599 }, 15600 15601 activatePrevTab: function () { 15602 var base = this, 15603 tabs = base.tabs, 15604 activeTab = tabs.filter('.active-control'), 15605 activeIndex = tabs.index(activeTab); 15606 15607 if (activeIndex - 1 > -1) { 15608 tabs.eq(activeIndex - 1).trigger('activateTab'); 15609 } else { 15610 tabs.last().trigger('activateTab'); 15611 } 15612 }, 15613 15614 activateNextTab: function () { 15615 var base = this, 15616 tabs = base.tabs, 15617 activeTab = tabs.filter('.active-control'), 15618 activeIndex = tabs.index(activeTab); 15619 15620 if (activeIndex + 1 < tabs.length) { 15621 tabs.eq(activeIndex + 1).trigger('activateTab'); 15622 } else { 15623 tabs.first().trigger('activateTab'); 15624 } 15625 }, 15626 15627 onKeyTab: function (ev) { 15628 var base = ev.data; 15629 base.tabs = base.$el.find(base.options.tabControls); 15630 15631 switch (ev.key) { 15632 case 'ArrowLeft': 15633 case 'Left': 15634 // IE/Edge 15635 base.activatePrevTab(); 15636 break; 15637 15638 case 'ArrowRight': 15639 case 'Right': 15640 // IE/Edge 15641 base.activateNextTab(); 15642 break; 15643 15644 case 'Home': 15645 base.tabs.first().trigger('activateTab'); 15646 break; 15647 15648 case 'End': 15649 base.tabs.last().trigger('activateTab'); 15650 break; 15651 15652 default: 15653 //skip preventDefault etc. 15654 return; 15655 } 15656 15657 ev.stopPropagation(); 15658 ev.preventDefault(); 15659 }, 15660 15661 tabKeyboardCtrl: function () { 15662 var base = this, 15663 eventString = 'keydown.cms_toggle'; 15664 base.$el.off(eventString, base.onKeyAcc); 15665 base.$el.on(eventString, base, base.onKeyTab); 15666 }, 15667 15668 refreshTab: function () { 15669 throw new Error( 15670 "refreshTab() ist obsolet." + 15671 " onRefresh() zu überschreiben ist nicht mehr nötig, um den Typ des Toggles festzulegen." + 15672 " Dies geschieht jetzt über die Option 'mode' (mit Wert 'tabs' für Tabs)." + 15673 " Diese Option ist auch in Breakpoints erlaubt." 15674 ); 15675 }, 15676 15677 /** 15678 * @method switchToTabs 15679 * @desc Switch to tabs mode 15680 */ 15681 switchToTabs: function () { 15682 var base = this, 15683 activeTab; 15684 15685 base.contentPanels.attr('role', 'tabpanel'); 15686 base.tabKeyboardCtrl(); 15687 15688 if (base.options.hashControlled) { 15689 base.onPopState('opened'); 15690 } else { 15691 activeTab = base.tabs.filter('[aria-selected=true]'); 15692 if (activeTab.length) { 15693 base.clickedElem = activeTab; 15694 base.changeStateTab(); 15695 } 15696 } 15697 15698 base.$el.find(base.options.heading).each(function () { 15699 $(this).removeAttr('aria-expanded'); 15700 }); // Autoplay muss deaktiviert sein, da die Events focusin und focu
15700sout im Firefox derzeit nocht nicht implementiert 15701 // sind bzw. noch bugs enthalten 15702 15703 if (base.options.changeOnHover && !base.options.autoplay) { 15704 base.$el.on('mouseenter focus', base.options.tabControls, function (e) { 15705 base.clickedElem = $(this); 15706 base.changeStateTab(); 15707 }); 15708 } 15709 15710 base.hide(base.$el.find('.' + base.options.panelClosedClass)); 15711 base.show(base.$el.find('.' + base.options.panelOpenedClass)); 15712 }, 15713 15714 focusPrevHeading: function () { 15715 var base = this, 15716 buttons = base.buttons, 15717 activeButton = buttons.filter(document.activeElement), 15718 activeIndex = buttons.index(activeButton); 15719 15720 if (activeIndex - 1 > -1) { 15721 buttons.eq(activeIndex - 1).focus(); 15722 } else { 15723 buttons.last().focus(); 15724 } 15725 }, 15726 15727 focusNextHeading: function () { 15728 var base = this, 15729 buttons = base.buttons, 15730 activeButton = buttons.filter(document.activeElement), 15731 activeIndex = buttons.index(activeButton); 15732 15733 if (activeIndex + 1 < buttons.length) { 15734 buttons.eq(activeIndex + 1).focus(); 15735 } else { 15736 buttons.first().focus(); 15737 } 15738 }, 15739 15740 onKeyAcc: function (ev) { 15741 var base = ev.data; 15742 15743 if (!base.options.accordionDisableKeyboardCtrl) { 15744 switch (ev.key) { 15745 case 'ArrowUp': 15746 case 'Up': 15747 // IE/Edge 15748 base.focusPrevHeading(); 15749 break; 15750 15751 case 'ArrowDown': 15752 case 'Down': 15753 // IE/Edge 15754 base.focusNextHeading(); 15755 break; 15756 15757 case 'Home': 15758 base.buttons.first().focus(); 15759 break; 15760 15761 case 'End': 15762 base.buttons.last().focus(); 15763 break; 15764 15765 default: 15766 //skip preventDefault etc. 15767 return; 15768 } 15769 15770 ev.preventDefault(); 15771 } 15772 }, 15773 15774 accKeyboardCtrl: function () { 15775 var base = this, 15776 eventString = 'keydown.cms_toggle'; 15777 base.$el.off(eventString, base.onKeyTab); // remove listener for tabs 15778 base.$el.off(eventString, base.onKeyAcc); // avoid duplicate listener 15779 base.$el.on(eventString, base, base.onKeyAcc); 15780 }, 15781 15782 refreshAccordion: function () { 15783 throw new Error( 15784 "refreshAccordion() ist obsolet." + 15785 " onRefresh() zu überschreiben ist nicht mehr nötig um den Typ des Toggles festzulegen." + 15786 " Dies geschieht jetzt über die Option 'mode' (mit Wert 'accordion' für Akkordeon)." + 15787 " Der Default-Modus in allen GröÃen ist 'accordion'." + 15788 " Diese Option ist auch in Breakpoints erlaubt." 15789 ); 15790 }, 15791 15792 /** 15793 * @method switchToAccordion 15794 * @desc Switch to accordion mode 15795 */ 15796 switchToAccordion: function () { 15797 var base = this; 15798 15799 if (base.contentPanels.is('div') || base.contentPanels.is('span')) { 15800 base.contentPanels.attr('role', 'region'); 15801 } 15802 base.accKeyboardCtrl(); 15803 base.$el.find(base.options.elements).each(function () { 15804 var $elem = $(this); 15805 15806 if ($elem.is('[hidden]')) { 15807 $elem.prev('.active-control').removeClass('active-control').addClass('inactive-control'); 15808 } else { 15809 $elem.prev('.inactive-control').removeClass('inactive-control').addClass('active-control'); 15810 } 15811 }); 15812 15813 if (base.options.hashControlled) { 15814 base.onPopState('opened'); 15815 } 15816 15817 base.$el.find(base.options.heading).each(function () { 15818 if ($(this).hasClass('inactive-control')) { 15819 base.hide($(this).next()); 15820 } 15821 }); 15822 15823 let activeDescendant = base.$el.find(document.activeElement); 15824 if (activeDescendant.length > 0) { 15825 base.tabs.each(function (i, el) { 15826 let tab = $(el); 15827 if (tab.is(activeDescendant) || tab.find(activeDescendant).length) { 15828 base.buttons.eq(tab.prop('cms_aria_index')).focus(); 15829 } 15830 }); 15831 } 15832 }, 15833 15834 /** 15835 * @method changeStatePlayPause 15836 * @param {string} imgsrc - Imagesource-Link 15837 * @param {string} alt - Alt-Text des Images 15838 * @desc Bild tauschen für Play/Pausebutton 15839 */ 15840 changeStatePlayPause: function (imgsrc, imgalt) { 15841 var base = this; 15842 var image = base.playbutton.find('img'); 15843 image.prop('alt', imgalt).prop('src', imgsrc); 15844 }, 15845 15846 /** 15847 * @method getSwitchPanelClass 15848 * @param {Object} elem - geklicktes Element (durchgereicht von changeState oder autoplayStart) 15849 * @desc Liefert die switch-panel Klasse des geklickten Elements 15850 */ 15851 getSwitchPanelClass: function (elem) { 15852 return $.grep(elem.prop('class').split(' '), function (value) { 15853 return value.indexOf('switch-panel') > -1; 15854 }); 15855 }, 15856 15857 uninitAccordion: function () { 15858 throw new Error( 15859 "uninitAccordion() ist obsolet." + 15860 " uninitAccordion() aufzurufen ist nicht mehr nötig um den Typ des Toggles festzulegen." + 15861 " Dies geschieht jetzt über die Option 'mode' (mit Wert 'none' für kein Toggle)." 15862 ); 15863 }, 15864 15865 /** 15866 * @method switchToNone 15867 * @desc Soll den GroÃteil der DOM-Ãnderungen durch das Modul rückgängig machen. 15868 * Die Klassen active-control und inactive-control sind davon ausgenommen. 15869 */ 15870 switchToNone: function () { 15871 var base = this; 15872 15873 if (base.$el.hasClass('cms-toggle')) { 15874 base.$el.removeClass('cms-toggle'); 15875 base.$el.off('.cms_toggle'); //entfernt nur namespace='.cms_toggle' Events 15876 15877 base.headings.filter(function () { 15878 return $(this).attr('data-transformedbytoggle') === 'true'; 15879 }).each(function (i) { 15880 var contents = base.buttons.eq(i).contents(); 15881 $(this).empty().append(contents); 15882 }); 15883 base.show(base.contentPanels); 15884 base.contentPanels.removeAttr('hidden role aria-labelledby'); 15885 base.$el.find(base.options.tabControlContainer).removeAttr('role'); 15886 base.tabs.removeAttr('role aria-selected tabindex'); 15887 base.buttons.removeAttr('aria-expanded'); 15888 base.clonedHeadings.remove(); 15889 base.contentPanels.removeClass(base.options.panelOpenedClass + ' ' + base.options.panelClosedClass); 15890 base.contentPanels.removeClass(function (index, className) { 15891 return className.match(base.options.switchPanelClass + "\\d*", "g"); 15892 }); 15893 base.aria.$el.data('cms.aria', null); 15894 base.aria = null; 15895 } 15896 }, 15897 15898 destroyWidget: function () { 15899 throw new Error( 15900 "destroyWidget() ist obsolet." + 15901 " destroyWidget() nicht mehr unterstützt." + 15902 " Vermutlich genügt es die Option 'mode' (mit Wert 'none' für kein Toggle) zu setzen." + 15903 " Ein \"echtes\" destroy ist dies jedoch nicht, die Modulinstanz bleibt erhalten." 15904 ); 15905 }, 15906 15907 /** 15908 * @method addA11y 15909 * @desc setzt den focus auf das erste fokussierbare Element 15910 * @param elem {jQuery} Element welches nach fokussierbaren Elementen durchsucht wird. Ist mindestens ein Element vorhanden, 15911 * wird der Fokus gesetzt 15912 * @param tabPanel {jQuery} Element auf welches gesprungen werden soll, wenn im TabContainer keiner fokussierbaren Element vorhanden sind 15913 */ 15914 addA11y: function (elem, tabPanel) { 15915 var base = this; 15916 elem = elem || base.$el; 15917 var focusElements = elem.find('input,textarea,select,a,button').not(':hidden'); 15918 15919 if (focusElements.length) { 15920 focusElements[0].focus();
15921 focusElements.last().keydown(function (e) { 15922 }); 15923 } 15924 }, 15925 15926 /** 15927 * @method addRichtextContainer 15928 * @desc Sucht in base.el nach Elementen mit den Klasse startaccordion, endaccordion und accordionheadline (konfigurierbar) 15929 * und baut die für cms_toggle benötigte Struktur um diese Elemente herum. 15930 * 15931 * Wenn alle benötigten Elemente eingebaut wurden, ruft sich das Script nochmal selbst auf; dann mit der Option richtext := false 15932 */ 15933 addRichtextContainer: function () { 15934 var base = this, 15935 containers; 15936 containers = base.$el.find(base.options.richtextStart).map(function () { 15937 var startAcc = $(this), 15938 rtAccContainer = $(base.options.richtextAccordionContainer, base.el).insertBefore(startAcc), 15939 rtTabContainer = $(base.options.richtextTabControlContainer, base.el).insertBefore(startAcc), 15940 headings, 15941 wrapper; 15942 startAcc. 15943 add(startAcc.nextUntil(base.options.richtextEnd)). 15944 add(startAcc.nextAll(base.options.richtextEnd).first()). 15945 appendTo(rtAccContainer); 15946 headings = rtAccContainer.find(base.options.richtextStart).add(rtAccContainer.find(base.options.richtextControl)); 15947 headings.addClass('heading').each(function (i) { 15948 var heading = $(this), 15949 nextHeading = headings.eq(i + 1); 15950 rtTabContainer.append($(base.options.richtextTabControlContainerItem).append($('<a/>').html(heading.html()))); 15951 if (nextHeading.length) { 15952 heading.nextUntil(nextHeading).wrapAll('<div/>'); 15953 } 15954 }); 15955 rtAccContainer.find('.heading').last().nextUntil(base.options.richtextEnd).add(rtAccContainer.find(base.options.richtextEnd)).wrapAll('<div/>'); 15956 wrapper = $(base.options.richtextWrapper, base.el).insertBefore(rtTabContainer); 15957 15958 let usedModes = base.findAllUsedModes(); 15959 if (usedModes.includes('tabs')) { 15960 wrapper.append(rtTabContainer); 15961 } else { 15962 rtTabContainer.remove(); 15963 } 15964 if (usedModes.includes('accordion')) { 15965 wrapper.append(rtAccContainer); 15966 } else { 15967 headings.remove(); 15968 } 15969 return wrapper[0]; 15970 }); 15971 base.$el.removeData('cms.toggle'); 15972 containers.cms_toggle($.extend({}, base.options, { 15973 richtext: false 15974 })); 15975 }, 15976 15977 defaultOptions: { 15978 mode: 'accordion', //Möglichkeiten: accordion, tabs, none 15979 richtext: false, 15980 richtextWrapper: '<div class="richtext-accordion"/>', 15981 richtextStart: '.startaccordion', 15982 richtextControl: '.accordionheadline', 15983 richtextEnd: '.endaccordion', 15984 tabContainer: '> .tabs-container', 15985 tabControls: '> .tabs-list > li a', 15986 tabControlContainer: '> .tabs-list', 15987 richtextTabControlContainer: '<ul class="tabs-list"/>', 15988 richtextTabControlContainerItem: '<li></li>', 15989 tabListHeading: '', 15990 elements: '> .tabs-container > div', 15991 heading: '> .tabs-container > .heading', 15992 clonedHeadingClass: 'cloned-heading', 15993 switchPanelClass: 'switch-panel', 15994 panelOpenedClass: 'panel-opened', 15995 panelClosedClass: 'panel-closed', 15996 richtextAccordionContainer: '<div class="tabs-container"/>', 15997 semanticHeading: 'h1,h2,h3,h4,h5,h6', 15998 tabbables: 'a[href], area, input, button, select, textarea, audio, video, [tabindex]', 15999 accordionAnimationDuration: 400, 16000 accordionCloseOther: true, 16001 accordionNoClose: false, 16002 accordionDisableKeyboardCtrl: false, 16003 accordionPanelHeight: false, 16004 accordionElementToOpen: null, 16005 accordionElementsStopPropagation: '', 16006 hashControlled: false, 16007 autoplay: false, 16008 playButtonImagePaused: null, 16009 playButtonImagePlaying: null, 16010 playButtonAltTextPaused: typeof PLAY === 'undefined' ? 'Animation starten' : PLAY, 16011 playButtonAltTextPlaying: typeof PAUSE === 'undefined' ? 'Animation stoppen' : PAUSE, 16012 accordionHeadingTitleClosed: null, 16013 accordionHeadingTitleOpened: null, 16014 autoSpeed: '5000', 16015 playOnLoad: false, 16016 pauseOnHover: true, 16017 changeOnHover: false, 16018 allOpen: false, 16019 animateTab: false, 16020 respondToEvents: true, 16021 scrolling: { 16022 scrollOffset: function (referenceElement) { 16023 return NaN; 16024 }, 16025 scrollToControlElementAfterOpen: true, 16026 scrollAnimationDuration: 300, 16027 scrollOverlaySelector: '.js-header.is-sticky' 16028 }, 16029 onRefresh: function () { 16030 this.switchAccordingToMode(); 16031 }, 16032 responsive: [] 16033 } 16034}); 16035 16036 /* Ende cms_toggle */ 16037 /* Start cms_tree_navigation */ 16038 /*! --GSBDocStart 16039 * @name: @cms/cms_tree_navigation 16040 * @version: 7.1.0 16041 * @description: Modul für konfigurierbare Cookiebanner 16042 * --CMSDocEnd 16043*/"use strict"; 16044cms.makeCMSModule('cms.tree_navigation', { 16045
16046 init: function init() { 16047 const base = this; 16048 base.preInit(); 16049 base.initButtonHandlers(); 16050 base.initCustomEventHandlers(); 16051 base.registerMetaFixerInitialized(); 16052 }, 16053 16054 registerMetaFixerInitialized: function registerMetaFixerInitialized() { 16055 const base = this; 16056 base.$el.on('cms_meta_fixer_initialized', base, base.onMetaFixerInitialized); 16057 }, 16058 16059 adjustFocus: function adjustFocus($anchor) { 16060 const base = this; 16061 base.$el.find(`.${base.options.classes.anchor}`).find('a, button').not(`.${base.options.buttonClasses.toggle}`).not(base.options.classes.alwaysFocusable ? `.${base.options.classes.alwaysFocusable}` : '').attr('tabindex', -1); 16062 16063 if (base.$el.hasClass(base.options.classes.show)) { 16064 // only make anything tabable when the menu is shown 16065 if ($anchor.length) { 16066 const $navigatedBackFrom = $anchor.prevObject; 16067 // add sibling on the same level, to allow multiple 'ul' on the same level 16068 $anchor = $anchor.add($anchor.siblings(`.${base.options.cssClasses.anchor_current}`)); 16069 // only make the currently opened sub menu's links and it's siblings tabable 16070 const $currentOpenedSubMenuLinks = $anchor.find('a, button').filter((i, e) => !$(e).closest(`.${base.options.classes.anchor}`).hasClass(base.options.cssClasses.anchor_closed)); 16071 $currentOpenedSubMenuLinks.attr('tabindex', 0); 16072 16073 // set focus 16074 if ($navigatedBackFrom) { 16075 // focus the previously opened menu opener, which opened the menu navigating back from 16076 $navigatedBackFrom.find('> button').first().attr('tabindex', 0).trigger('focus'); 16077 } else { 16078 if (window.getComputedStyle($anchor[0]).transitionDuration !== '0s') { 16079 // if navigateToInner makes the menu slide in, using CSS transition 16080 // wait for the transition to end and then focus the first menu entry to avoid scrolling 16081 $anchor.one('transitionend transitioncancel', function () { 16082 $anchor.find('button,a').first().trigger('focus'); 16083 }); 16084 } else { 16085 $anchor.find('button,a').first().trigger('focus'); 16086 } 16087 } 16088 16089 // fix Meta Navigation 16090 if (base.options.classes.metaNav) { 16091 const $metaMenuButtons = base.$el.find(`:not(.${base.options.classes.anchor_closed})`).find(`.${base.options.classes.metaNav}`).find('a, button'); 16092 if ($metaMenuButtons.length) { 16093 // metaMenuButtons are visible and should be tabable 16094 $metaMenuButtons.attr('tabindex', '0'); 16095 } else { 16096 base.$el.find(`.${base.options.classes.metaNav}`).find('a, button').attr('tabindex', '-1'); 16097 } 16098 } 16099 16100 } else { 16101 // make everything tabbable 16102 const $allButtonsAndLinks = base.$el.find('a, button'); 16103 16104 $allButtonsAndLinks.filter('[tabindex="-1"]'). 16105 attr('tabindex', 0); 16106 16107 $allButtonsAndLinks. 16108 first().trigger('focus'); 16109 16110 } 16111 } else { 16112 const nodes = base.$el.find(`.${base.options.classes.node}`); 16113 nodes.find('> button[disabled]'). 16114 removeAttr('disabled'); 16115 nodes.siblings(). 16116 removeClass(base.options.cssClasses.anchor_closed); 16117 16118 base.$el.find(`.${base.options.classes.anchor}`). 16119 css('--height', ''); 16120 } 16121 }, 16122 16123 adjustHeight: function adjustHeight(anchor, button) { 16124 const base = this; 16125 if (base.options.mode === 'overlay') { 16126 let $anchor = $(anchor); 16127 const $openedUls = base.$el.find(`.${base.options.classes.anchor}.${base.options.cssClasses.anchor_opened}:visible`); 16128 16129 // If navigating back, switch to next ul parent 16130 if ($(button).length < 1) { 16131 $anchor = $anchor.parent().closest(`.${base.options.classes.anchor}`); 16132 } 16133 16134 let maxHeight = 0; 16135 // Find maximal natural height of an element 16136 $openedUls.css('--height', 'auto'); 16137 $openedUls.each(function () { 16138 if ($(this).outerHeight(true) > maxHeight) { 16139 maxHeight = $(this).outerHeight(true); 16140 } 16141 }); 16142 16143 $openedUls.each(function () { 16144 $(this).css('--height', `${maxHeight}px`); 16145 $(this).css('--overflow', 'hidden'); 16146 }); 16147 base.adjustFocus($anchor); 16148 base.$el.trigger('height_adjusted.tree_navigation.cms'); 16149 } 16150 }, 16151 16152 16153 onMetaFixerInitialized: function onMetaFixerInitialized(ev) { 16154 const base = ev.data; 16155 const nnId = $('body').data('nn'); 16156 const $openElement = $(`#nn-${nnId}`); 16157 if ($openElement.length > 0) { 16158 const $uls = $openElement.parents('ul'); 16159 const buttons = []; 16160 $uls.each(function () { 16161 let button = $(this).prev('button'); 16162 if (button.length < 1) { 16163 button = $(this).closest(`.${base.options.classes.node}`).find('button')[0]; 16164 } 16165 buttons.unshift(button); 16166 }); 16167 16168 if (base.options.openSubNavForCurrentNode) { 16169 const button = $openElement.find('button').first(); 16170 buttons.unshift(button); 16171 } 16172 16173 for (let i = 0; i < buttons.length; i++) { 16174 const currentButton = buttons[i]; 16175 base.navigateToInner(currentButton); 16176 } 16177 base.$el.trigger('cms_tree_navigation_open_node', buttons[buttons.length]); 16178 } 16179 return $openElement; 16180 }, 16181 16182 preInit: function preInit() { 16183 const base = this; 16184 const tnOptions = base.options; 16185 base.$el.cms_responsiveListener(base); 16186 16187 // initial state 16188 const initialOpen = tnOptions.states.initStateOpen; 16189 base.toggleMenuSet(initialOpen, false); 16190 16191 base.resetState(); 16192
16193 if (tnOptions.optional.setMaxAnchorHeight) { 16194 let height = 0; 16195 base.$el.find(`.${tnOptions.classes.anchor}`).each(function (i, element) { 16196 const currHeight = $(element).outerHeight(true); 16197 if (currHeight > height) { 16198 height = currHeight; 16199 } 16200 }); 16201 base.$el.find(`.${tnOptions.classes.anchor}`).each(function (i, element) { 16202 $(element).css('--height', `${height}px`); 16203 }); 16204 } 16205 16206 // set initial aria-expanded for toggle to open the menu 16207 base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first().attr('aria-expanded', initialOpen); 16208 }, 16209 16210 16211 initButtonHandlers: function initButtonHandlers() { 16212 const base = this; 16213 const tnOptions = base.options; 16214 16215 // handle menu 16216 // display 16217 base.$el.find(`.${tnOptions.buttonClasses.toggleOn}`).first().on('click', function (e) { 16218 base.toggleMenuSet(true); 16219 base.toggleClass(base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first(), true, tnOptions.cssClasses.toggleClass_opened, tnOptions.cssClasses.toggleClass_closed); 16220 base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first().attr('aria-expanded', true); 16221 }); 16222 // hide 16223 base.$el.find(`.${tnOptions.buttonClasses.toggleOff}`).first().on('click', function (e) { 16224 base.toggleMenuSet(false); 16225 base.toggleClass(base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first(), false, tnOptions.cssClasses.toggleClass_opened, tnOptions.cssClasses.toggleClass_closed); 16226 base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first().attr('aria-expanded', false); 16227 }); 16228 // toggle 16229 base.$el.find(`.${tnOptions.buttonClasses.toggle}`).first().on('click.toggle.tree_navigation.cms', function (e) { 16230 const setOpen = $(base.el).hasClass(tnOptions.classes.hide); 16231 base.toggleMenuSet(setOpen); 16232 base.toggleClassesIf(base.el, tnOptions.classes.show, this, tnOptions.cssClasses.toggleClass_opened, tnOptions.cssClasses.toggleClass_closed); 16233 $(this).attr('aria-expanded', setOpen); 16234 }); 16235 // navigate to inner level 16236 base.$el.find(`.${tnOptions.buttonClasses.navigateToInner}`).on('click', function (e) { 16237 base.navigateToInner(this); 16238 }); 16239 16240 if (tnOptions.states.navBackButton) { 16241 // go back one level 16242 base.$el.find(`.${tnOptions.buttonClasses.navigateBack}`).on('click', function (e) { 16243 base.navigateBack(this); 16244 }); 16245 } 16246 }, 16247 16248 initCustomEventHandlers: function initCustomEventHandlers(base = this) { 16249 // close toggle (triggered when cms_mobile_nav_service_search is opened) 16250 $(document).on('close.toggle.tree_navigation.cms', base, function (ev, base = ev.data) { 16251 base.toggleMenuSet(false); 16252 base.toggleClassesIf(base.el, false, base.$el.find(`.${base.options.buttonClasses.toggle}`).first(), base.options.cssClasses.toggleClass_opened, base.options.cssClasses.toggleClass_closed); 16253 base.$el.find(`.${base.options.buttonClasses.toggle}`).first().attr('aria-expanded', false); 16254 }); 16255 }, 16256 16257 // --------------------------------------------------- 16258 16259 resetState: function resetState() { 16260 const base = this; 16261 const tnOptions = base.options; 16262 base.hideAllAnchorsButFirstLevel(); 16263 // hide all nodes 16264 $(base.el).find(`.${tnOptions.classes.node}`).each(function (i, node) { 16265 $(node).removeClass(tnOptions.cssClasses.node_opened); 16266 $(node).addClass(tnOptions.cssClasses.node_closed); 16267 $(node).find('button').not(`.${tnOptions.buttonClasses.navigateBack}`).attr('aria-expanded', false); // set initial aria-expanded to false 16268 }); 16269 // set all navigateToInner buttons -> closed 16270 $(base.el).find(`.${tnOptions.buttonClasses.navigateToInner}`).each(function (i, button) { 16271 $(button).removeClass(tnOptions.cssClasses.navigateToInner_opened); 16272 $(button).addClass(tnOptions.cssClasses.navigateToInner_closed); 16273 }); 16274 }, 16275 16276 hideAllAnchorsButFirstLevel: function hideAllAnchorsButFirstLevel() { 16277 const base = this; 16278 const tnOptions = base.options; 16279 const $firstLevelAnchors = $(base.el).find(`.${tnOptions.classes.anchor}`).filter(function (index, anchor) { 16280 return $(anchor).parent().closest(`.${tnOptions.classes.anchor}`).length === 0; 16281 }); 16282 const $deeperLevelAnchors = $(base.el).find(`.${tnOptions.classes.anchor}`).not($firstLevelAnchors);
16283 $firstLevelAnchors.addClass(tnOptions.cssClasses.anchor_opened).removeClass(tnOptions.cssClasses.anchor_closed); 16284 base.setAnchorCurrentClass($firstLevelAnchors, true); // only overlay mode 16285 $deeperLevelAnchors.addClass(tnOptions.cssClasses.anchor_closed).removeClass(tnOptions.cssClasses.anchor_opened); 16286 }, 16287 16288 trapFocus: function trapFocus() { 16289 const base = this; 16290 base.focusTrapIsEngaged = true; 16291 $(base.$el).add(`.${base.options.buttonClasses.toggle}`).on('focusout', base, function (e) { 16292 const base = e.data; 16293 if (base.focusTrapIsEngaged) { 16294 const triggeredByToggle = $(e.target).hasClass(base.options.buttonClasses.toggle) || $(e.target).hasClass(base.options.buttonClasses.toggleOff); 16295 if (triggeredByToggle) { 16296 if (!base.$el.find(e.relatedTarget).length) { 16297 base.focusTrapIsEngaged = false; 16298 } 16299 } else { 16300 if (!base.$el.find(e.relatedTarget).length) { 16301 base.$el.find(`.${base.options.buttonClasses.toggle}`).focus(); 16302 } 16303 } 16304 } else { 16305 if (base.$el.find(e.target).length) { 16306 base.focusTrapIsEngaged = true; 16307 } 16308 } 16309 }); 16310 }, 16311 16312 openNode: function openNode(open, anchor, button, node) { 16313 const base = this; 16314 16315 base.setAnchor(anchor, open); 16316 base.setButton(button, open); 16317 base.setNode(node, open); 16318 base.$el.trigger('cms_tree_navigation_open_node', button); 16319 }, 16320 navigateToInner: function navigateToInner(button) { 16321 const base = this; 16322 const tnOptions = base.options; 16323 let open = tnOptions.states.navOpenOnly; 16324 16325 const anchor = $(button).siblings(`.${tnOptions.classes.anchor}`); 16326 const node = $(button).parents(`.${tnOptions.classes.node}`).first(); 16327 16328 if (!tnOptions.states.navOpenOnly) { 16329 open = $(node).hasClass(tnOptions.cssClasses.node_closed); 16330 } 16331 16332 if (tnOptions.mode === 'overlay') { 16333 node.siblings().addClass(tnOptions.cssClasses.anchor_closed); 16334 } 16335 16336 base.openNode(open, anchor, button, node); 16337 base.adjustHeight(anchor, button); 16338 }, 16339 navigateBack: function navigateBack(backButton) { 16340 const base = this; 16341 const tnOptions = base.options; 16342 16343 const anchor = $(backButton).parents(`.${tnOptions.classes.anchor}`).first(); 16344 const button = $(backButton).siblings(`.${tnOptions.buttonClasses.navigateToInner}`); 16345 const node = $(backButton).parents(`.${tnOptions.classes.node}`).first(); 16346 base.$el.trigger('cms_tree_navigation_navigate_back', backButton); 16347 16348 base.setAnchor(anchor, false); 16349 base.setButton(button, false); 16350 base.setButton(anchor.siblings('button'), false); 16351 if (tnOptions.mode === 'overlay') { 16352 node.siblings().removeClass(tnOptions.cssClasses.anchor_closed); 16353 } 16354 base.setNode(node, false); 16355 base.adjustHeight(anchor, button); 16356 }, 16357 toggleMenuSet: function toggleMenuSet(open, adjustFocus = true) { 16358 const base = this; 16359 const tnOptions = base.options; 16360 if (open) { 16361 base.resetState(); 16362 base.$el.trigger('beforeOpen.tree_navigation.cms', base); 16363 $('body').removeClass(tnOptions.classes.bodyMenuClosed).addClass(tnOptions.classes.bodyMenuOpened); 16364 base.trapFocus(); // engage focus trap 16365 base.toggleClass($(base.el), open, tnOptions.classes.show, tnOptions.classes.hide); // show menu 16366 16367 const $anchor = base.$el.find(` > .${base.options.classes.anchor}`); 16368 const $node = $anchor.find(` > .${base.options.classes.node}`); 16369 base.adjustHeight($anchor, $node); // needed if the menu has been opened and navigated before 16370 base.$el.trigger('afterOpen.tree_navigation.cms', base); 16371 } else { 16372 base.$el.trigger('beforeClose.tree_navigation.cms', base); 16373 $('body').removeClass(tnOptions.classes.bodyMenuOpened).addClass(tnOptions.classes.bodyMenuClosed); 16374 base.hideAllAnchorsButFirstLevel(); 16375 16376 // disengage focus trap 16377 base.focusTrapIsEngaged = false; 16378 $(base.$el).add(`.${base.options.buttonClasses.toggle}`).off('focusout'); 16379 16380 base.toggleClass($(base.el), open, tnOptions.classes.show, tnOptions.classes.hide); 16381 base.$el.trigger('afterClose.tree_navigation.cms', base); 16382 } 16383 if (adjustFocus) { 16384 const $openElement = base.onMetaFixerInitialized({ data: base }); 16385 if (base.options.mode === 'overlay') { 16386 const $focusElement = $openElement ? $openElement.closest('ul') : $(base.$el.find(`.${base.options.classes.anchor}`).first()); 16387 base.adjustFocus($focusElement); 16388 } 16389 } 16390 }, 16391
16392 setAnchorCurrentClass: function setAnchorCurrentClass(element, open) { 16393 const base = this; 16394 const tnOptions = base.options; 16395 if (tnOptions.mode === 'overlay') { 16396 base.$el.find(`.${tnOptions.classes.anchor}`).removeClass(tnOptions.cssClasses.anchor_current); 16397 if (open) { 16398 const $siblings = element.siblings(`.${tnOptions.classes.anchor}`); 16399 element.add($siblings).addClass(tnOptions.cssClasses.anchor_current); 16400 } else { 16401 const $parentAnchor = element.parent().closest(`.${tnOptions.classes.anchor}`); 16402 const $siblingAnchors = $parentAnchor.siblings(`.${tnOptions.classes.anchor}`); 16403 $parentAnchor.add($siblingAnchors).addClass(tnOptions.cssClasses.anchor_current); 16404 } 16405 } 16406 }, 16407 16408 setAnchor: function setAnchor(element, open) { 16409 const base = this; 16410 const tnOptions = base.options; 16411 base.setAnchorCurrentClass(element, open); // only overlay mode 16412 base.toggleClass(element, open, tnOptions.cssClasses.anchor_opened, tnOptions.cssClasses.anchor_closed); 16413 }, 16414 setButton: function setButton(button, open) { 16415 const base = this; 16416 const tnOptions = base.options; 16417 base.toggleClass(button, open, tnOptions.cssClasses.navigateToInner_opened, tnOptions.cssClasses.navigateToInner_closed); 16418 const $button = $(button); 16419 16420 $button.attr('aria-expanded', open); 16421 16422 if (tnOptions.mode === 'overlay') { 16423 if ($button.attr('disabled')) { 16424 $button.removeAttr('disabled'); 16425 } else { 16426 $button.attr('disabled', 'true'); 16427 } 16428 } 16429 }, 16430 setNode: function setNode(node, open) { 16431 const base = this; 16432 const tnOptions = base.options; 16433 base.toggleClass(node, open, tnOptions.cssClasses.node_opened, tnOptions.cssClasses.node_closed); 16434 }, 16435 toggleClassesIf: function toggleClassesIf(element, hasClass, thenElement, addClass, removeClass) { 16436 const base = this; 16437 base.toggleClass(thenElement, $(element).hasClass(hasClass), addClass, removeClass); 16438 }, 16439 16440 // --------------------- methods --------------------- 16441 toggleClass: function toggleClass(element, condition, addClass, removeClass) { 16442 const base = this; 16443 if (condition) { 16444 base.setClass(element, condition, addClass, removeClass); 16445 } else { 16446 base.setClass(element, !condition, removeClass, addClass); 16447 } 16448 }, 16449 setClass: function setClass(element, condition, addClass, removeClass) { 16450 if (condition) { 16451 $(element).addClass(addClass); 16452 $(element).removeClass(removeClass); 16453 } 16454 }, 16455 16456 defaultOptions: { 16457 mode: 'explorer', // Der Modus in welchem das Modul laufen soll. Entweder 'explorer' oder 'overlay' 16458 openSubNavForCurrentNode: true, // Gibt an ob ein Navigationspunkt dessen Seite gerade angezeigt wird und welcher weitere Unterpunkte hat diese aufklappen soll 16459 // classes to set 16460 cssClasses: { 16461 toggleClass_opened: 'is-opened', // Klasse, die dem Menü-Trigger einer Menüebene hinzugefügt wird, wenn die Ebene sichtbar ist 16462 toggleClass_closed: 'is-closed', // Klasse, die dem Menü-Trigger einer Menüebene hinzugefügt wird, wenn die Ebene ausgeblendet ist 16463 navigateToInner_opened: 'is-opened', // Klasse, die den Buttons innerhalb von `classes.node` hinzugefügt wird, wenn die Ebene sichtbar ist 16464 navigateToInner_closed: 'is-closed', // Klasse, die den Buttons innerhalb von `classes.node` hinzugefügt wird, wenn die Ebene ausgeblendet ist 16465 node_opened: 'is-opened', // Klasse, die `classes.node` hinzugefügt wird, wenn die Ebene sichtbar ist 16466 node_closed: 'is-closed', // Klasse, die `classes.node` hinzugefügt wird, wenn die Ebene ausgeblendet ist 16467 anchor_opened: 'is-visible', // Klasse, die `classes.anchor` hinzugefügt wird, wenn die Ebene sichtbar ist 16468 anchor_closed: 'is-invisible', // Klasse, die `classes.anchor` hinzugefügt wird, wenn die Ebene ausgeblendet ist 16469 anchor_current: 'is-current' // Klasse, die `classes.anchor` hinzugefügt wird, wenn die Ebene im 'overlay' `mode` die gerade sichtbare Ebene ist 16470 }, 16471 // dom nodes 16472 classes: { 16473 show: 'js-nav-mobile--visible', // Klasse, die base.$el hinzugefügt wird, wenn das Menü geöffnet ist 16474 hide: 'js-nav-mobile--hidden', // Klasse, die base.$el hinzugefügt wird, wenn das Menü geschlossen ist 16475 anchor: 'js-nav-mobile--list', // Menüebene (Liste) 16476 node: 'js-nav-mobile--node', // Einzelne Einträge einer Menüebene 16477 bodyMenuOpened: 'mobile-menu-opened', // Klasse, die body hinzugefügt wird, wenn das Menü geöffnet ist 16478 bodyMenuClosed: 'mobile-menu-closed', // Klasse, die body hinzugefügt wird, wenn das Menü geschlossen ist 16479 metaNav: 'js-meta-nav', // Selektor für die ul der metaNavigation im 'overlay' `mode` 16480 alwaysFocusable: '' // / Service-Navigation, die immer antabbar sein soll
16481 }, 16482 buttonClasses: { 16483 toggle: 'js-nav-mobile--toggle', // Button zum Anzeigen/Ausblenden von dem Menü 16484 toggleOn: 'js-nav-mobile--toggleOn', // Button zum Anzeigen von dem Menü 16485 toggleOff: 'js-nav-mobile--toggleOff', // Button zum Ausblenden von dem Menü 16486 navigateToInner: 'js-nav-mobile--navigateToInner', // Button zum Navigieren zur nächsten Menüebene 16487 navigateBack: 'js-nav-mobile--back' // / Button zum Navigieren eine Menüebene zurück 16488 }, 16489 states: { 16490 initStateOpen: false, 16491 navBackButton: true, 16492 navOpenOnly: false 16493 }, 16494 path: { 16495 indicator: 'body', 16496 indicatorAttr: 'data-nn', 16497 nodePrefix: '#tn-' 16498 }, 16499 optional: { 16500 setMaxAnchorHeight: false, 16501 anchorWrapper: '' // Selektor, falls `classes.anchor` kein direktes Kind vom `base.$el` ist muss diese Klasse auf den direkten parent von `classes.anchor` zeigen 16502 } 16503 } 16504}); 16505 16506 /* Ende cms_tree_navigation */ 16507 /* Start cms_form_element_visibility */ 16508 "use strict"; 16509function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } 16510cms.makeCMSModule('cms.form_element_visibility', { 16511 init: function init() { 16512 var base = this, 16513 configs = base.options.configs || []; 16514 configs.forEach(function (config) { 16515 var control = $('#' + config.formElementId), 16516 valueConfigs = config.values || {}, 16517 defaultValueConfig = config.defaultValue, 16518 checkedConfig = config.checked, 16519 uncheckedConfig = config.unchecked; 16520 var conditionalConfigs = []; 16521 if (defaultValueConfig) { 16522 conditionalConfigs.push(defaultValueConfig); 16523 } 16524 conditionalConfigs.push.apply(conditionalConfigs, _toConsumableArray(Object.values(valueConfigs))); 16525 if (uncheckedConfig) { 16526 conditionalConfigs.push(uncheckedConfig); 16527 } 16528 if (checkedConfig) { 16529 conditionalConfigs.push(checkedConfig); 16530 } 16531 conditionalConfigs.forEach(function (valueConfig) { 16532 var hideElements = valueConfig.hideElements || [], 16533 showElements = valueConfig.showElements || [], 16534 elementsToHide = [], 16535 elementsToShow = []; 16536 hideElements.forEach(function (selector) { 16537 elementsToHide.push.apply(elementsToHide, _toConsumableArray(base.$el.find(selector))); 16538 }); 16539 showElements.forEach(function (selector) { 16540 elementsToShow.push.apply(elementsToShow, _toConsumableArray(base.$el.find(selector))); 16541 }); 16542 valueConfig.elementsToHide = $(elementsToHide); 16543 valueConfig.elementsToShow = $(elementsToShow); 16544 }); 16545 control.on('updateVisibility.' + base.eventName, { 16546 base: base, 16547 config: config 16548 }, base.updateVisibility).on('change', function (ev) { 16549 $(ev.currentTarget).trigger('updateVisibility.' + base.eventName); 16550 }).trigger('updateVisibility.' + base.eventName); 16551 }); 16552 }, 16553 updateVisibility: function updateVisibility(ev) {console.log("UPDATE VISIBILITY"); 16554 var _ev$data = ev.data, 16555 base = _ev$data.base, 16556 config = _ev$data.config; 16557 var formElement = ev.target; 16558 var valueConfigs = config.values || {}; 16559 var valueConfig = valueConfigs && valueConfigs[formElement.value] || config.defaultValue; 16560 if (valueConfig) { 16561 base.updateVisibilityByConfig(valueConfig); 16562 } 16563 if (formElement.checked === false && config.unchecked) { 16564 // do nothing if checked is falsy but not false 16565 base.updateVisibilityByConfig(config.unchecked); 16566 } else if (formElement.checked === true && config.checked) { 16567 base.updateVisibilityByConfig(config.checked); 16568 } 16569 }, 16570 updateVisibilityByConfig: function updateVisibilityByConfig(config) { 16571 var base = this; 16572 base.hideElements(config); 16573 base.showElements(config); 16574 }, 16575 hideElements: function hideElements(showHideConfig) { 16576 var base = this, 16577 ancestorSelector = showHideConfig.ancestor || base.options.selectors.ancestor; 16578 showHideConfig.elementsToHide.closest(ancestorSelector).hide(); 16579 }, 16580 showElements: function showElements(showHideConfig) { 16581 var base = this, 16582 ancestorSelector = showHideConfig.ancestor || base.options.selectors.ancestor; 16583 showHideConfig.elementsToShow.closest(ancestorSelector).show(); 16584 }, 16585 defaultOptions: { 16586 configs: [], 16587 selectors: { 16588 ancestor: '.row' 16589 } 16590 } 16591}); 16592 16593 /* Ende cms_form_element_visibility */ 16594 /* Start cms_form_utility_char_limit */ 16595 /*! --GSBDocStart 16596 * @name: @cms/cms_form_utility 16597 * @version: 1.2.0 16598 * @description: [//]: # (Diesen und folgende Kommentare auf keinen Fall löschen!) [//]: # (Nur so akzeptiert license-checker die Lizenz) [//]: # (SEE LICENSE IN LICENSE-INTERNAL.txt) [//]: # (https://license-internal.txt) 16599 * --CMSDocEnd 16600*/"use strict"; 16601cms.makeCMSModule('cms.form_utility_char_limit', { 16602 init: function () { 16603 const base = this; 16604 const textarea = base.el.querySelector(base.options.selectors.textarea); 16605 const countNow = base.el.querySelector(base.options.selectors.countNow); 16606 const countMax = base.el.querySelector(base.options.selectors.countMax); 16607 const countHint = base.el.querySelector(base.options.selectors.countHint); 16608 const statusDiv = base.el.querySelector(base.options.selectors.statusDiv); 16609 base.maxLength = parseInt(textarea.maxLength); 16610 countMax.textContent = base.maxLength; 16611 countNow.textContent = base.maxLength - textarea.value.length; 16612 let timeoutId; 16613 16614 textarea.setAttribute('aria-describedby', 'texthint'); 16615 16616 // Status bei Eingabe verarbeiten: 16617 textarea.addEventListener('input', function () { 16618 const currentLength = textarea.value.length; 16619 const remainingLength = base.maxLength - currentLength; 16620 countNow.textContent = remainingLength; 16621 clearTimeout(timeoutId); 16622 if (currentLength === base.maxLength) { 16623 statusDiv.textContent = `${remainingLength} Zeichen übrig â Maximallänge erreicht!`; 16624 countHint.classList.add('max'); 16625 } else if (currentLength === Math.round(base.maxLength / 2)) { 16626 statusDiv.textContent = `${remainingLength} Zeichen übrig â Halbzeit.`; 16627 countHint.classList.add('half'); 16628 } else { 16629 const announceCountHint = () => { 16630 statusDiv.textContent = `${remainingLength} Zeichen übrig`; 16631 }; 16632 timeoutId = setTimeout(announceCountHint, base.options.statusDelay); 16633 countHint.classList.remove('half', 'max'); 16634 } 16635 }); 16636 16637 // Tastatureingaben nach Erreichen des Maximum verarbeiten: 16638 textarea.addEventListener('keydown', function (e) { 16639 const currentLength = textarea.value.length; 16640 // Gegebenenfalls weitere Tasten als Ausnahmen aufführen. 16641 if (currentLength >= base.maxLength && !['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', `End`, `Home`, `PageUp`, `PageDown`, `Escape`, `Tab`, `PrintScreen`, `Insert`, `ContextMenu`, `F1`, `F2`, `F3`, `F4`, `F5`, `F6`, `F7`, `F8`, `F9`, `F10`, `F11`, `F12`, '
16641Shift', 'CapsLock', 'Control'].includes(e.key)) { 16642 setTimeout(() => { 16643 statusDiv.innerHTML = `<span id="${Date.now()}">Maximale Zeichenanzahl erreicht â weitere Eingaben werden ignoriert.</span>`; 16644 }, 1); 16645 } 16646 }); 16647 }, 16648 defaultOptions: { 16649 statusDelay: 750, 16650 selectors: { 16651 textarea: 'textarea', 16652 countNow: '.js-count_now', 16653 countMax: '.js-count_max', 16654 countHint: '.js-count_hint', 16655 statusDiv: '.js-count_out' 16656 } 16657 } 16658}); 16659 16660 /* Ende cms_form_utility_char_limit */ 16661})(); 16662 /* Start connectFormElements */ 16663 //Beispiel aus dem Prototypen 16664"use strict"; 16665var cms; 16666cms = cms || {}; 16667cms.connectFormElements = function () { 16668 console.log("CONNECT FORM ELEMENTS"); 16669 $("form[name=KontaktformularBeschwerdeIF]").cms_form_element_visibility({ 16670 selectors: { "ancestor": "span" }, 16671 configs: [{ 16672 formElementId: "f18930934g18993284d18993304i1", 16673 unchecked: { 16674 ancestor: "#beschwerde_strafanzeige", 16675 hideElements: ["#f18930934d18991786"] 16676 }, 16677 checked: { 16678 ancestor: "#beschwerde_strafanzeige", 16679 hideElements: ["#f18930934d18991786"] 16680 } 16681 }, { 16682 formElementId: "f18930934g18993284d18993306i2", 16683 unchecked: { 16684 ancestor: "#beschwerde_strafanzeige", 16685 hideElements: ["#f18930934d18991786"] 16686 }, 16687 checked: { 16688 ancestor: "#beschwerde_strafanzeige", 16689 showElements: ["#f18930934d18991786"] 16690 } 16691 }, { 16692 formElementId: "f18930934g18993290d18993304i1", 16693 unchecked: { 16694 ancestor: "#beschwerde_vorgang", 16695 hideElements: ["#f18930934d18991796"] 16696 }, 16697 checked: { 16698 ancestor: "#beschwerde_vorgang", 16699 hideElements: ["#f18930934d18991796"] 16700 } 16701 }, { 16702 formElementId: "f18930934g18993290d18993306i2", 16703 unchecked: { 16704 ancestor: "#beschwerde_vorgang", 16705 hideElements: ["#f18930934d18991796"] 16706 }, 16707 checked: { 16708 ancestor: "#beschwerde_vorgang", 16709 showElements: ["#f18930934d18991796"] 16710 } 16711 }] 16712 }); 16713 $("form[name=KontaktformularFintech]").cms_form_element_visibility({ 16714 selectors: { "ancestor": "span" }, 16715 configs: [{ 16716 formElementId: "f7881780g18388134d18388186i1", 16717 unchecked: { 16718 ancestor: "#fintech_partner_container", 16719 hideElements: ["#f7881780d7897202"] 16720 }, 16721 checked: { 16722 ancestor: "#fintech_partner_container", 16723 hideElements: ["#f7881780d7897202"] 16724 } 16725 }, { 16726 formElementId: "f7881780g18388134d18388214i2", 16727 unchecked: { 16728 ancestor: "#fintech_partner_container", 16729 hideElements: ["#f7881780d7897202"] 16730 }, 16731 checked: { 16732 ancestor: "#fintech_partner_container", 16733 showElements: ["#f7881780d7897202"] 16734 } 16735 }, { 16736 formElementId: "f7881780g12301186d7894900i1", 16737 unchecked: { 16738 hideElements: ["#f7881780g12301186d18382678i2", "#f7881780g12301186d18382680i3", "#f7881780g12301186d18382682i4", "#f7881780g12301186d18382684i5"] 16739 }, 16740 checked: { 16741 showElements: ["#f7881780g12301186d18382678i2", "#f7881780g12301186d18382680i3", "#f7881780g12301186d18382682i4", "#f7881780g12301186d18382684i5"] 16742 } 16743 }, { 16744 formElementId: "f7881780g12301186d12271448i6", 16745 unchecked: { 16746 hideElements: ["#f7881780g12301186d18382696i7", "#f7881780g12301186d18382700i8", "#f7881780g12301186d18382702i9", "#f7881780g12301186d18382704i10", "#f7881780g12301186d18382706i11", "#f7881780g12301186d18382698i12"] 16747 }, 16748 checked: { 16749 showElements: ["#f7881780g12301186d18382696i7", "#f7881780g12301186d18382700i8", "#f7881780g12301186d18382702i9", "#f7881780g12301186d18382704i10", "#f7881780g12301186d18382706i11", "#f7881780g12301186d18382698i12"] 16750 } 16751 }, { 16752 formElementId: "f7881780g12301186d18382618i18", 16753 unchecked: { 16754 hideElements: ["#f7881780g12301186d7894908i19", "#f7881780g12301186d7894910i20"] 16755 }, 16756 checked: { 16757 showElements: ["#f7881780g12301186d7894908i19", "#f7881780g12301186d7894910i20"] 16758 } 16759 }, { 16760 formElementId: "f7881780g12301186d18382624i21", 16761 unchecked: { 16762 hideElements: ["#f7881780g12301186d18382724i22", "#f7881780g12301186d18382726i23", "#f7881780g12301186d18382728i24", "#f7881780g12301186d18382730i25", "#f7881780g12301186d18382732i26"] 16763 }, 16764 checked: { 16765 showElements: ["#f7881780g12301186d18382724i22", "#f7881780g12301186d18382726i23", "#f7881780g12301186d18382728i24", "#f7881780g12301186d18382730i25", "#f7881780g12301186d18382732i26"] 16766 } 16767 }, {
16768 formElementId: "f18519598g18388134d18388186i1", 16769 unchecked: { 16770 ancestor: "#fintech_partner_container", 16771 hideElements: ["#f18519598d7897202"] 16772 }, 16773 checked: { 16774 ancestor: "#fintech_partner_container", 16775 hideElements: ["#f18519598d7897202"] 16776 } 16777 }, { 16778 formElementId: "f18519598g18388134d18388214i2", 16779 unchecked: { 16780 ancestor: "#fintech_partner_container", 16781 hideElements: ["#f18519598d7897202"] 16782 }, 16783 checked: { 16784 ancestor: "#fintech_partner_container", 16785 showElements: ["#f18519598d7897202"] 16786 } 16787 }, { 16788 formElementId: "f18519598g12301186d7894900i1", 16789 unchecked: { 16790 hideElements: ["#f18519598g12301186d18382678i2", "#f18519598g12301186d18382680i3", "#f18519598g12301186d18382682i4", "#f18519598g12301186d18382684i5"] 16791 }, 16792 checked: { 16793 showElements: ["#f18519598g12301186d18382678i2", "#f18519598g12301186d18382680i3", "#f18519598g12301186d18382682i4", "#f18519598g12301186d18382684i5"] 16794 } 16795 }, { 16796 formElementId: "f18519598g12301186d12271448i6", 16797 unchecked: { 16798 hideElements: ["#f18519598g12301186d18382696i7", "#f18519598g12301186d18382700i8", "#f18519598g12301186d18382702i9", "#f18519598g12301186d18382704i10", "#f18519598g12301186d18382706i11", "#f18519598g12301186d18382698i12"] 16799 }, 16800 checked: { 16801 showElements: ["#f18519598g12301186d18382696i7", "#f18519598g12301186d18382700i8", "#f18519598g12301186d18382702i9", "#f18519598g12301186d18382704i10", "#f18519598g12301186d18382706i11", "#f18519598g12301186d18382698i12"] 16802 } 16803 }, { 16804 formElementId: "f18519598g12301186d18382618i18", 16805 unchecked: { 16806 hideElements: ["#f18519598g12301186d7894908i19", "#f18519598g12301186d7894910i20"] 16807 }, 16808 checked: { 16809 showElements: ["#f18519598g12301186d7894908i19", "#f18519598g12301186d7894910i20"] 16810 } 16811 }, { 16812 formElementId: "f18519598g12301186d18382624i21", 16813 unchecked: { 16814 hideElements: ["#f18519598g12301186d18382724i22", "#f18519598g12301186d18382726i23", "#f18519598g12301186d18382728i24", "#f18519598g12301186d18382730i25", "#f18519598g12301186d18382732i26"] 16815 }, 16816 checked: { 16817 showElements: ["#f18519598g12301186d18382724i22", "#f18519598g12301186d18382726i23", "#f18519598g12301186d18382728i24", "#f18519598g12301186d18382730i25", "#f18519598g12301186d18382732i26"] 16818 } 16819 }] 16820 }); 16821 $("form[name=KontaktformularHGS]").cms_form_element_visibility({ 16822 selectors: { "ancestor": ".optional" }, 16823 configs: [{ 16824 formElementId: "f19667066g19666938d19673202i2", 16825 checked: { 16826 ancestor: "#Kontaktdaten", 16827 showElements: ["#f19667066d19667052"] 16828 } 16829 }, { 16830 formElementId: "f19667066g19666938d19673204i1", 16831 checked: { 16832 ancestor: "#Kontaktdaten", 16833 hideElements: ["#f19667066d19667052"] 16834 } 16835 }, { 16836 formElementId: "f19667066g19666950d19673202i2", 16837 checked: { 16838 showElements: ["#f19667066d19667012"] 16839 } 16840 }, { 16841 formElementId: "f19667066g19666950d19673204i1", 16842 checked: { 16843 hideElements: ["#f19667066d19667012"] 16844 } 16845 }, { 16846 formElementId: "f19667066g19666930d19673202i1", 16847 checked: { 16848 showElements: ["#f19667066d19666988"] 16849 } 16850 }, { 16851 formElementId: "f19667066g19666930d19573636i2", 16852 checked: { 16853 hideElements: ["#f19667066d19666988"] 16854 } 16855 }, { 16856 formElementId: "f19667066g19666946d19673202i2", 16857 checked: { 16858 showElements: ["#f19667066d19667016"] 16859 } 16860 }, { 16861 formElementId: "f19667066g19666946d19673204i1", 16862 checked: { 16863 hideElements: ["#f19667066d19667016"] 16864 } 16865 }, { 16866 formElementId: "f19667066g19666934d19673202i2", 16867 checked: { 16868 showElements: ["#f19667066d19667008"] 16869 } 16870 }, { 16871 formElementId: "f19667066g19666934d19673204i1", 16872 checked: { 16873 hideElements: ["#f19667066d19667008"] 16874 } 16875 }, { 16876 formElementId: "f19667066g19666942d19666956i1", 16877 checked: { 16878 showElements: ["#bankenaufsicht-hint", "#group_desc", "#form-contact", "#next"], 16879 hideElements: ["#versicherungsaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 16880 } 16881 }, {
16882 formElementId: "f19667066g19666942d19666970i2", 16883 checked: { 16884 showElements: ["#versicherungsaufsicht-hint", "#group_desc", "#form-contact", "#next"], 16885 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 16886 } 16887 }, { 16888 formElementId: "f19667066g19666942d19666972i3", 16889 checked: { 16890 showElements: ["#wertpapieraufsicht-hint", "#group_desc", "#form-contact", "#next"], 16891 hideElements: ["#bankenaufsicht-hint", "#versicherungsaufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 16892 } 16893 }, { 16894 formElementId: "f19667066g19666942d19666966i4", 16895 checked: { 16896 showElements: ["#markmanipulation-hint", "#group_desc", "#form-contact", "#next"], 16897 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#versicherungsaufsicht-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 16898 } 16899 }, { 16900 formElementId: "f19667066g19666942d19666962i5", 16901 checked: { 16902 showElements: ["#geldwaeschepraevention-hint", "#group_desc", "#form-contact", "#next"], 16903 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#versicherungsaufsicht-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 16904 } 16905 }, { 16906 formElementId: "f19667066g19666942d19666968i6", 16907 checked: { 16908 showElements: ["#unerlaubte_geschaefte-hint", "#group_desc", "#form-contact", "#next"], 16909 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#versicherungsaufsicht-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 16910 } 16911 }, { 16912 formElementId: "f19667066g19666942d19666960i7", 16913 checked: { 16914 showElements: ["#enforcement-hint", "#group_desc", "#form-contact", "#next"], 16915 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#versicherungsaufsicht-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 16916 } 16917 }, { 16918 formElementId: "f19667066g19666942d19666958i8", 16919 checked: { 16920 showElements: ["#dma-hint"], 16921 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#versicherungsaufsicht-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint", "#group_desc", "#form-contact", "#next"] 16922 } 16923 }, { 16924 formElementId: "f19667066g19666942d19666954i9", 16925 checked: { 16926 showElements: ["#anderer_schwerpunkt-hint"], 16927 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#versicherungsaufsicht-hint", "#kundenbeziehung-hint", "#group_desc", "#form-contact", "#next"] 16928 }, 16929 }, { 16930 formElementId: "f19667066g19666942d19666964i10", 16931 checked: { 16932 showElements: ["#kundenbeziehung-hint"], 16933 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#versicherungsaufsicht-hint", "#group_desc", "#form-contact", "#next"] 16934 } 16935 }, { 16936 formElementId: "f19704388g19666938d19673202i2", 16937 checked: { 16938 ancestor: "#Kontaktdaten", 16939 showElements: ["#f19704388d19667052"] 16940 } 16941 }, { 16942 formElementId: "f19704388g19666938d19673204i1", 16943 checked: { 16944 ancestor: "#Kontaktdaten", 16945 hideElements: ["#f19704388d19667052"] 16946 } 16947 }, {
16948 formElementId: "f19704388g19666950d19673202i2", 16949 checked: { 16950 showElements: ["#f19704388d19667012"] 16951 } 16952 }, { 16953 formElementId: "f19704388g19666950d19673204i1", 16954 checked: { 16955 hideElements: ["#f19704388d19667012"] 16956 } 16957 }, { 16958 formElementId: "f19704388g19666930d19673202i1", 16959 checked: { 16960 showElements: ["#f19704388d19666988"] 16961 } 16962 }, { 16963 formElementId: "f19704388g19666930d19573636i2", 16964 checked: { 16965 hideElements: ["#f19704388d19666988"] 16966 } 16967 }, { 16968 formElementId: "f19704388g19666946d19673202i2", 16969 checked: { 16970 showElements: ["#f19704388d19667016"] 16971 } 16972 }, { 16973 formElementId: "f19704388g19666946d19673204i1", 16974 checked: { 16975 hideElements: ["#f19704388d19667016"] 16976 } 16977 }, { 16978 formElementId: "f19704388g19666934d19673202i2", 16979 checked: { 16980 showElements: ["#f19704388d19667008"] 16981 } 16982 }, { 16983 formElementId: "f19704388g19666934d19673204i1", 16984 checked: { 16985 hideElements: ["#f19704388d19667008"] 16986 } 16987 }, { 16988 formElementId: "f19704388g19666942d19666956i1", 16989 checked: { 16990 showElements: ["#bankenaufsicht-hint", "#group_desc", "#form-contact", "#next"], 16991 hideElements: ["#versicherungsaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 16992 } 16993 }, { 16994 formElementId: "f19704388g19666942d19666970i2", 16995 checked: { 16996 showElements: ["#versicherungsaufsicht-hint", "#group_desc", "#form-contact", "#next"], 16997 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 16998 } 16999 }, { 17000 formElementId: "f19704388g19666942d19666972i3", 17001 checked: { 17002 showElements: ["#wertpapieraufsicht-hint", "#group_desc", "#form-contact", "#next"], 17003 hideElements: ["#bankenaufsicht-hint", "#versicherungsaufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 17004 } 17005 }, { 17006 formElementId: "f19704388g19666942d19666966i4", 17007 checked: { 17008 showElements: ["#markmanipulation-hint", "#group_desc", "#form-contact", "#next"], 17009 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#versicherungsaufsicht-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 17010 } 17011 }, { 17012 formElementId: "f19704388g19666942d19666962i5", 17013 checked: { 17014 showElements: ["#geldwaeschepraevention-hint", "#group_desc", "#form-contact", "#next"], 17015 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#versicherungsaufsicht-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 17016 } 17017 }, { 17018 formElementId: "f19704388g19666942d19666968i6", 17019 checked: { 17020 showElements: ["#unerlaubte_geschaefte-hint", "#group_desc", "#form-contact", "#next"], 17021 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#versicherungsaufsicht-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 17022 } 17023 }, { 17024 formElementId: "f19704388g19666942d19666960i7", 17025 checked: { 17026 showElements: ["#enforcement-hint", "#group_desc", "#form-contact", "#next"], 17027 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#versicherungsaufsicht-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint"] 17028 } 17029 }, {
17030 formElementId: "f19704388g19666942d19666958i8", 17031 checked: { 17032 showElements: ["#dma-hint"], 17033 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#versicherungsaufsicht-hint", "#anderer_schwerpunkt-hint", "#kundenbeziehung-hint", "#group_desc", "#form-contact", "#next"] 17034 } 17035 }, { 17036 formElementId: "f19704388g19666942d19666954i9", 17037 checked: { 17038 showElements: ["#anderer_schwerpunkt-hint"], 17039 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#versicherungsaufsicht-hint", "#kundenbeziehung-hint", "#group_desc", "#form-contact", "#next"] 17040 } 17041 }, { 17042 formElementId: "f19704388g19666942d19666964i10", 17043 checked: { 17044 showElements: ["#kundenbeziehung-hint"], 17045 hideElements: ["#bankenaufsicht-hint", "#wertpapieraufsicht-hint", "#markmanipulation-hint", "#geldwaeschepraevention-hint", "#unerlaubte_geschaefte-hint", "#enforcement-hint", "#dma-hint", "#anderer_schwerpunkt-hint", "#versicherungsaufsicht-hint", "#group_desc", "#form-contact", "#next"] 17046 } 17047 } 17048 ] 17049 }); 17050 $("form[name=Kontaktformular-Marktmanipulation]").cms_form_element_visibility({ 17051 selectors: { "ancestor": ".optional" }, 17052 configs: [{ 17053 formElementId: "f239186g239160d241496i1", 17054 checked: { 17055 showElements: ["#Marktmanipulation_Sachverhalt-hint"], 17056 hideElements: ["#Marktmanipulation_hinweisgberschutz-hint"] 17057 } 17058 }, 17059 { 17060 formElementId: "f239186g239160d241488i2", 17061 checked: { 17062 showElements: ["#Marktmanipulation_hinweisgberschutz-hint"], 17063 hideElements: ["#Marktmanipulation_Sachverhalt-hint"] 17064 } 17065 } 17066 ] 17067 }); 17068 $("form[name=Kontaktformular-UnerlaubteGeschaefte]").cms_form_element_visibility({ 17069 selectors: { "ancestor": ".optional" }, 17070 configs: [{ 17071 formElementId: "f770866g770976d770984i1", 17072 checked: { 17073 showElements: ["#Marktmanipulation_Sachverhalt-hint"], 17074 hideElements: ["#Marktmanipulation_hinweisgberschutz-hint"] 17075 } 17076 }, 17077 { 17078 formElementId: "f770866g770976d770980i2", 17079 checked: { 17080 showElements: ["#Marktmanipulation_hinweisgberschutz-hint"], 17081 hideElements: ["#Marktmanipulation_Sachverhalt-hint"] 17082 } 17083 } 17084 ] 17085 }); 17086}; 17087cms.connectFormElements(); 17088 17089 /* Ende connectFormElements */ 17090 /* Start init */ 17091 "use strict"; // noinspection ES6ConvertVarToLetConst, JSUnusedGlobalSymbols 17092$(function () { 17093 const $body = $('body'),$html = $('html'), 17094 $content = $('.content'); 17095 17096 const minBreakpoint = 1, 17097 mediumBreakpoint = 768, 17098 largeBreakpoint = 1025, 17099 xLargeBreakpoint = 1439, 17100 xxLargeBreakpoint = 1919; 17101 17102 // header-height slim 17103 $body.css('--header-height', `${$('.js-headerheight').outerHeight()}px`); 17104 window.addEventListener('resize', () => { 17105 $body.css('--header-height', `${$('.js-headerheight').outerHeight()}px`); 17106 }); 17107 17108 // Deaktivierung von Animationen für automatisierte Tests (Backstop, Cypress, ...) 17109 if (typeof document.cookie !== 'undefined' && document.cookie.match('testmode')) { 17110 $.fx.off = true; 17111 $body.addClass('no-transition'); 17112 } 17113 17114 $body.addClass('js-on').removeClass('js-off'); 17115 17116 // BITV: Alle Flyouts, die über hover angezeigt werden, müssen 17117 // anderweitig (hier: über Esc) schlieÃbar sein 17118 $body.on('keydown', function (ev) { 17119 const key = ev.key; 17120 if (key === 'Esc' || key === 'Escape') { 17121 $body.trigger('closeAllFlyouts.cms'); 17122 } 17123 }); 17124 $body.on('closeAllFlyouts.cms', function () { 17125 $body.find('.mejs__captions-selector').not('.mejs__offscreen'). 17126 addClass('mejs__offscreen'); 17127 $body.find('.mejs__volume-slider').not(':hidden'). 17128 hide(); 17129 }); 17130 17131 function getAllNextNodes(node) { 17132 const result = []; 17133 let next; 17134 while (next = node.nextSibling) { 17135 result.push(next); 17136 node = next; 17137 } 17138 return result; 17139 } 17140 17141 const randnummerAuralLabel = "Randnummer"; 17142 $('.js-randnummer').each((i, nummer) => { 17143 const $nummer = $(nummer); 17144 const $content = $(document.createElement('span')); 17145 const $container = $nummer.parent(); 17146 $nummer. 17147 attr({ 17148 'aria-label': `${randnummerAuralLabel}: ${$nummer.text()}`, 17149 title: `${randnummerAuralLabel}: ${$nummer.text()}` 17150 }). 17151 wrapInner($(document.createElement('span')).attr('aria-hidden', 'true')); 17152 $nummer.after($content.append(getAllNextNodes(nummer)).addClass('c-randnummer__content')); 17153 $container.addClass('c-randnummer__container'); 17154 }); 17155 17156 const $loadNavigation = $('[data-navigation-url]'); 17157 const fetchURL = $loadNavigation.data('navigation-url'); 17158 if (fetchURL) { 17159 fetch(fetchURL).then((res) => res.text()).then((html) => { 17160 $loadNavigation.html(html); 17161 17162 let path = $('[data-navigation-nn-path]').data('navigation-nn-path').split('/'); 17163 path.forEach((id) => 17164 $(`[data-navigation-nn="${id}"]`).children('a, button, strong').attr("aria-current", "true") 17165 ); 17166 $(`[data-navigation-nn="${path.pop()}"]`).children('a, button, strong').attr("aria-current", "page"); 17167 17168 // Flyout 17169 $('.js-flyout-nav-level1-tabs-list').cms_toggle({ 17170 elements: '> .js-flyout-nav-level1 .js-flyout-button-level1 + .js-flyout-level1', 17171 heading: '> .js-flyout-nav-level1 .js-flyout-button-level1', 17172 mode: 'accordion', 17173 responsive: [{ 17174 breakpoint: 1026, 17175 mode: 'none' 17176 }] 17177 }); 17178 17179 const $searchFlyout = $('.js-flyout-search'); 17180 17181 // Suchflyout 17182 $searchFlyout.cms_simple_toggle({ 17183 item: '.js-flyout-search-item', 17184 opener: '.js-flyout-search-button', 17185 closeOnFocusout: true 17186 }); 17187 17188 // Flyout Level 2 17189 $('.js-flyout-nav-level2').cms_simple_toggle({ 17190 item: '.js-flyout-level2', 17191 opener: '.js-flyout-button-level2', 17192 closeOnFocusout: true 17193 }); 17194 17195 // Flyout Level 3 17196 $('.js-flyout-nav-level3').cms_simple_toggle({ 17197 item: '.js-flyout-level3', 17198 opener: '.js-flyout-button-level3', 17199 closeOnFocusout: true 17200 }); 17201 17202 // navSkip öffnet die Suche in der Primärnavigation und fokussiert das Eingabefeld 17203 $('.js-navskip-search').on('click', function (ev) { 17204 ev.preventDefault(); 17205 $searchFlyout.trigger('open'); 17206 $searchFlyout.find('input[type="search"]').trigger('focus'); 17207 }); 17208 17209 // Beim Ãffnen der Suche über den Button in der Primärnavigation, setze Fokus ins Eingabefeld 17210 $searchFlyout.on('afterOpen.simple_toggle.cms', function (ev) { 17211 const menuToggle = $('.js-nav-mobile--toggle'); 17212 const triggeringEvent = ev.relatedEvent; 17213 const triggeringElement = $(triggeringEvent.target).closest('button'); 17214 if (menuToggle.is('[aria-expanded="true"]')) { 17215 menuToggle.click(); 17216 } 17217 if (triggeringElement.is('[aria-expanded="true"]')) { 17218 $searchFlyout.find('input[type="search"]').trigger('focus'); 17219 } 17220 }); 17221 17222 // Mobile Navigation 17223 $('.js-nav-mobile').cms_tree_navigation({ 17224 mode: 'overlay', 17225 classes: { 17226 bodyMenuOpened: 's-mobile-menu-opened', 17227 bodyMenuClosed: 's-mobile-menu-closed' 17228 } 17229 }); 17230 }); 17231 } 17232
17233 //Open Details if anchored element is within 17234 $(`${window.location.hash}`).parents('details').attr('open', 'open'); 17235 17236 $content.cms_responsiveTables(); 17237 17238 /* Scroll check for tables. */ 17239 const responsiveTableClass = '.l-responsive-table'; 17240 const tableContainers = document.querySelectorAll(responsiveTableClass); 17241 17242 // Add wrapper element 17243 function create_responsive_table_wrapper(table_container) { 17244 const wrapper_div = document.createElement('div'); 17245 wrapper_div.classList.add('l-responsive-table__wrapper'); 17246 17247 const scroll_clone_div = document.createElement('div'); 17248 scroll_clone_div.classList.add('responsiveTableScrollClone'); 17249 scroll_clone_div.setAttribute('tabindex', '-1'); 17250 wrapper_div.appendChild(scroll_clone_div); 17251 17252 const table_clone_div = document.createElement('div'); 17253 table_clone_div.classList.add('responsiveTableClone'); 17254 table_clone_div.style.width = `${table_container.querySelector('table').getBoundingClientRect().width}px`; 17255 scroll_clone_div.appendChild(table_clone_div); 17256 17257 // Erstellen Sie eine Kopie des table_container, bevor Sie es entfernen
17258 const table_container_copy = table_container.cloneNode(true); 17259 wrapper_div.appendChild(table_container_copy); 17260 17261 // Ersetzen Sie das ursprüngliche table_container durch das wrapper_div 17262 table_container.parentNode.replaceChild(wrapper_div, table_container); 17263 17264 return wrapper_div; 17265 } 17266 17267 function syncScroll(element1, element2) { 17268 function scrollHandler(event) { 17269 if (event.target === element1) { 17270 element2.scrollTo(element1.scrollLeft, 0); 17271 } else { 17272 element1.scrollTo(element2.scrollLeft, 0); 17273 } 17274 } 17275 17276 $(element1).on('scroll', scrollHandler); 17277 $(element2).on('scroll', scrollHandler); 17278 } 17279 17280 function scrollState(containerSelector) { 17281 const containers = document.querySelectorAll(containerSelector); 17282 containers.forEach((element) => { 17283 if (element.scrollWidth <= element.clientWidth) { 17284 element.classList.remove('is-scroll-right', 'is-scroll-left'); 17285 } else if (element.scrollLeft === 0) { 17286 element.classList.remove('is-scroll-left'); 17287 element.classList.add('is-scroll-right'); 17288 } else if (element.scrollLeft + element.clientWidth >= element.scrollWidth) { 17289 element.classList.remove('is-scroll-right'); 17290 element.classList.add('is-scroll-left'); 17291 } else { 17292 element.classList.add('is-scroll-left', 'is-scroll-right'); 17293 } 17294 }); 17295 } 17296 17297 document.addEventListener('DOMContentLoaded', () => { 17298 scrollState(responsiveTableClass); 17299 }); 17300 window.addEventListener('resize', () => { 17301 scrollState(responsiveTableClass); 17302 }); 17303 17304 // Erstelle Wrapper und synchronisiere den Scroll für jede Tabelle 17305 tableContainers.forEach((table_container) => { 17306 const wrapper = create_responsive_table_wrapper(table_container); 17307 const scroll_clone = wrapper.querySelector('.responsiveTableScrollClone'); 17308 const table = wrapper.querySelector('.l-responsive-table'); 17309 syncScroll(scroll_clone, table); 17310 17311 table.addEventListener('scroll', () => { 17312 scrollState(responsiveTableClass); 17313 }); 17314 }); 17315 17316 const $videoAudio = $('video, audio'); 17317 const $notVimeo = $videoAudio.filter((index, el) => $(el).find('source[type|="video/vimeo"]').length < 1); 17318 const $vimeo = $videoAudio.filter((index, el) => $(el).find('source[type|="video/vimeo"]').length > 0); 17319 17320 cms.requireCMSComponent('bundle_multimedia', $notVimeo).done(function ($media) { 17321 $media.cms_multimedia({ 17322 settings: { 17323 mediaelementplayerOptions: { 17324 iconSprite: $media.attr('data-icons-controls'), 17325 iconSpritePathA11y: $media.attr('data-icons-a11y') 17326 } 17327 } 17328 }); 17329 }); 17330 17331 cms.requireCMSComponent('bundle_multimedia', $vimeo).done(function ($media) { 17332 $media.cms_multimedia({ 17333 settings: { 17334 mediaelementplayerOptions: { 17335 features: '' 17336 } 17337 } 17338 }); 17339 }); 17340 17341 const $cookiebanner = $('#cookiebanner'); 17342 17343 // cookiebanner 17344 $cookiebanner.cms_cookiebanner({ 17345 selectors: { 17346 dialog: '#cookiebanner' 17347 }, 17348 modal: true, 17349 cookies: { 17350 neccessary: { 17351 off: () => { 17352 document.cookie = 'cmsbanner=closed; path=/'; 17353 } 17354 }, 17355 statistics: { 17356 on: 'matomo', 17357 off: 'matomo' 17358 } 17359 } 17360 }).on('open', updateCookieBanner).on('close', updateCookieBanner); 17361 17362 //prevent Scrolling when cookiebanner is opened 17363 updateCookieBanner(); 17364 17365 function updateCookieBanner() { 17366 if ($cookiebanner.attr('open')) { 17367 $html.css({ 'overflow': 'hidden', 'scrollbar-gutter': 'stable' }); 17368 } else { 17369 $html.css({ 'overflow': 'initial' }); 17370 } 17371 } 17372 17373 $('.js-toc').cms_simple_toggle({ 17374 item: '.js-toc__list', 17375 opener: '.js-toc__button', 17376 closeOnFocusout: true 17377 }); 17378 17379 $('.js-toc-module').cms_simple_toggle({ 17380 item: '> .js-toc-module__list', 17381 opener: '> .js-toc-module__button', 17382 closeOnFocusout: true 17383 }); 17384 17385 // scroll service nav into view 17386 $('.c-nav-service-meta a').on('focusin', function () { 17387 if ($('.js-header').hasClass('is-sticky')) { 17388 window.scrollTo({ top: 0, behavior: 'smooth' }); 17389 } 17390 }); 17391 17392 // Richtext-Accordion 17393 $content.cms_toggle({ 17394 richtext: true, 17395 richtextWrapper: '<div class="c-richtext-accordion"/>', 17396 richtextStart: '.js-richtext-accordion-start', 17397 richtextEnd: '.js-richtext-accordion-end', 17398 richtextControl: '.c-richtext-accordion__opener', 17399 heading: '.c-richtext-accordion__opener', 17400 responsive: null, 17401 accordionCloseOther: false 17402 }).on('afterAnimationOpen.toggle.cms', function () { 17403 var tabelWidth = $(this).find('.c-richtext-accordion table').width(); 17404 $(this).find('.c-richtext-accordion .responsiveTableClone').css('width', tabelWidth); 17405 }); 17406 17407 // richtext-tab-accordion 17408 $content.cms_toggle({ 17409 mode: 'tabs', 17410 richtext: true, 17411 richtextWrapper: '<div class="c-richtext-tab-accordion"/>', 17412 richtextStart: '.js-richtext-tab-accordion-start', 17413 richtextEnd: '.js-richtext-tab-accordion-end', 17414 richtextControl: '.js-richtext-tab-accordion__opener',
17415 richtextTabControlContainerItem: '<li class="c-richtext-tab-accordion__item"></li>', 17416 richtextTabControlContainer: '<ul class="c-richtext-tab-accordion__list tabs-list"></ul>', 17417 responsive: [{ 17418 breakpoint: largeBreakpoint, 17419 mode: 'accordion' 17420 }] 17421 }); 17422 17423 // Accordions (z.B. Footer) 17424 $('.js-accordion-footer').cms_toggle({ 17425 accordionCloseOther: false, 17426 elements: '.js-accordion-footer-entry', 17427 heading: '.js-accordion-footer-opener', 17428 accordionContainer: '.js-accordion-footer-container' 17429 }); 17430 17431 // Accordions (z.B. Glossar) 17432 $('.js-accordion').cms_toggle({ 17433 accordionCloseOther: false, 17434 elements: '.js-accordion-entry', 17435 heading: '.js-accordion-opener', 17436 accordionContainer: '.js-accordion-container' 17437 }); 17438 17439 // c-related 17440 $('.js-related').cms_toggle({ 17441 hashControlled: true, 17442 accordionCloseOther: false, 17443 elements: '.js-related-entry', 17444 heading: '.js-related-opener', 17445 accordionContainer: '.js-related__list' 17446 }); 17447 17448 // HashControlled-Accordions (z.B. FAQList) 17449 $('.js-accordion-hashControlled').cms_toggle({ 17450 hashControlled: true, 17451 accordionCloseOther: false, 17452 elements: '.js-accordion-entry', 17453 heading: '.js-accordion-opener', 17454 accordionContainer: '.js-accordion-container' 17455 }); 17456 17457 // cms_toggle without hashControl 17458 $('.js-tabs').cms_toggle({ 17459 mode: 'tabs', 17460 tabControls: '> .tabs-list > li button', 17461 responsive: [{ 17462 breakpoint: largeBreakpoint, 17463 mode: 'accordion' 17464 }], 17465 accordionCloseOther: false 17466 }); 17467 17468 //Richtext-Accordion mit OpenGraphTags versehen 17469 $('.c-richtext-accordion').each(function (i, accordion) { 17470 const $accordion = $(accordion); 17471 $accordion.attr('itemscope', '').attr('itemtype', 'https://schema.org/FAQPage'); 17472 $accordion.find('.c-richtext-accordion__opener').each(function (j, el) { 17473 const question = $(el); 17474 question.find('button').attr('itemprop', 'name'); 17475 question.next('div').attr('itemscope', '').attr('itemprop', 'acceptedAnswer').attr('itemtype', 'https://schema.org/Answer'). 17476 find('p').first().attr('itemprop', 'text'); 17477 const content = question.nextUntil('.c-richtext-accordion__opener').add(question); 17478 content.wrapAll('<div itemScope itemProp="mainEntity" itemType="https://schema.org/Question"></div>'); 17479 }); 17480 }); 17481 17482 // Drucken 17483 $('.js-print').on('click', function (e) { 17484 e.preventDefault(); 17485 window.print(); 17486 }); 17487 17488 // Share 17489 $('.js-share').cms_simple_toggle({ 17490 opener: '.js-share-button', 17491 item: '.js-share-box', 17492 showClass: 'visible', 17493 hideClass: 'invisible', 17494 closeOnFocusout: true 17495 }); 17496 17497 // AutoSuggest 17498 $('.js-autosuggest').cms_autosuggest(); 17499 17500 // Suche - Facetten & Sortierung 17501 $('.js-facet, .js-sort').cms_simple_toggle(); 17502 17503 // SchlieÃt alle details/summary bei Escape 17504 document.addEventListener('keydown', function (event) { 17505 if (event.key === 'Escape') { 17506 // Alle offenen <details>-Elemente finden 17507 document.querySelectorAll('details[open]').forEach(function (details) { 17508 details.removeAttribute('open'); 17509 }); 17510 } 17511 }); 17512 17513 // SchlieÃt bestimmte geöffnete details/summary bei focusout 17514 document.addEventListener('focusout', function (event) { 17515 const details = event.target.closest('details.js-close-on-blur'); 17516 if (!details) return; 17517 17518 setTimeout(function () { 17519 const next = document.activeElement; 17520 if (!next || !details.contains(next)) { 17521 details.removeAttribute('open'); 17522 } 17523 }, 0); 17524 }); 17525 17526 // scroll-control 17527 $html.cms_scroll_control({ 17528 cookiebannerAnimationDuration: 900, // gsb_banner.options.animationSpeed ist auch 900 17529 scrollAnimationDuration: 600, 17530 scrollOnPageLoad: true, 17531 scrollOnAnchorLinkClick: true, 17532 scrollOffset: function () { 17533 return 100; 17534 }, 17535 selectors: { 17536 anchorLinks: 'a[href*="#"]:not([href="#"]):not(.hash-controlled)', 17537 cookiebanner: '#c-cookiebanner' // Berücksichtigen des cookiebanners, verwendet cookiebannerAnimationDuration 17538 } 17539 }); 17540 17541 // Formular - bei Fehlern im Formular zum ersten Fehlerlink springen 17542 const $formErrors = $('.js-error-list'); 17543 if ($formErrors.length > 0) { 17544 setTimeout(function () { 17545 $formErrors.first().get(0).scrollIntoView(); 17546 $($formErrors.find('a').first()).focus().select(); 17547 }); 17548 } else { 17549 const $errorInput = $('[aria-invalid=true]').first(); 17550 if ($errorInput.length) { 17551 setTimeout(function () { 17552 $errorInput.get(0).scrollIntoView(); 17553 $errorInput.focus(); 17554 }); 17555 } 17556 } 17557 17558 // Formular 17559 $('.js-char-count').cms_form_utility_char_limit(); 17560 17561 //echarts 17562 $('.js-simple-toggle').cms_simple_toggle(); 17563 17564 function eChartInit() { 17565 if (cms.chartConfigs) { 17566 cms.requireCMSComponent('bundle_echarts', $('.js-chart')).done(function ($charts) { 17567 $charts.each((i, el) => { 17568 const $chart = $(el); 17569 const variant = $chart.attr('data-chart-variant'); 17570 const theme = $chart.attr('data-chart-theme'); 17571 const themeDark = `${theme}-dark`; 17572 17573 if (cms.chartConfigs[variant]) { 17574 $chart.cms_echarts({ 17575 libConfig: cms.chartConfigs[variant], 17576 themes: { 17577 default: theme, 17578 darkMode: themeDark 17579 } 17580 }); 17581 } else { 17582 throw Error( 17583 `Keine Konfig für die Diagramm-Variante '${variant}' gefunden. Bitte prüfe,` + 17584 ' ob die Konfiguration im Browser geladen wird und' + 17585 ' ob der "Glue"-Code um den Beispiel-Code herum (a) vorhanden ist und (b) korrekt ist' 17586 ); 17587 } 17588 }); 17589 }); 17590 } 17591 } 17592 17593 eChartInit(); 17594 17595 // Slider Numbers 17596 cms.requireCMSComponent('bundle_slideshow', $('.js-carousel, .js-carousel-dialog')).done(function ($jsCarousel) { 17597 $jsCarousel.each(function () { 17598 const base = $(this); 17599 const slides = { 17600 small: Number.parseInt($(this).attr('data-small-slides')), 17601 medium: Number.parseInt($(this).attr('data-medium-slides')), 17602 large: Number.parseInt($(this).attr('data-large-slides')), 17603 xLarge: Number.parseInt($(this).attr('data-xlarge-slides')), 17604 xxLarge: Number.parseInt($(this).attr('data-xxlarge-slides')) 17605 }; 17606 17607 const gap = { 17608 small: Number.parseInt($(this).attr('data-small-gap')), 17609 medium: Number.parseInt($(this).attr('data-medium-gap')), 17610 large: Number.parseInt($(this).attr('data-large-gap')), 17611 xLarge: Number.parseInt($(this).attr('data-xlarge-gap')), 17612 xxLarge: Number.parseInt($(this).attr('data-xxlarge-gap')) 17613 }; 17614 17615 const autoplay = $(this).attr('data-autoplay') ? $(this).attr('data-autoplay').toLowerCase() === 'true' : false, 17616 infinite = $(this).attr('data-infinite') ? $(this).attr('data-infinite').toLowerCase() === 'true' : false;
17617 17618 const responsiveObj = { 17619 small: { breakpoint: mediumBreakpoint, settings: {} }, 17620 medium: { breakpoint: largeBreakpoint, settings: {} }, 17621 large: { breakpoint: xLargeBreakpoint, settings: {} }, 17622 xLarge: { breakpoint: xxLargeBreakpoint, settings: {} } 17623 }; 17624 17625 const responsiveArr = []; 17626 Object.keys(responsiveObj).forEach((breakpoint) => { 17627 const page = {}; 17628 const trackOptions = { page: page }; 17629 let shouldAddBreakpoint = !Number.isNaN(slides[breakpoint]) || !Number.isNaN(gap[breakpoint]); 17630 17631 if (!Number.isNaN(slides[breakpoint]) && !Number.isNaN(gap[breakpoint])) { 17632 page.slideCount = slides[breakpoint]; 17633 page.gap = gap[breakpoint]; 17634 } else if (!Number.isNaN(gap[breakpoint])) page.gap = gap[breakpoint];else 17635 if (!Number.isNaN(slides[breakpoint])) page.slideCount = slides[breakpoint]; 17636 17637 // ######## Uebertrage von responsiveObj to responsiveArr, falls settings wenigstens einen Key hat 17638 if (shouldAddBreakpoint) { 17639 responsiveObj[breakpoint].settings.trackOptions = trackOptions; 17640 responsiveArr.push(responsiveObj[breakpoint]); 17641 } 17642 }); 17643 17644 base.cms_carousel({ 17645 trackOptions: { 17646 page: { 17647 slideCount: !Number.isNaN(slides['xxLarge']) ? slides['xxLarge'] : 1, 17648 gap: !Number.isNaN(gap['xxLarge']) ? gap['xxLarge'] : 0 17649 }, 17650 behavior: { 17651 infiniteSlide: false, 17652 adaptiveTrackHeight: true 17653 } 17654 }, 17655 behavior: { 17656 autoplay: autoplay 17657 }, 17658 responsive: responsiveArr 17659 }); 17660 }); 17661 }); 17662 17663 // JS Carousel for Gallery 17664 cms.requireCMSComponent('bundle_slideshow', $('.js-gallery, .js-gallery-dialog')).done(function ($galleryCarousel) { 17665 $galleryCarousel.each(function () { 17666 const base = $(this); 17667 const slides = { 17668 small: Number.parseInt($(this).attr('data-small-slides')), 17669 medium: Number.parseInt($(this).attr('data-medium-slides')), 17670 large: Number.parseInt($(this).attr('data-large-slides')), 17671 xLarge: Number.parseInt($(this).attr('data-xlarge-slides')), 17672 xxLarge: Number.parseInt($(this).attr('data-xxlarge-slides')) 17673 }; 17674 17675 const gap = { 17676 small: Number.parseInt($(this).attr('data-small-gap')), 17677 medium: Number.parseInt($(this).attr('data-medium-gap')), 17678 large: Number.parseInt($(this).attr('data-large-gap')), 17679 xLarge: Number.parseInt($(this).attr('data-xlarge-gap')), 17680 xxLarge: Number.parseInt($(this).attr('data-xxlarge-gap')) 17681 }; 17682 17683 const autoplay = $(this).attr('data-autoplay') ? $(this).attr('data-autoplay').toLowerCase() === 'true' : false, 17684 infinite = $(this).attr('data-infinite') ? $(this).attr('data-infinite').toLowerCase() === 'true' : false; 17685 17686 const responsiveObj = { 17687 small: { breakpoint: mediumBreakpoint, settings: {} }, 17688 medium: { breakpoint: largeBreakpoint, settings: {} }, 17689 large: { breakpoint: xLargeBreakpoint, settings: {} }, 17690 xLarge: { breakpoint: xxLargeBreakpoint, settings: {} } 17691 }; 17692 17693 const responsiveArr = []; 17694 Object.keys(responsiveObj).forEach((breakpoint) => { 17695 const page = {}; 17696 const trackOptions = { page: page }; 17697 let shouldAddBreakpoint = !Number.isNaN(slides[breakpoint]) || !Number.isNaN(gap[breakpoint]); 17698 17699 if (!Number.isNaN(slides[breakpoint]) && !Number.isNaN(gap[breakpoint])) { 17700 page.slideCount = slides[breakpoint]; 17701 page.gap = gap[breakpoint]; 17702 } else if (!Number.isNaN(gap[breakpoint])) page.gap = gap[breakpoint];else 17703 if (!Number.isNaN(slides[breakpoint])) page.slideCount = slides[breakpoint]; 17704 17705 // ######## Uebertrage von responsiveObj to responsiveArr, falls settings wenigstens einen Key hat 17706 if (shouldAddBreakpoint) { 17707 responsiveObj[breakpoint].settings.trackOptions = trackOptions; 17708 responsiveArr.push(responsiveObj[breakpoint]); 17709 } 17710 }); 17711 17712 base.cms_carousel({ 17713 trackOptions: { 17714 page: { 17715 slideCount: !Number.isNaN(slides['xxLarge']) ? slides['xxLarge'] : 1, 17716 gap: !Number.isNaN(gap['xxLarge']) ? gap['xxLarge'] : 0 17717 }, 17718 behavior: { 17719 infiniteSlide: infinite, 17720 adaptiveTrackHeight: true 17721 } 17722 }, 17723 responsive: responsiveArr 17724 }); 17725 }); 17726 17727 $('.js-lightbox-opener').on("click", function () { 17728 const slideNumber = Number.parseInt($(this).attr('data-sli
17728de-number')); 17729 console.log(slideNumber); 17730 if (!Number.isNaN(slideNumber)) { 17731 setTimeout(() => { 17732 $('.js-gallery-dialog').trigger($.Event('goto.carousel', { movement: slideNumber })); 17733 }, 300); 17734 } 17735 }); 17736 17737 $('.c-lightbox__closer, .l-carousel__button').on("click", () => { 17738 $('video').trigger('pause'); 17739 $('iframe').each(function () { 17740 this.contentWindow.postMessage('{"event":"command","func":"stopVideo","args":""}', '*'); 17741 }); 17742 }); 17743 }); 17744 17745 // slideshow: for timeline 17746 cms.requireCMSComponent('bundle_slideshow', $('.js-timeline')).done(function ($jsCarousel) { 17747 $jsCarousel.each(function () { 17748 const base = $(this); 17749 const slides = { 17750 small: Number.parseInt($(this).attr('data-small-slides')), 17751 medium: Number.parseInt($(this).attr('data-medium-slides')), 17752 large: Number.parseInt($(this).attr('data-large-slides')), 17753 xLarge: Number.parseInt($(this).attr('data-xlarge-slides')), 17754 xxLarge: Number.parseInt($(this).attr('data-xxlarge-slides')) 17755 }; 17756 17757 const gap = { 17758 small: Number.parseInt($(this).attr('data-small-gap')), 17759 medium: Number.parseInt($(this).attr('data-medium-gap')), 17760 large: Number.parseInt($(this).attr('data-large-gap')), 17761 xLarge: Number.parseInt($(this).attr('data-xlarge-gap')), 17762 xxLarge: Number.parseInt($(this).attr('data-xxlarge-gap')) 17763 }; 17764 17765 const responsiveObj = { 17766 small: { breakpoint: mediumBreakpoint, settings: {} }, 17767 medium: { breakpoint: largeBreakpoint, settings: {} }, 17768 large: { breakpoint: xLargeBreakpoint, settings: {} }, 17769 xLarge: { breakpoint: xxLargeBreakpoint, settings: {} } 17770 }; 17771 17772 const responsiveArr = []; 17773 Object.keys(responsiveObj).forEach((breakpoint) => { 17774 const page = {}; 17775 const trackOptions = { page: page }; 17776 let shouldAddBreakpoint = !Number.isNaN(slides[breakpoint]) || !Number.isNaN(gap[breakpoint]); 17777 17778 if (!Number.isNaN(slides[breakpoint]) && !Number.isNaN(gap[breakpoint])) { 17779 page.slideCount = slides[breakpoint]; 17780 page.gap = gap[breakpoint]; 17781 } else if (!Number.isNaN(gap[breakpoint])) page.gap = gap[breakpoint];else 17782 if (!Number.isNaN(slides[breakpoint])) page.slideCount = slides[breakpoint]; 17783 17784 // ######## Uebertrage von responsiveObj to responsiveArr, falls settings wenigstens einen Key hat 17785 if (shouldAddBreakpoint) { 17786 responsiveObj[breakpoint].settings.trackOptions = trackOptions; 17787 responsiveArr.push(responsiveObj[breakpoint]); 17788 } 17789 }); 17790 17791 base.cms_carousel({ 17792 behavior: { 17793 shouldAlwaysInit: true 17794 }, 17795 trackOptions: { 17796 page: { 17797 slideCount: !Number.isNaN(slides['xxLarge']) ? slides['xxLarge'] : 1, 17798 gap: !Number.isNaN(gap['xxLarge']) ? gap['xxLarge'] : 0 17799 } 17800 }, 17801 responsive: responsiveArr 17802 }); 17803 }); 17804 }); 17805 17806 // Dialog 17807 $('dialog').not('.c-cookiebanner').cms_dialog(); 17808 17809 17810 $('[data-example-client-validation]').before( 17811 $("<span></span>"). 17812 addClass('js-clientsidevalidation-errmsg'). 17813 append("<strong class='formError'>Pflichtfeld nicht ausgefüllt.</strong>") 17814 ); 17815 $('.js-search-field').cms_fancy_selects(); 17816 17817 $('.js-result-list-filter').cms_result_list_filter(); 17818 17819 17820 $('.js-flip-card').cms_flip_card(); 17821 17822 // Flip-Cards (c-flip-card__front und c-flip-card__back) in der Timeline sollen nicht fokussierbar sein (GSBBAFIN-257) 17823 const $front = $('.js-timeline .c-flip-card__front'); 17824 const $back = $('.js-timeline .c-flip-card__back'); 17825 17826 if ($front.attr('tabindex') === '0') { 17827 $front.removeAttr('tabindex'); 17828 } 17829 17830 $('.js-timeline .js-flip-card-button').on('click', function () { 17831 $front.each(function (index, element) { 17832 if ($(element).attr('tabindex') === '0') { 17833 $(element).removeAttr('tabindex'); 17834 $(element).children().first().attr('tabindex', '0'); 17835 } else if ($(element).attr('tabindex') === '-1') { 17836 $(element).children().first().attr('tabindex', '-1'); 17837 } 17838 }); 17839 17840 $back.each(function (index, element) { 17841 if ($(element).attr('tabindex') === '0') { 17842 $(element).removeAttr('tabindex'); 17843 $(element).children().first().attr('tabindex', '0'); 17844 } else if ($(element).attr('tabindex') === '-1') { 17845 $(element).children().first().attr('tabindex', '-1'); 17846 } 17847 }); 17848 }); 17849 17850 function hasParentWithTabindexMinusOne(element) { 17851 return $(element).parents('[tabindex="-1"]').length > 0; 17852 } 17853 17854 let observer = new MutationObserver((mutationsList) => { 17855 for (const mutation of mutationsList) { 17856 if ( 17857 mutation.type === 'attributes' && 17858 mutation.attributeName === 'tabindex') 17859 { 17860 const target = mutation.target; 17861 17862 if ( 17863 target.getAttribute('tabindex') !== '-1' && 17864 hasParentWithTabindexMinusOne(target)) 17865 { 17866 target.setAttribute('tabindex', '-1'); 17867 } 17868 } 17869 } 17870 }); 17871 17872 document.querySelectorAll('.js-flip-card-button').forEach((el) => { 17873 observer.observe(el, { 17874 attributes: true, 17875 attributeFilter: ['tabindex'] 17876 }); 17877 }); 17878 17879 17880 cms.requireCMSComponent('bundle_animate_number', $('.js-teaser-number__number')).done(function ($animate_numbers) { 17881 $animate_numbers.cms_animate_number({ 17882 triggerPositionOffsetPercent: 80 17883 }); 17884 }); 17885 17886 17887 // Social Media Consent Wrapper 17888 const $mastodonTeasers = $('.js-mastodon-consent-reload'). 17889 cms_consent_reload({ cookieName: 'cms_consent_mastodon' }). 17890 on('afterConsent.consent_reload.cms', () => $mastodonTeasers.trigger('consent.consent_reload.cms')); 17891 const $linkedinTeasers = $('.js-linkedin-consent-reload'). 17892 cms_consent_reload({ cookieName: 'cms_consent_linkedin' }). 17893 on('afterConsent.consent_reload.cms', () => $linkedinTeasers.trigger('consent.consent_reload.cms')); 17894 const $instagramTeasers = $('.js-instagram-consent-reload'). 17895 cms_consent_reload({ cookieName: 'cms_consent_instagram' }). 17896 on('afterConsent.consent_reload.cms', () => $instagramTeasers.trigger('consent.consent_reload.cms')); 17897 const $videoTeasers = $('.js-video-consent-reload'). 17898 cms_consent_reload({ cookieName: 'cms_consent_video' }). 17899 on('afterConsent.consent_reload.cms', () => $videoTeasers.trigger('consent.consent_reload.cms')); 17900 17901 17902 // Prüft ob der Consentwrapper vorhanden ist und fügt nach schlieÃen des Cookiebanners einen Pagereload durch 17903 const consentContainer = document.querySelector('.c-consent-container'); 17904 const cookieBannerClicker = document.querySelector('.c-cookiebanner'); 17905 if (typeof consentContainer != 'undefined' && consentContainer != null) { 17906 cookieBannerClicker.addEventListener("afterClose", function (e) { 17907 location.reload(); 17908 }); 17909 } 17910 17911 //DTVP-Importer 17912 cms.requireCMSComponent('bundle_datatables', $('.js-dtvp-importer')).done(function ($dtvp_importer) { 17913 $dtvp_importer.cms_dtvp_importer(); 17914 }); 17915 17916 //Kontakt-Finder 17917 $(".js-contact-finder").each(function () { 17918 addContactFinderEventHandlers($(this)); 17919 }); 17920 17921 function normalizeContactFinderTextLinks($scope) { 17922 $scope.find('.c-contact-finder__text a.RichTextIntLink, .c-contact-finder__text a.RichTextExtLink'). 17923 each(function () { 17924 const $a = $(this); 17925 const href = $a.attr('href'); 17926 if (!href || /^https?:\/\//i.test(href) || /^mailto:/i.test(href) || /^tel:/i.test(href) || href.startsWith('#')) { 17927 return; 17928 } 17929 if (href.startsWith('/')) { 17930 $a.attr('href', window.location.origin + href); 17931 } else { 17932 $a.attr('href', window.location.origin + '/' + href); 17933 } 17934 }); 17935 } 17936 17937 function addContactFinderEventHandlers($contactFinderContent) { 17938 normalizeContactFinderTextLinks($contactFinderContent); 17939 17940 $contactFinderContent.find("a").not(".c-teaser *").on("click", function (ev) { 17941 const $link = $(this); 17942 if ($link.closest('.c-contact-finder__text').length && $link.is('.RichTextIntLink, .RichTextExtLink')) { 17943 return; 17944 } 17945 ev.preventDefault(); 17946 const href = $link.attr("href") + "?view=render"; 17947 $.ajax({ 17948 url: href, 17949 success: function (data) { 17950 const $newContactFinderContent = $(data).find(".js-contact-finder"); 17951 $contactFinderContent.html($newContactFinderContent.html()); 17952 }, 17953 complete: function (data) { 17954 addContactFinderEventHandlers($contactFinderContent); 17955 window.scrollTo({ top: $contactFinderContent.position().top, behavior: 'smooth' }); 17956 } 17957 }); 17958 }); 17959 } 17960 17961 const $fileUploadForm = $('.js-dynamic-file-upload-form'); 17962 $fileUploadForm.cms_dynamic_file_uploader(); 17963 17964 // Fussnoten 17965 function changeTagName($el, newTag) { 17966 const $newEl = $(`<${newTag}>`); 17967 $.each($el[0].attributes, function () { 17968 $newEl.attr(this.name, this.value); 17969 }); 17970 $newEl.append($el.contents()); 17971 $newEl.data($el.data()); 17972 $el.replaceWith($newEl); 17973 return $newEl; 17974 } 17975 $($('.js-footnote__button').toArray().map((el) => changeTagName($(el), 'a'))); 17976 const $buttons = $('.js-footnote__button'); 17977 const $footnotes = $('.js-anmerkungstexte li'); 17978 $('.js-anmerkungstexte').attr('aria-label', $('body').hasClass('lang-de') ? 'FuÃnoten' : 'Footnotes'); 17979 17980 $buttons.each(function (index) { 17981 $(this).attr('href', '#footnote-' + (index + 1)). 17982 attr('aria-label', `(${$('body').hasClass('lang-de') ? 'FuÃnote' : 'footnote'} ${$(this).text()})`); 17983 });$footnotes.each(function (index) { 17984 $(this).attr('id', 'footnote-' + (index + 1)); 17985 }); 17986 17987 function handleHashTarget() { 17988 const hash = window.location.hash; 17989 if (!hash) return; 17990 17991 const target = document.querySelector(hash); 17992 if (!target) return; 17993 17994 if (hash === '#facetReset') { 17995 $(target).on('focus', function () { 17996 let $facetResetLink = $('.c-facet-reset__link'); 17997 let $searchResults = $('#searchResults'); 17998 17999 if ($facetResetLink.length !== 0) { 18000 $facetResetLink.get(0).focus(); 18001 } else { 18002 $searchResults.attr("tabindex", -1).focus(); 18003 $('html, body').animate({ 18004 scrollTop: $searchResults.offset().top - 120 18005 }, 800); 18006 } 18007 }); 18008 } else {
18009 const accordionEntry = target.closest(".js-accordion-entry"); 18010 if (accordionEntry) { 18011 const controlledId = accordionEntry.id; 18012 const accordionButton = document.querySelector(`button[aria-controls="${controlledId}"]`); 18013 18014 if (accordionButton) { 18015 accordionButton.click(); 18016 18017 const observer = new MutationObserver(() => { 18018 if (accordionButton.getAttribute("aria-expanded") === 'true') { 18019 setTimeout(function () { 18020 target.focus(); 18021 observer.disconnect(); 18022 }, 100); 18023 } 18024 }); 18025 18026 observer.observe(accordionButton, { attributes: true, attributeFilter: ["aria-expanded"] }); 18027 } 18028 } else { 18029 target.focus(); 18030 } 18031 } 18032 } 18033 18034 $(document).ready(handleHashTarget); 18035 window.addEventListener("hashchange", handleHashTarget); 18036 18037}); 18038// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -- Unterdrücke, dass no-console nicht wieder aktiviert wird 18039/* eslint-disable no-console -- Das Ziel ist es Konsolen-Ausgaben zu machen */ 18040$(function () { 18041 // Prüfe, ob Aria-describedby und labelled-by passende IDs und zugehörige Elemente haben 18042 if (ISPREVIEW) { 18043 const $body = $('body'); 18044 let aria = new Set(); 18045 let ids = new Set(); 18046 const arrAria = [...$body.html().matchAll(/<[^<]*(aria-labelledby="([^"]*)"|aria-describedby="([^"]*)")[^>]*>/gmu)]; 18047 arrAria.forEach((el) => { 18048 if (!aria.has(el[2]) && !aria.has(el[3])) { 18049 aria.add(el[2]); 18050 aria.add(el[3]); 18051 aria.delete(undefined); 18052 } else { 18053 console.log(`ID bereits vergeben: ${el[0]}`); 18054 } 18055 }); 18056 const arrId = [...$body.html().matchAll(/<[^<]* id="([^"]*)"[^>]*>/gmu)]; 18057 arrId.forEach((el) => { 18058 if (!ids.has(el[1])) { 18059 ids.add(el[1]); 18060 } else { 18061 console.log(`ID doppelt: ${el[0]}`); 18062 } 18063 }); 18064 18065 function splitArr(arr) { 18066 const splits = []; 18067 const newSet = new Set(); 18068 arr.forEach((el) => { 18069 splits.push(el.split(" ")); 18070 }); 18071 splits.forEach((array) => { 18072 array.forEach((el) => { 18073 newSet.add(el); 18074 }); 18075 }); 18076 newSet.delete(""); 18077 return newSet; 18078 } 18079 18080 aria = splitArr(aria); 18081 ids = splitArr(ids); 18082 18083 const missingIds = new Set(); 18084 aria.forEach((el) => { 18085 if (!ids.has(el)) { 18086 missingIds.add(el); 18087 } 18088 }); 18089 18090 if (missingIds.size > 0) { 18091 const additionalHTML = 'Folgende Aria-Ids haben kein Ziel: '; 18092 missingIds.forEach((el) => console.log(additionalHTML + el)); 18093 } 18094 } 18095}); 18096 18097 /* Ende init */ 18098jQuery(document).ready(function (jQuery){ 18099 // Autosuggest 18100 var searchforms = []; 18101 if(searchforms.length > 0){ 18102 $(searchforms).each(function(index){ 18103 var valueObj = searchforms[index],form; 18104 if(valueObj !== undefined){ 18105 form = jQuery('form[name="'+ valueObj.name +'"]'); 18106 if(form.length > 0){ 18107 form.cms_AutoSuggest({}, valueObj.action); 18108 } 18109 } 18110 }); 18111 } 18112});
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.