vendor: 18,408 bytes, lines 1-485
1/*! 2 * Select2 4.1.0-rc.0 3 * https://select2.github.io 4 * 5 * Released under the MIT license 6 * https://github.com/select2/select2/blob/master/LICENSE.md 7 */ 8; (function (factory) { 9 if (typeof define === 'function' && define.amd) { 10 // AMD. Register as an anonymous module. 11 define(['jquery'], factory); 12 } else if (typeof module === 'object' && module.exports) { 13 // Node/CommonJS 14 module.exports = function (root, jQuery) { 15 if (jQuery === undefined) { 16 // require('jQuery') returns a factory that requires window to 17 // build a jQuery instance, we normalize how we use modules 18 // that require this pattern but the window provided is a noop 19 // if it's defined (how jquery works) 20 if (typeof window !== 'undefined') { 21 jQuery = require('jquery'); 22 } 23 else { 24 jQuery = require('jquery')(root); 25 } 26 } 27 factory(jQuery); 28 return jQuery; 29 }; 30 } else { 31 // Browser globals 32 factory(jQuery); 33 } 34}(function (jQuery) { 35 // This is needed so we can catch the AMD loader configuration and use it 36 // The inner file should be wrapped (by `banner.start.js`) in a function that 37 // returns the AMD loader references. 38 var S2 = (function () { 39 // Restore the Select2 AMD loader so it can be used 40 // Needed mostly in the language files, where the loader is not inserted 41 if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) { 42 var S2 = jQuery.fn.select2.amd; 43 } 44 var S2; (function () { 45 if (!S2 || !S2.requirejs) { 46 if (!S2) { S2 = {}; } else { require = S2; } 47 /** 48 * @license almond 0.3.3 Copyright jQuery Foundation and other contributors. 49 * Released under MIT license, http://github.com/requirejs/almond/LICENSE 50 */ 51 //Going sloppy to avoid 'use strict' string cost, but strict practices should 52 //be followed. 53 /*global setTimeout: false */ 54 55 var requirejs, require, define; 56 (function (undef) { 57 var main, req, makeMap, handlers, 58 defined = {}, 59 waiting = {}, 60 config = {}, 61 defining = {}, 62 hasOwn = Object.prototype.hasOwnProperty, 63 aps = [].slice, 64 jsSuffixRegExp = /\.js$/; 65 66 function hasProp(obj, prop) { 67 return hasOwn.call(obj, prop); 68 } 69 70 /** 71 * Given a relative module name, like ./something, normalize it to 72 * a real name that can be mapped to a path. 73 * @param {String} name the relative name 74 * @param {String} baseName a real name that the name arg is relative 75 * to. 76 * @returns {String} normalized name 77 */ 78 function normalize(name, baseName) { 79 var nameParts, nameSegment, mapValue, foundMap, lastIndex, 80 foundI, foundStarMap, starI, i, j, part, normalizedBaseParts, 81 baseParts = baseName && baseName.split("/"), 82 map = config.map, 83 starMap = (map && map['*']) || {}; 84 85 //Adjust any relative paths. 86 if (name) { 87 name = name.split('/'); 88 lastIndex = name.length - 1; 89 90 // If wanting node ID compatibility, strip .js from end 91 // of IDs. Have to do this here, and not in nameToUrl 92 // because node allows either .js or non .js to map 93 // to same file. 94 if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { 95 name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); 96 } 97 98 // Starts with a '.' so need the baseName 99 if (name[0].charAt(0) === '.' && baseParts) { 100 //Convert baseName to array, and lop off the last part, 101 //so that . matches that 'directory' and not name of the baseName's 102 //module. For instance, baseName of 'one/two/three', maps to 103 //'one/two/three.js', but we want the directory, 'one/two' for 104 //this normalization. 105 normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); 106 name = normalizedBaseParts.concat(name); 107 } 108 109 //start trimDots 110 for (i = 0; i < name.length; i++) { 111 part = name[i]; 112 if (part === '.') { 113 name.splice(i, 1); 114 i -= 1; 115 } else if (part === '..') { 116 // If at the start, or previous value is still .., 117 // keep them so that when converted to a path it may 118 // still work when converted to a path, even though 119 // as an ID it is less than ideal. In larger point 120 // releases, may be better to just kick out an error. 121 if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') { 122 continue; 123 } else if (i > 0) { 124 name.splice(i - 1, 2); 125 i -= 2; 126 } 127 } 128 } 129 //end trimDots 130 131 name = name.join('/'); 132 } 133 134 //Apply map config if available. 135 if ((baseParts || starMap) && map) { 136 nameParts = name.split('/'); 137 138 for (i = nameParts.length; i > 0; i -= 1) { 139 nameSegment = nameParts.slice(0, i).join("/"); 140 141 if (baseParts) { 142 //Find the longest baseName segment match in the config. 143 //So, do joins on the biggest to smallest lengths of baseParts. 144 for (j = baseParts.length; j > 0; j -= 1) { 145 mapValue = map[baseParts.slice(0, j).join('/')]; 146 147 //baseName segment has config, find if it has one for 148 //this name. 149 if (mapValue) { 150 mapValue = mapValue[nameSegment]; 151 if (mapValue) { 152 //Match, update name to the new value. 153 foundMap = mapValue; 154 foundI = i; 155 break; 156 } 157 } 158 } 159 } 160 161 if (foundMap) { 162 break; 163 } 164 165 //Check for a star map match, but just hold on to it, 166 //if there is a shorter segment match later in a matching 167 //config, then favor over this star map. 168 if (!foundStarMap && starMap && starMap[nameSegment]) { 169 foundStarMap = starMap[nameSegment]; 170 starI = i; 171 } 172 } 173 174 if (!foundMap && foundStarMap) { 175 foundMap = foundStarMap; 176 foundI = starI; 177 } 178 179 if (foundMap) { 180 nameParts.splice(0, foundI, foundMap); 181 name = nameParts.join('/'); 182 } 183 } 184 185 return name; 186 } 187 188 function makeRequire(relName, forceSync) { 189 return function () { 190 //A version of a require function that passes a moduleName 191 //value for items that may need to 192 //look up paths relative to the moduleName 193 var args = aps.call(arguments, 0); 194 195 //If first arg is not require('string'), and there is only 196 //one arg, it is the array form without a callback. Insert 197 //a null so that the following concat is correct. 198 if (typeof args[0] !== 'string' && args.length === 1) { 199 args.push(null); 200 } 201 return req.apply(undef, args.concat([relName, forceSync])); 202 }; 203 } 204 205 function makeNormalize(relName) { 206 return function (name) { 207 return normalize(name, relName); 208 }; 209 } 210 211 function makeLoad(depName) { 212 return function (value) { 213 defined[depName] = value; 214 }; 215 } 216 217 function callDep(name) { 218 if (hasProp(waiting, name)) { 219 var args = waiting[name]; 220 delete waiting[name]; 221 defining[name] = true; 222 main.apply(undef, args); 223 } 224 225 if (!hasProp(defined, name) && !hasProp(defining, name)) { 226 throw new Error('No ' + name); 227 } 228 return defined[name]; 229 } 230 231 //Turns a plugin!resource to [plugin, resource] 232 //with the plugin being undefined if the name 233 //did not have a plugin prefix. 234 function splitPrefix(name) { 235 var prefix, 236 index = name ? name.indexOf('!') : -1; 237 if (index > -1) { 238 prefix = name.substring(0, index); 239 name = name.substring(index + 1, name.length); 240 } 241 return [prefix, name]; 242 } 243 244 //Creates a parts array for a relName where first part is plugin ID, 245 //second part is resource ID. Assumes relName has already been normalized. 246 function makeRelParts(relName) { 247 return relName ? splitPrefix(relName) : []; 248 } 249 250 /** 251 * Makes a name map, normalizing the name, and using a plugin 252 * for normalization if necessary. Grabs a ref to plugin 253 * too, as an optimization. 254 */ 255 makeMap = function (name, relParts) { 256 var plugin, 257 parts = splitPrefix(name), 258 prefix = parts[0], 259 relResourceName = relParts[1]; 260 261 name = parts[1]; 262 263 if (prefix) { 264 prefix = normalize(prefix, relResourceName); 265 plugin = callDep(prefix); 266 } 267 268 //Normalize according 269 if (prefix) { 270 if (plugin && plugin.normalize) { 271 name = plugin.normalize(name, makeNormalize(relResourceName)); 272 } else { 273 name = normalize(name, relResourceName); 274 } 275 } else { 276 name = normalize(name, relResourceName); 277 parts = splitPrefix(name); 278 prefix = parts[0]; 279 name = parts[1]; 280 if (prefix) { 281 plugin = callDep(prefix); 282 } 283 } 284 285 //Using ridiculous property names for space reasons 286 return { 287 f: prefix ? prefix + '!' + name : name, //fullName 288 n: name, 289 pr: prefix, 290 p: plugin 291 }; 292 }; 293 294 function makeConfig(name) { 295 return function () { 296 return (config && config.config && config.config[name]) || {}; 297 }; 298 } 299 300 handlers = { 301 require: function (name) { 302 return makeRequire(name); 303 }, 304 exports: function (name) { 305 var e = defined[name]; 306 if (typeof e !== 'undefined') { 307 return e; 308 } else { 309 return (defined[name] = {}); 310 } 311 }, 312 module: function (name) { 313 return { 314 id: name, 315 uri: '', 316 exports: defined[name], 317 config: makeConfig(name) 318 }; 319 } 320 }; 321 322 main = function (name, deps, callback, relName) { 323 var cjsModule, depName, ret, map, i, relParts, 324 args = [], 325 callbackType = typeof callback, 326 usingExports; 327 328 //Use name if no relName 329 relName = relName || name; 330 relParts = makeRelParts(relName); 331 332 //Call the callback to define the module, if necessary. 333 if (callbackType === 'undefined' || callbackType === 'function') { 334 //Pull out the defined dependencies and pass the ordered 335 //values to the callback. 336 //Default to [require, exports, module] if no deps 337 deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; 338 for (i = 0; i < deps.length; i += 1) { 339 map = makeMap(deps[i], relParts); 340 depName = map.f; 341 342 //Fast path CommonJS standard dependencies. 343 if (depName === "require") { 344 args[i] = handlers.require(name); 345 } else if (depName === "exports") { 346 //CommonJS module spec 1.1 347 args[i] = handlers.exports(name); 348 usingExports = true; 349 } else if (depName === "module") { 350 //CommonJS module spec 1.1 351 cjsModule = args[i] = handlers.module(name); 352 } else if (hasProp(defined, depName) || 353 hasProp(waiting, depName) || 354 hasProp(defining, depName)) { 355 args[i] = callDep(depName); 356 } else if (map.p) { 357 map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {}); 358 args[i] = defined[depName]; 359 } else { 360 throw new Error(name + ' missing ' + depName); 361 } 362 } 363 364 ret = callback ? callback.apply(defined[name], args) : undefined; 365 366 if (name) { 367 //If setting exports via "module" is in play, 368 //favor that over return value and exports. After that, 369 //favor a non-undefined return value over exports use. 370 if (cjsModule && cjsModule.exports !== undef && 371 cjsModule.exports !== defined[name]) { 372 defined[name] = cjsModule.exports; 373 } else if (ret !== undef || !usingExports) { 374 //Use the return value from the function. 375 defined[name] = ret; 376 } 377 } 378 } else if (name) { 379 //May just be an object definition for the module. Only 380 //worry about defining if have a module name. 381 defined[name] = callback; 382 } 383 }; 384 385 requirejs = require = req = function (deps, callback, relName, forceSync, alt) { 386 if (typeof deps === "string") { 387 if (handlers[deps]) { 388 //callback in this case is really relName 389 return handlers[deps](callback); 390 } 391 //Just return the module wanted. In this scenario, the 392 //deps arg is the module name, and second arg (if passed) 393 //is just the relName. 394 //Normalize module name, if it contains . or .. 395 return callDep(makeMap(deps, makeRelParts(callback)).f); 396 } else if (!deps.splice) { 397 //deps is a config object, not an array. 398 config = deps; 399 if (config.deps) { 400 req(config.deps, config.callback); 401 } 402 if (!callback) { 403 return; 404 } 405 406 if (callback.splice) { 407 //callback is an array, which means it is a dependency list. 408 //Adjust args if there are dependencies 409 deps = callback; 410 callback = relName; 411 relName = null; 412 } else { 413 deps = undef; 414 } 415 } 416 417 //Support require(['a']) 418 callback = callback || function () { }; 419 420 //If relName is a function, it is an errback handler, 421 //so remove it. 422 if (typeof relName === 'function') { 423 relName = forceSync; 424 forceSync = alt; 425 } 426 427 //Simulate async callback; 428 if (forceSync) { 429 main(undef, deps, callback, relName); 430 } else { 431 //Using a non-zero value because of concern for what old browsers 432 //do, and latest browsers "upgrade" to 4 if lower value is used: 433 //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout: 434 //If want a value immediately, use require('id') instead -- something 435 //that works in almond on the global level, but not guaranteed and 436 //unlikely to work in other AMD implementations. 437 setTimeout(function () { 438 main(undef, deps, callback, relName); 439 }, 4); 440 } 441 442 return req; 443 }; 444 445 /** 446 * Just drops the config on the floor, but returns req in case 447 * the config return value is used. 448 */ 449 req.config = function (cfg) { 450 return req(cfg); 451 }; 452 453 /** 454 * Expose module registry for debugging and tooling 455 */ 456 requirejs._defined = defined; 457 458 define = function (name, deps, callback) { 459 if (typeof name !== 'string') { 460 throw new Error('See almond README: incorrect module build, no module name'); 461 } 462 463 //This module may not have dependencies 464 if (!deps.splice) { 465 //deps is not an array, so probably means 466 //an object literal or factory function for 467 //the value. Adjust args. 468 callback = deps; 469 deps = []; 470 } 471 472 if (!hasProp(defined, name) && !hasProp(waiting, name)) { 473 waiting[name] = [name, deps, callback]; 474 } 475 }; 476 477 define.amd = { 478 jQuery: true 479 }; 480 }()); 481 482 S2.requirejs = requirejs; S2.require = require; S2.define = define; 483 } 484 }()); 485 S2.define("almond", function () { });
vendor: 6,408 bytes, lines 486-715
486 487 /* global jQuery:false, $:false */ 488 S2.define('jquery', [], function () { 489 var _$ = jQuery || $; 490 491 if (_$ == null && console && console.error) { 492 console.error( 493 'Select2: An instance of jQuery or a jQuery-compatible library was not ' + 494 'found. Make sure that you are including jQuery before Select2 on your ' + 495 'web page.' 496 ); 497 } 498 499 return _$; 500 }); 501 502 S2.define('select2/utils', [ 503 'jquery' 504 ], function ($) { 505 var Utils = {}; 506 507 Utils.Extend = function (ChildClass, SuperClass) { 508 var __hasProp = {}.hasOwnProperty; 509 510 function BaseConstructor() { 511 this.constructor = ChildClass; 512 } 513 514 for (var key in SuperClass) { 515 if (__hasProp.call(SuperClass, key)) { 516 ChildClass[key] = SuperClass[key]; 517 } 518 } 519 520 BaseConstructor.prototype = SuperClass.prototype; 521 ChildClass.prototype = new BaseConstructor(); 522 ChildClass.__super__ = SuperClass.prototype; 523 524 return ChildClass; 525 }; 526 527 function getMethods(theClass) { 528 var proto = theClass.prototype; 529 530 var methods = []; 531 532 for (var methodName in proto) { 533 var m = proto[methodName]; 534 535 if (typeof m !== 'function') { 536 continue; 537 } 538 539 if (methodName === 'constructor') { 540 continue; 541 } 542 543 methods.push(methodName); 544 } 545 546 return methods; 547 } 548 549 Utils.Decorate = function (SuperClass, DecoratorClass) { 550 var decoratedMethods = getMethods(DecoratorClass); 551 var superMethods = getMethods(SuperClass); 552 553 function DecoratedClass() { 554 var unshift = Array.prototype.unshift; 555 556 var argCount = DecoratorClass.prototype.constructor.length; 557 558 var calledConstructor = SuperClass.prototype.constructor; 559 560 if (argCount > 0) { 561 unshift.call(arguments, SuperClass.prototype.constructor); 562 563 calledConstructor = DecoratorClass.prototype.constructor; 564 } 565 566 calledConstructor.apply(this, arguments); 567 } 568 569 DecoratorClass.displayName = SuperClass.displayName; 570 571 function ctr() { 572 this.constructor = DecoratedClass; 573 } 574 575 DecoratedClass.prototype = new ctr(); 576 577 for (var m = 0; m < superMethods.length; m++) { 578 var superMethod = superMethods[m]; 579 580 DecoratedClass.prototype[superMethod] = 581 SuperClass.prototype[superMethod]; 582 } 583 584 var calledMethod = function (methodName) { 585 // Stub out the original method if it's not decorating an actual method 586 var originalMethod = function () { }; 587 588 if (methodName in DecoratedClass.prototype) { 589 originalMethod = DecoratedClass.prototype[methodName]; 590 } 591 592 var decoratedMethod = DecoratorClass.prototype[methodName]; 593 594 return function () { 595 var unshift = Array.prototype.unshift; 596 597 unshift.call(arguments, originalMethod); 598 599 return decoratedMethod.apply(this, arguments); 600 }; 601 }; 602 603 for (var d = 0; d < decoratedMethods.length; d++) { 604 var decoratedMethod = decoratedMethods[d]; 605 606 DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod); 607 } 608 609 return DecoratedClass; 610 }; 611 612 var Observable = function () { 613 this.listeners = {}; 614 }; 615 616 Observable.prototype.on = function (event, callback) { 617 this.listeners = this.listeners || {}; 618 619 if (event in this.listeners) { 620 this.listeners[event].push(callback); 621 } else { 622 this.listeners[event] = [callback]; 623 } 624 }; 625 626 Observable.prototype.trigger = function (event) { 627 var slice = Array.prototype.slice; 628 var params = slice.call(arguments, 1); 629 630 this.listeners = this.listeners || {}; 631 632 // Params should always come in as an array 633 if (params == null) { 634 params = []; 635 } 636 637 // If there are no arguments to the event, use a temporary object 638 if (params.length === 0) { 639 params.push({}); 640 } 641 642 // Set the `_type` of the first object to the event 643 params[0]._type = event; 644 645 if (event in this.listeners) { 646 this.invoke(this.listeners[event], slice.call(arguments, 1)); 647 } 648 649 if ('*' in this.listeners) { 650 this.invoke(this.listeners['*'], arguments); 651 } 652 }; 653 654 Observable.prototype.invoke = function (listeners, params) { 655 for (var i = 0, len = listeners.length; i < len; i++) { 656 listeners[i].apply(this, params); 657 } 658 }; 659 660 Utils.Observable = Observable; 661 662 Utils.generateChars = function (length) { 663 var chars = ''; 664 665 for (var i = 0; i < length; i++) { 666 var randomChar = Math.floor(Math.random() * 36); 667 chars += randomChar.toString(36); 668 } 669 670 return chars; 671 }; 672 673 Utils.bind = function (func, context) { 674 return function () { 675 func.apply(context, arguments); 676 }; 677 }; 678 679 Utils._convertData = function (data) { 680 for (var originalKey in data) { 681 var keys = originalKey.split('-'); 682 683 var dataLevel = data; 684 685 if (keys.length === 1) { 686 continue; 687 } 688 689 for (var k = 0; k < keys.length; k++) { 690 var key = keys[k]; 691 692 // Lowercase the first letter 693 // By default, dash-separated becomes camelCase 694 key = key.substring(0, 1).toLowerCase() + key.substring(1); 695 696 if (!(key in dataLevel)) { 697 dataLevel[key] = {}; 698 } 699 700 if (k == keys.length - 1) { 701 dataLevel[key] = data[originalKey]; 702 } 703 704 dataLevel = dataLevel[key]; 705 } 706 707 delete data[originalKey]; 708 } 709 710 return data; 711 }; 712 713 Utils.hasScroll = function (index, el) { 714 // Adapted from the function created by @ShadowScripter 715 // and adapted by @BillBarry on the Stack Exchange Code Review website.
vendor: 64,095 bytes, lines 716-2951
716 // The original code can be found at 717 // http://codereview.stackexchange.com/q/13338 718 // and was designed to be used with the Sizzle selector engine. 719 720 var $el = $(el); 721 var overflowX = el.style.overflowX; 722 var overflowY = el.style.overflowY; 723 724 //Check both x and y declarations 725 if (overflowX === overflowY && 726 (overflowY === 'hidden' || overflowY === 'visible')) { 727 return false; 728 } 729 730 if (overflowX === 'scroll' || overflowY === 'scroll') { 731 return true; 732 } 733 734 return ($el.innerHeight() < el.scrollHeight || 735 $el.innerWidth() < el.scrollWidth); 736 }; 737 738 Utils.escapeMarkup = function (markup) { 739 var replaceMap = { 740 '\\': '\', 741 '&': '&', 742 '<': '<', 743 '>': '>', 744 '"': '"', 745 '\'': ''', 746 '/': '/' 747 }; 748 749 // Do not try to escape the markup if it's not a string 750 if (typeof markup !== 'string') { 751 return markup; 752 } 753 754 return String(markup).replace(/[&<>"'\/\\]/g, function (match) { 755 return replaceMap[match]; 756 }); 757 }; 758 759 // Cache objects in Utils.__cache instead of $.data (see #4346) 760 Utils.__cache = {}; 761 762 var id = 0; 763 Utils.GetUniqueElementId = function (element) { 764 // Get a unique element Id. If element has no id, 765 // creates a new unique number, stores it in the id 766 // attribute and returns the new id with a prefix. 767 // If an id already exists, it simply returns it with a prefix. 768 769 var select2Id = element.getAttribute('data-select2-id'); 770 771 if (select2Id != null) { 772 return select2Id; 773 } 774 775 // If element has id, use it. 776 if (element.id) { 777 select2Id = 'select2-data-' + element.id; 778 } else { 779 select2Id = 'select2-data-' + (++id).toString() + 780 '-' + Utils.generateChars(4); 781 } 782 783 element.setAttribute('data-select2-id', select2Id); 784 785 return select2Id; 786 }; 787 788 Utils.StoreData = function (element, name, value) { 789 // Stores an item in the cache for a specified element. 790 // name is the cache key. 791 var id = Utils.GetUniqueElementId(element); 792 if (!Utils.__cache[id]) { 793 Utils.__cache[id] = {}; 794 } 795 796 Utils.__cache[id][name] = value; 797 }; 798 799 Utils.GetData = function (element, name) { 800 // Retrieves a value from the cache by its key (name) 801 // name is optional. If no name specified, return 802 // all cache items for the specified element. 803 // and for a specified element. 804 var id = Utils.GetUniqueElementId(element); 805 if (name) { 806 if (Utils.__cache[id]) { 807 if (Utils.__cache[id][name] != null) { 808 return Utils.__cache[id][name]; 809 } 810 return $(element).data(name); // Fallback to HTML5 data attribs. 811 } 812 return $(element).data(name); // Fallback to HTML5 data attribs. 813 } else { 814 return Utils.__cache[id]; 815 } 816 }; 817 818 Utils.RemoveData = function (element) { 819 // Removes all cached items for a specified element. 820 var id = Utils.GetUniqueElementId(element); 821 if (Utils.__cache[id] != null) { 822 delete Utils.__cache[id]; 823 } 824 825 element.removeAttribute('data-select2-id'); 826 }; 827 828 Utils.copyNonInternalCssClasses = function (dest, src) { 829 var classes; 830 831 var destinationClasses = dest.getAttribute('class').trim().split(/\s+/); 832 833 destinationClasses = destinationClasses.filter(function (clazz) { 834 // Save all Select2 classes 835 return clazz.indexOf('select2-') === 0; 836 }); 837 838 var sourceClasses = src.getAttribute('class').trim().split(/\s+/); 839 840 sourceClasses = sourceClasses.filter(function (clazz) { 841 // Only copy non-Select2 classes 842 return clazz.indexOf('select2-') !== 0; 843 }); 844 845 var replacements = destinationClasses.concat(sourceClasses); 846 847 dest.setAttribute('class', replacements.join(' ')); 848 }; 849 850 return Utils; 851 }); 852 853 S2.define('select2/results', [ 854 'jquery', 855 './utils' 856 ], function ($, Utils) { 857 function Results($element, options, dataAdapter) { 858 this.$element = $element; 859 this.data = dataAdapter; 860 this.options = options; 861 862 Results.__super__.constructor.call(this); 863 } 864 865 Utils.Extend(Results, Utils.Observable); 866 867 Results.prototype.render = function () { 868 var $results = $( 869 '<ul class="select2-results__options" role="listbox"></ul>' 870 ); 871 872 if (this.options.get('multiple')) { 873 $results.attr('aria-multiselectable', 'true'); 874 } 875 876 this.$results = $results; 877 878 return $results; 879 }; 880 881 Results.prototype.clear = function () { 882 this.$results.empty(); 883 }; 884 885 Results.prototype.displayMessage = function (params) { 886 var escapeMarkup = this.options.get('escapeMarkup'); 887 888 this.clear(); 889 this.hideLoading(); 890 891 var $message = $( 892 '<li role="alert" aria-live="assertive"' + 893 ' class="select2-results__option"></li>' 894 ); 895 896 var message = this.options.get('translations').get(params.message); 897 898 $message.append( 899 escapeMarkup( 900 message(params.args) 901 ) 902 ); 903 904 $message[0].className += ' select2-results__message'; 905 906 this.$results.append($message); 907 }; 908 909 Results.prototype.hideMessages = function () { 910 this.$results.find('.select2-results__message').remove(); 911 }; 912 913 Results.prototype.append = function (data) { 914 this.hideLoading(); 915 916 var $options = []; 917 918 if (data.results == null || data.results.length === 0) { 919 if (this.$results.children().length === 0) { 920 this.trigger('results:message', { 921 message: 'noResults' 922 }); 923 } 924 925 return; 926 } 927 928 data.results = this.sort(data.results); 929 930 for (var d = 0; d < data.results.length; d++) { 931 var item = data.results[d]; 932 933 var $option = this.option(item); 934 935 $options.push($option); 936 } 937 938 this.$results.append($options); 939 }; 940 941 Results.prototype.position = function ($results, $dropdown) { 942 var $resultsContainer = $dropdown.find('.select2-results'); 943 $resultsContainer.append($results); 944 }; 945 946 Results.prototype.sort = function (data) { 947 var sorter = this.options.get('sorter'); 948 949 return sorter(data); 950 }; 951 952 Results.prototype.highlightFirstItem = function () { 953 var $options = this.$results 954 .find('.select2-results__option--selectable'); 955 956 var $selected = $options.filter('.select2-results__option--selected'); 957 958 // Check if there are any selected options 959 if ($selected.length > 0) { 960 // If there are selected options, highlight the first 961 $selected.first().trigger('mouseenter'); 962 } else { 963 // If there are no selected options, highlight the first option 964 // in the dropdown 965 $options.first().trigger('mouseenter'); 966 } 967 968 this.ensureHighlightVisible(); 969 }; 970 971 Results.prototype.setClasses = function () { 972 var self = this; 973 974 this.data.current(function (selected) { 975 var selectedIds = selected.map(function (s) { 976 return s.id.toString(); 977 }); 978 979 var $options = self.$results 980 .find('.select2-results__option--selectable'); 981 982 $options.each(function () { 983 var $option = $(this); 984 985 var item = Utils.GetData(this, 'data'); 986 987 // id needs to be converted to a string when comparing 988 var id = '' + item.id; 989 990 if ((item.element != null && item.element.selected) || 991 (item.element == null && selectedIds.indexOf(id) > -1)) { 992 this.classList.add('select2-results__option--selected'); 993 $option.attr('aria-selected', 'true'); 994 } else { 995 this.classList.remove('select2-results__option--selected'); 996 $option.attr('aria-selected', 'false'); 997 } 998 }); 999 1000 }); 1001 }; 1002 1003 Results.prototype.showLoading = function (params) { 1004 this.hideLoading(); 1005 1006 var loadingMore = this.options.get('translations').get('searching'); 1007 1008 var loading = { 1009 disabled: true, 1010 loading: true, 1011 text: loadingMore(params) 1012 }; 1013 var $loading = this.option(loading); 1014 $loading.className += ' loading-results'; 1015 1016 this.$results.prepend($loading); 1017 }; 1018 1019 Results.prototype.hideLoading = function () { 1020 this.$results.find('.loading-results').remove(); 1021 }; 1022 1023 Results.prototype.option = function (data) { 1024 var option = document.createElement('li'); 1025 option.classList.add('select2-results__option'); 1026 option.classList.add('select2-results__option--selectable'); 1027 1028 var attrs = { 1029 'role': 'option' 1030 }; 1031 1032 var matches = window.Element.prototype.matches || 1033 window.Element.prototype.msMatchesSelector || 1034 window.Element.prototype.webkitMatchesSelector; 1035 1036 if ((data.element != null && matches.call(data.element, ':disabled')) || 1037 (data.element == null && data.disabled)) { 1038 attrs['aria-disabled'] = 'true'; 1039 1040 option.classList.remove('select2-results__option--selectable'); 1041 option.classList.add('select2-results__option--disabled'); 1042 } 1043 1044 if (data.id == null) { 1045 option.classList.remove('select2-results__option--selectable'); 1046 } 1047 1048 if (data._resultId != null) { 1049 option.id = data._resultId; 1050 } 1051 1052 if (data.title) { 1053 option.title = data.title; 1054 } 1055 1056 if (data.children) { 1057 attrs.role = 'group'; 1058 attrs['aria-label'] = data.text; 1059 1060 option.classList.remove('select2-results__option--selectable'); 1061 option.classList.add('select2-results__option--group'); 1062 } 1063 1064 for (var attr in attrs) { 1065 var val = attrs[attr]; 1066 1067 option.setAttribute(attr, val); 1068 } 1069 1070 if (data.children) { 1071 var $option = $(option); 1072 1073 var label = document.createElement('strong'); 1074 label.className = 'select2-results__group'; 1075 1076 this.template(data, label); 1077 1078 var $children = []; 1079 1080 for (var c = 0; c < data.children.length; c++) { 1081 var child = data.children[c]; 1082 1083 var $child = this.option(child); 1084 1085 $children.push($child); 1086 } 1087 1088 var $childrenContainer = $('<ul></ul>', { 1089 'class': 'select2-results__options select2-results__options--nested', 1090 'role': 'none' 1091 }); 1092 1093 $childrenContainer.append($children); 1094 1095 $option.append(label); 1096 $option.append($childrenContainer); 1097 } else { 1098 this.template(data, option); 1099 } 1100 1101 Utils.StoreData(option, 'data', data); 1102 1103 return option; 1104 }; 1105 1106 Results.prototype.bind = function (container, $container) { 1107 var self = this; 1108 1109 var id = container.id + '-results'; 1110 1111 this.$results.attr('id', id); 1112 1113 container.on('results:all', function (params) { 1114 self.clear(); 1115 self.append(params.data); 1116 1117 if (container.isOpen()) { 1118 self.setClasses(); 1119 self.highlightFirstItem(); 1120 } 1121 }); 1122 1123 container.on('results:append', function (params) { 1124 self.append(params.data); 1125 1126 if (container.isOpen()) { 1127 self.setClasses(); 1128 } 1129 }); 1130 1131 container.on('query', function (params) { 1132 self.hideMessages(); 1133 self.showLoading(params); 1134 }); 1135 1136 container.on('select', function () { 1137 if (!container.isOpen()) { 1138 return; 1139 } 1140 1141 self.setClasses(); 1142 1143 if (self.options.get('scrollAfterSelect')) { 1144 self.highlightFirstItem(); 1145 } 1146 }); 1147 1148 container.on('unselect', function () { 1149 if (!container.isOpen()) { 1150 return; 1151 } 1152 1153 self.setClasses(); 1154 1155 if (self.options.get('scrollAfterSelect')) { 1156 self.highlightFirstItem(); 1157 } 1158 }); 1159 1160 container.on('open', function () { 1161 // When the dropdown is open, aria-expended="true" 1162 self.$results.attr('aria-expanded', 'true'); 1163 self.$results.attr('aria-hidden', 'false'); 1164 1165 self.setClasses(); 1166 self.ensureHighlightVisible(); 1167 }); 1168 1169 container.on('close', function () { 1170 // When the dropdown is closed, aria-expended="false" 1171 self.$results.attr('aria-expanded', 'false'); 1172 self.$results.attr('aria-hidden', 'true'); 1173 self.$results.removeAttr('aria-activedescendant'); 1174 }); 1175 1176 container.on('results:toggle', function () { 1177 var $highlighted = self.getHighlightedResults(); 1178 1179 if ($highlighted.length === 0) { 1180 return; 1181 } 1182 1183 $highlighted.trigger('mouseup'); 1184 }); 1185 1186 container.on('results:select', function () { 1187 var $highlighted = self.getHighlightedResults(); 1188 1189 if ($highlighted.length === 0) { 1190 return; 1191 } 1192 1193 var data = Utils.GetData($highlighted[0], 'data'); 1194 1195 if ($highlighted.hasClass('select2-results__option--selected')) { 1196 self.trigger('close', {}); 1197 } else { 1198 self.trigger('select', { 1199 data: data 1200 }); 1201 } 1202 }); 1203 1204 container.on('results:previous', function () { 1205 var $highlighted = self.getHighlightedResults(); 1206 1207 var $options = self.$results.find('.select2-results__option--selectable'); 1208 1209 var currentIndex = $options.index($highlighted); 1210 1211 // If we are already at the top, don't move further 1212 // If no options, currentIndex will be -1 1213 if (currentIndex <= 0) { 1214 return; 1215 } 1216 1217 var nextIndex = currentIndex - 1; 1218 1219 // If none are highlighted, highlight the first 1220 if ($highlighted.length === 0) { 1221 nextIndex = 0; 1222 } 1223 1224 var $next = $options.eq(nextIndex); 1225 1226 $next.trigger('mouseenter'); 1227 1228 var currentOffset = self.$results.offset().top; 1229 var nextTop = $next.offset().top; 1230 var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset); 1231 1232 if (nextIndex === 0) { 1233 self.$results.scrollTop(0); 1234 } else if (nextTop - currentOffset < 0) { 1235 self.$results.scrollTop(nextOffset); 1236 } 1237 }); 1238 1239 container.on('results:next', function () { 1240 var $highlighted = self.getHighlightedResults(); 1241 1242 var $options = self.$results.find('.select2-results__option--selectable'); 1243 1244 var currentIndex = $options.index($highlighted); 1245 1246 var nextIndex = currentIndex + 1; 1247 1248 // If we are at the last option, stay there 1249 if (nextIndex >= $options.length) { 1250 return; 1251 } 1252 1253 var $next = $options.eq(nextIndex); 1254 1255 $next.trigger('mouseenter'); 1256 1257 var currentOffset = self.$results.offset().top + 1258 self.$results.outerHeight(false); 1259 var nextBottom = $next.offset().top + $next.outerHeight(false); 1260 var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset; 1261 1262 if (nextIndex === 0) { 1263 self.$results.scrollTop(0); 1264 } else if (nextBottom > currentOffset) { 1265 self.$results.scrollTop(nextOffset); 1266 } 1267 }); 1268 1269 container.on('results:focus', function (params) { 1270 params.element[0].classList.add('select2-results__option--highlighted'); 1271 params.element[0].setAttribute('aria-selected', 'true'); 1272 }); 1273 1274 container.on('results:message', function (params) { 1275 self.displayMessage(params); 1276 }); 1277 1278 if ($.fn.mousewheel) { 1279 this.$results.on('mousewheel', function (e) { 1280 var top = self.$results.scrollTop(); 1281 1282 var bottom = self.$results.get(0).scrollHeight - top + e.deltaY; 1283 1284 var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0; 1285 var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height(); 1286 1287 if (isAtTop) { 1288 self.$results.scrollTop(0); 1289 1290 e.preventDefault(); 1291 e.stopPropagation(); 1292 } else if (isAtBottom) { 1293 self.$results.scrollTop( 1294 self.$results.get(0).scrollHeight - self.$results.height() 1295 ); 1296 1297 e.preventDefault(); 1298 e.stopPropagation(); 1299 } 1300 }); 1301 } 1302 1303 this.$results.on('mouseup', '.select2-results__option--selectable', 1304 function (evt) { 1305 var $this = $(this); 1306 1307 var data = Utils.GetData(this, 'data'); 1308 1309 if ($this.hasClass('select2-results__option--selected')) { 1310 if (self.options.get('multiple')) { 1311 self.trigger('unselect', { 1312 originalEvent: evt, 1313 data: data 1314 }); 1315 } else { 1316 self.trigger('close', {}); 1317 } 1318 1319 return; 1320 } 1321 1322 self.trigger('select', { 1323 originalEvent: evt, 1324 data: data 1325 }); 1326 }); 1327 1328 this.$results.on('mouseenter', '.select2-results__option--selectable', 1329 function (evt) { 1330 var data = Utils.GetData(this, 'data'); 1331 1332 self.getHighlightedResults() 1333 .removeClass('select2-results__option--highlighted') 1334 .attr('aria-selected', 'false'); 1335 1336 self.trigger('results:focus', { 1337 data: data, 1338 element: $(this) 1339 }); 1340 }); 1341 }; 1342 1343 Results.prototype.getHighlightedResults = function () { 1344 var $highlighted = this.$results 1345 .find('.select2-results__option--highlighted'); 1346 1347 return $highlighted; 1348 }; 1349 1350 Results.prototype.destroy = function () { 1351 this.$results.remove(); 1352 }; 1353 1354 Results.prototype.ensureHighlightVisible = function () { 1355 var $highlighted = this.getHighlightedResults(); 1356 1357 if ($highlighted.length === 0) { 1358 return; 1359 } 1360 1361 var $options = this.$results.find('.select2-results__option--selectable'); 1362 1363 var currentIndex = $options.index($highlighted); 1364 1365 var currentOffset = this.$results.offset().top; 1366 var nextTop = $highlighted.offset().top; 1367 var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset); 1368 1369 var offsetDelta = nextTop - currentOffset; 1370 nextOffset -= $highlighted.outerHeight(false) * 2; 1371 1372 if (currentIndex <= 2) { 1373 this.$results.scrollTop(0); 1374 } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) { 1375 this.$results.scrollTop(nextOffset); 1376 } 1377 }; 1378 1379 Results.prototype.template = function (result, container) { 1380 var template = this.options.get('templateResult'); 1381 var escapeMarkup = this.options.get('escapeMarkup'); 1382 1383 var content = template(result, container); 1384 1385 if (content == null) { 1386 container.style.display = 'none'; 1387 } else if (typeof content === 'string') { 1388 container.innerHTML = escapeMarkup(content); 1389 } else { 1390 $(container).append(content); 1391 } 1392 }; 1393 1394 return Results; 1395 }); 1396 1397 S2.define('select2/keys', [ 1398 1399 ], function () { 1400 var KEYS = { 1401 BACKSPACE: 8, 1402 TAB: 9, 1403 ENTER: 13, 1404 SHIFT: 16, 1405 CTRL: 17, 1406 ALT: 18, 1407 ESC: 27, 1408 SPACE: 32, 1409 PAGE_UP: 33, 1410 PAGE_DOWN: 34, 1411 END: 35, 1412 HOME: 36, 1413 LEFT: 37, 1414 UP: 38, 1415 RIGHT: 39, 1416 DOWN: 40, 1417 DELETE: 46 1418 }; 1419 1420 return KEYS; 1421 }); 1422 1423 S2.define('select2/selection/base', [ 1424 'jquery', 1425 '../utils', 1426 '../keys' 1427 ], function ($, Utils, KEYS) { 1428 function BaseSelection($element, options) { 1429 this.$element = $element; 1430 this.options = options; 1431 1432 BaseSelection.__super__.constructor.call(this); 1433 } 1434 1435 Utils.Extend(BaseSelection, Utils.Observable); 1436 1437 BaseSelection.prototype.render = function () { 1438 var $selection = $( 1439 '<span class="select2-selection" role="combobox" ' + 1440 ' aria-haspopup="true" aria-expanded="false">' + 1441 '</span>' 1442 ); 1443 1444 this._tabindex = 0; 1445 1446 if (Utils.GetData(this.$element[0], 'old-tabindex') != null) { 1447 this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex'); 1448 } else if (this.$element.attr('tabindex') != null) { 1449 this._tabindex = this.$element.attr('tabindex'); 1450 } 1451 1452 $selection.attr('title', this.$element.attr('title')); 1453 $selection.attr('tabindex', this._tabindex); 1454 $selection.attr('aria-disabled', 'false'); 1455 1456 this.$selection = $selection; 1457 1458 return $selection; 1459 }; 1460 1461 BaseSelection.prototype.bind = function (container, $container) { 1462 var self = this; 1463 1464 var resultsId = container.id + '-results'; 1465 1466 this.container = container; 1467 1468 this.$selection.on('focus', function (evt) { 1469 self.trigger('focus', evt); 1470 }); 1471 1472 this.$selection.on('blur', function (evt) { 1473 self._handleBlur(evt); 1474 }); 1475 1476 this.$selection.on('keydown', function (evt) { 1477 self.trigger('keypress', evt); 1478 1479 if (evt.which === KEYS.SPACE) { 1480 evt.preventDefault(); 1481 } 1482 }); 1483 1484 container.on('results:focus', function (params) { 1485 self.$selection.attr('aria-activedescendant', params.data._resultId); 1486 }); 1487 1488 container.on('selection:update', function (params) { 1489 self.update(params.data); 1490 }); 1491 1492 container.on('open', function () { 1493 // When the dropdown is open, aria-expanded="true" 1494 self.$selection.attr('aria-expanded', 'true'); 1495 self.$selection.attr('aria-owns', resultsId); 1496 1497 self._attachCloseHandler(container); 1498 }); 1499 1500 container.on('close', function () { 1501 // When the dropdown is closed, aria-expanded="false" 1502 self.$selection.attr('aria-expanded', 'false'); 1503 self.$selection.removeAttr('aria-activedescendant'); 1504 self.$selection.removeAttr('aria-owns'); 1505 1506 self.$selection.trigger('focus'); 1507 1508 self._detachCloseHandler(container); 1509 }); 1510 1511 container.on('enable', function () { 1512 self.$selection.attr('tabindex', self._tabindex); 1513 self.$selection.attr('aria-disabled', 'false'); 1514 }); 1515 1516 container.on('disable', function () { 1517 self.$selection.attr('tabindex', '-1'); 1518 self.$selection.attr('aria-disabled', 'true'); 1519 }); 1520 }; 1521 1522 BaseSelection.prototype._handleBlur = function (evt) { 1523 var self = this; 1524 1525 // This needs to be delayed as the active element is the body when the tab 1526 // key is pressed, possibly along with others. 1527 window.setTimeout(function () { 1528 // Don't trigger `blur` if the focus is still in the selection 1529 if ( 1530 (document.activeElement == self.$selection[0]) || 1531 ($.contains(self.$selection[0], document.activeElement)) 1532 ) { 1533 return; 1534 } 1535 1536 self.trigger('blur', evt); 1537 }, 1); 1538 }; 1539 1540 BaseSelection.prototype._attachCloseHandler = function (container) { 1541 1542 $(document.body).on('mousedown.select2.' + container.id, function (e) { 1543 var $target = $(e.target); 1544 1545 var $select = $target.closest('.select2'); 1546 1547 var $all = $('.select2.select2-container--open'); 1548 1549 $all.each(function () { 1550 if (this == $select[0]) { 1551 return; 1552 } 1553 1554 var $element = Utils.GetData(this, 'element'); 1555 1556 $element.select2('close'); 1557 }); 1558 }); 1559 }; 1560 1561 BaseSelection.prototype._detachCloseHandler = function (container) { 1562 $(document.body).off('mousedown.select2.' + container.id); 1563 }; 1564 1565 BaseSelection.prototype.position = function ($selection, $container) { 1566 var $selectionContainer = $container.find('.selection'); 1567 $selectionContainer.append($selection); 1568 }; 1569 1570 BaseSelection.prototype.destroy = function () { 1571 this._detachCloseHandler(this.container); 1572 }; 1573 1574 BaseSelection.prototype.update = function (data) { 1575 throw new Error('The `update` method must be defined in child classes.'); 1576 }; 1577 1578 /** 1579 * Helper method to abstract the "enabled" (not "disabled") state of this 1580 * object. 1581 * 1582 * @return {true} if the instance is not disabled. 1583 * @return {false} if the instance is disabled. 1584 */ 1585 BaseSelection.prototype.isEnabled = function () { 1586 return !this.isDisabled(); 1587 }; 1588 1589 /** 1590 * Helper method to abstract the "disabled" state of this object. 1591 * 1592 * @return {true} if the disabled option is true. 1593 * @return {false} if the disabled option is false. 1594 */ 1595 BaseSelection.prototype.isDisabled = function () { 1596 return this.options.get('disabled'); 1597 }; 1598 1599 return BaseSelection; 1600 }); 1601 1602 S2.define('select2/selection/single', [ 1603 'jquery', 1604 './base', 1605 '../utils', 1606 '../keys' 1607 ], function ($, BaseSelection, Utils, KEYS) { 1608 function SingleSelection() { 1609 SingleSelection.__super__.constructor.apply(this, arguments); 1610 } 1611 1612 Utils.Extend(SingleSelection, BaseSelection); 1613 1614 SingleSelection.prototype.render = function () { 1615 var $selection = SingleSelection.__super__.render.call(this); 1616 1617 $selection[0].classList.add('select2-selection--single'); 1618 1619 $selection.html( 1620 '<span class="select2-selection__rendered"></span>' + 1621 '<span class="select2-selection__arrow" role="presentation">' + 1622 '<b role="presentation"></b>' + 1623 '</span>' 1624 ); 1625 1626 return $selection; 1627 }; 1628 1629 SingleSelection.prototype.bind = function (container, $container) { 1630 var self = this; 1631 1632 SingleSelection.__super__.bind.apply(this, arguments); 1633 1634 var id = container.id + '-container'; 1635 1636 this.$selection.find('.select2-selection__rendered') 1637 .attr('id', id) 1638 .attr('role', 'textbox') 1639 .attr('aria-readonly', 'true'); 1640 this.$selection.attr('aria-labelledby', id); 1641 this.$selection.attr('aria-controls', id); 1642 1643 this.$selection.on('mousedown', function (evt) { 1644 // Only respond to left clicks 1645 if (evt.which !== 1) { 1646 return; 1647 } 1648 1649 self.trigger('toggle', { 1650 originalEvent: evt 1651 }); 1652 }); 1653 1654 this.$selection.on('focus', function (evt) { 1655 // User focuses on the container 1656 }); 1657 1658 this.$selection.on('blur', function (evt) { 1659 // User exits the container 1660 }); 1661 1662 container.on('focus', function (evt) { 1663 if (!container.isOpen()) { 1664 self.$selection.trigger('focus'); 1665 } 1666 }); 1667 }; 1668 1669 SingleSelection.prototype.clear = function () { 1670 var $rendered = this.$selection.find('.select2-selection__rendered'); 1671 $rendered.empty(); 1672 $rendered.removeAttr('title'); // clear tooltip on empty 1673 }; 1674 1675 SingleSelection.prototype.display = function (data, container) { 1676 var template = this.options.get('templateSelection'); 1677 var escapeMarkup = this.options.get('escapeMarkup'); 1678 1679 return escapeMarkup(template(data, container)); 1680 }; 1681 1682 SingleSelection.prototype.selectionContainer = function () { 1683 return $('<span></span>'); 1684 }; 1685 1686 SingleSelection.prototype.update = function (data) { 1687 if (data.length === 0) { 1688 this.clear(); 1689 return; 1690 } 1691 1692 var selection = data[0]; 1693 1694 var $rendered = this.$selection.find('.select2-selection__rendered'); 1695 var formatted = this.display(selection, $rendered); 1696 1697 $rendered.empty().append(formatted); 1698 1699 var title = selection.title || selection.text; 1700 1701 if (title) { 1702 $rendered.attr('title', title); 1703 } else { 1704 $rendered.removeAttr('title'); 1705 } 1706 }; 1707 1708 return SingleSelection; 1709 }); 1710 1711 S2.define('select2/selection/multiple', [ 1712 'jquery', 1713 './base', 1714 '../utils' 1715 ], function ($, BaseSelection, Utils) { 1716 function MultipleSelection($element, options) { 1717 MultipleSelection.__super__.constructor.apply(this, arguments); 1718 } 1719 1720 Utils.Extend(MultipleSelection, BaseSelection); 1721 1722 MultipleSelection.prototype.render = function () { 1723 var $selection = MultipleSelection.__super__.render.call(this); 1724 1725 $selection[0].classList.add('select2-selection--multiple'); 1726 1727 $selection.html( 1728 '<ul class="select2-selection__rendered"></ul>' 1729 ); 1730 1731 return $selection; 1732 }; 1733 1734 MultipleSelection.prototype.bind = function (container, $container) { 1735 var self = this; 1736 1737 MultipleSelection.__super__.bind.apply(this, arguments); 1738 1739 var id = container.id + '-container'; 1740 this.$selection.find('.select2-selection__rendered').attr('id', id); 1741 1742 this.$selection.on('click', function (evt) { 1743 self.trigger('toggle', { 1744 originalEvent: evt 1745 }); 1746 }); 1747 1748 this.$selection.on( 1749 'click', 1750 '.select2-selection__choice__remove', 1751 function (evt) { 1752 // Ignore the event if it is disabled 1753 if (self.isDisabled()) { 1754 return; 1755 } 1756 1757 var $remove = $(this); 1758 var $selection = $remove.parent(); 1759 1760 var data = Utils.GetData($selection[0], 'data'); 1761 1762 self.trigger('unselect', { 1763 originalEvent: evt, 1764 data: data 1765 }); 1766 } 1767 ); 1768 1769 this.$selection.on( 1770 'keydown', 1771 '.select2-selection__choice__remove', 1772 function (evt) { 1773 // Ignore the event if it is disabled 1774 if (self.isDisabled()) { 1775 return; 1776 } 1777 1778 evt.stopPropagation(); 1779 } 1780 ); 1781 }; 1782 1783 MultipleSelection.prototype.clear = function () { 1784 var $rendered = this.$selection.find('.select2-selection__rendered'); 1785 $rendered.empty(); 1786 $rendered.removeAttr('title'); 1787 }; 1788 1789 MultipleSelection.prototype.display = function (data, container) { 1790 var template = this.options.get('templateSelection'); 1791 var escapeMarkup = this.options.get('escapeMarkup'); 1792 1793 return escapeMarkup(template(data, container)); 1794 }; 1795 1796 MultipleSelection.prototype.selectionContainer = function () { 1797 var $container = $( 1798 '<li class="select2-selection__choice">' + 1799 '<button type="button" class="select2-selection__choice__remove" ' + 1800 'tabindex="-1">' + 1801 '<span aria-hidden="true">×</span>' + 1802 '</button>' + 1803 '<span class="select2-selection__choice__display"></span>' + 1804 '</li>' 1805 ); 1806 1807 return $container; 1808 }; 1809 1810 MultipleSelection.prototype.update = function (data) { 1811 this.clear(); 1812 1813 if (data.length === 0) { 1814 return; 1815 } 1816 1817 var $selections = []; 1818 1819 var selectionIdPrefix = this.$selection.find('.select2-selection__rendered') 1820 .attr('id') + '-choice-'; 1821 1822 for (var d = 0; d < data.length; d++) { 1823 var selection = data[d]; 1824 1825 var $selection = this.selectionContainer(); 1826 var formatted = this.display(selection, $selection); 1827 1828 var selectionId = selectionIdPrefix + Utils.generateChars(4) + '-'; 1829 1830 if (selection.id) { 1831 selectionId += selection.id; 1832 } else { 1833 selectionId += Utils.generateChars(4); 1834 } 1835 1836 $selection.find('.select2-selection__choice__display') 1837 .append(formatted) 1838 .attr('id', selectionId); 1839 1840 var title = selection.title || selection.text; 1841 1842 if (title) { 1843 $selection.attr('title', title); 1844 } 1845 1846 var removeItem = this.options.get('translations').get('removeItem'); 1847 1848 var $remove = $selection.find('.select2-selection__choice__remove'); 1849 1850 $remove.attr('title', removeItem()); 1851 $remove.attr('aria-label', removeItem()); 1852 $remove.attr('aria-describedby', selectionId); 1853 1854 Utils.StoreData($selection[0], 'data', selection); 1855 1856 $selections.push($selection); 1857 } 1858 1859 var $rendered = this.$selection.find('.select2-selection__rendered'); 1860 1861 $rendered.append($selections); 1862 }; 1863 1864 return MultipleSelection; 1865 }); 1866 1867 S2.define('select2/selection/placeholder', [ 1868 1869 ], function () { 1870 function Placeholder(decorated, $element, options) { 1871 this.placeholder = this.normalizePlaceholder(options.get('placeholder')); 1872 1873 decorated.call(this, $element, options); 1874 } 1875 1876 Placeholder.prototype.normalizePlaceholder = function (_, placeholder) { 1877 if (typeof placeholder === 'string') { 1878 placeholder = { 1879 id: '', 1880 text: placeholder 1881 }; 1882 } 1883 1884 return placeholder; 1885 }; 1886 1887 Placeholder.prototype.createPlaceholder = function (decorated, placeholder) { 1888 var $placeholder = this.selectionContainer(); 1889 1890 $placeholder.html(this.display(placeholder)); 1891 $placeholder[0].classList.add('select2-selection__placeholder'); 1892 $placeholder[0].classList.remove('select2-selection__choice'); 1893 1894 var placeholderTitle = placeholder.title || 1895 placeholder.text || 1896 $placeholder.text(); 1897 1898 this.$selection.find('.select2-selection__rendered').attr( 1899 'title', 1900 placeholderTitle 1901 ); 1902 1903 return $placeholder; 1904 }; 1905 1906 Placeholder.prototype.update = function (decorated, data) { 1907 var singlePlaceholder = ( 1908 data.length == 1 && data[0].id != this.placeholder.id 1909 ); 1910 var multipleSelections = data.length > 1; 1911 1912 if (multipleSelections || singlePlaceholder) { 1913 return decorated.call(this, data); 1914 } 1915 1916 this.clear(); 1917 1918 var $placeholder = this.createPlaceholder(this.placeholder); 1919 1920 this.$selection.find('.select2-selection__rendered').append($placeholder); 1921 }; 1922 1923 return Placeholder; 1924 }); 1925 1926 S2.define('select2/selection/allowClear', [ 1927 'jquery', 1928 '../keys', 1929 '../utils' 1930 ], function ($, KEYS, Utils) { 1931 function AllowClear() { } 1932 1933 AllowClear.prototype.bind = function (decorated, container, $container) { 1934 var self = this; 1935 1936 decorated.call(this, container, $container); 1937 1938 if (this.placeholder == null) { 1939 if (this.options.get('debug') && window.console && console.error) { 1940 console.error( 1941 'Select2: The `allowClear` option should be used in combination ' + 1942 'with the `placeholder` option.' 1943 ); 1944 } 1945 } 1946 1947 this.$selection.on('mousedown', '.select2-selection__clear', 1948 function (evt) { 1949 self._handleClear(evt); 1950 }); 1951 1952 container.on('keypress', function (evt) { 1953 self._handleKeyboardClear(evt, container); 1954 }); 1955 }; 1956 1957 AllowClear.prototype._handleClear = function (_, evt) { 1958 // Ignore the event if it is disabled 1959 if (this.isDisabled()) { 1960 return; 1961 } 1962 1963 var $clear = this.$selection.find('.select2-selection__clear'); 1964 1965 // Ignore the event if nothing has been selected 1966 if ($clear.length === 0) { 1967 return; 1968 } 1969 1970 evt.stopPropagation(); 1971 1972 var data = Utils.GetData($clear[0], 'data'); 1973 1974 var previousVal = this.$element.val(); 1975 this.$element.val(this.placeholder.id); 1976 1977 var unselectData = { 1978 data: data 1979 }; 1980 this.trigger('clear', unselectData); 1981 if (unselectData.prevented) { 1982 this.$element.val(previousVal); 1983 return; 1984 } 1985 1986 for (var d = 0; d < data.length; d++) { 1987 unselectData = { 1988 data: data[d] 1989 }; 1990 1991 // Trigger the `unselect` event, so people can prevent it from being 1992 // cleared. 1993 this.trigger('unselect', unselectData); 1994 1995 // If the event was prevented, don't clear it out. 1996 if (unselectData.prevented) { 1997 this.$element.val(previousVal); 1998 return; 1999 } 2000 } 2001 2002 this.$element.trigger('input').trigger('change'); 2003 2004 this.trigger('toggle', {}); 2005 }; 2006 2007 AllowClear.prototype._handleKeyboardClear = function (_, evt, container) { 2008 if (container.isOpen()) { 2009 return; 2010 } 2011 2012 if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) { 2013 this._handleClear(evt); 2014 } 2015 }; 2016 2017 AllowClear.prototype.update = function (decorated, data) { 2018 decorated.call(this, data); 2019 2020 this.$selection.find('.select2-selection__clear').remove(); 2021 this.$selection[0].classList.remove('select2-selection--clearable'); 2022 2023 if (this.$selection.find('.select2-selection__placeholder').length > 0 || 2024 data.length === 0) { 2025 return; 2026 } 2027 2028 var selectionId = this.$selection.find('.select2-selection__rendered') 2029 .attr('id'); 2030 2031 var removeAll = this.options.get('translations').get('removeAllItems'); 2032 2033 var $remove = $( 2034 '<button type="button" class="select2-selection__clear" tabindex="-1">' + 2035 '<span aria-hidden="true">×</span>' + 2036 '</button>' 2037 ); 2038 $remove.attr('title', removeAll()); 2039 $remove.attr('aria-label', removeAll()); 2040 $remove.attr('aria-describedby', selectionId); 2041 Utils.StoreData($remove[0], 'data', data); 2042 2043 this.$selection.prepend($remove); 2044 this.$selection[0].classList.add('select2-selection--clearable'); 2045 }; 2046 2047 return AllowClear; 2048 }); 2049 2050 S2.define('select2/selection/search', [ 2051 'jquery', 2052 '../utils', 2053 '../keys' 2054 ], function ($, Utils, KEYS) { 2055 function Search(decorated, $element, options) { 2056 decorated.call(this, $element, options); 2057 } 2058 2059 Search.prototype.render = function (decorated) { 2060 var searchLabel = this.options.get('translations').get('search'); 2061 var $search = $( 2062 '<span class="select2-search select2-search--inline">' + 2063 '<textarea class="select2-search__field"' + 2064 ' type="search" tabindex="-1"' + 2065 ' autocorrect="off" autocapitalize="none"' + 2066 ' spellcheck="false" role="searchbox" aria-autocomplete="list" >' + 2067 '</textarea>' + 2068 '</span>' 2069 ); 2070 2071 this.$searchContainer = $search; 2072 this.$search = $search.find('textarea'); 2073 2074 this.$search.prop('autocomplete', this.options.get('autocomplete')); 2075 this.$search.attr('aria-label', searchLabel()); 2076 2077 var $rendered = decorated.call(this); 2078 2079 this._transferTabIndex(); 2080 $rendered.append(this.$searchContainer); 2081 2082 return $rendered; 2083 }; 2084 2085 Search.prototype.bind = function (decorated, container, $container) { 2086 var self = this; 2087 2088 var resultsId = container.id + '-results'; 2089 var selectionId = container.id + '-container'; 2090 2091 decorated.call(this, container, $container); 2092 2093 self.$search.attr('aria-describedby', selectionId); 2094 2095 container.on('open', function () { 2096 self.$search.attr('aria-controls', resultsId); 2097 self.$search.trigger('focus'); 2098 }); 2099 2100 container.on('close', function () { 2101 self.$search.val(''); 2102 self.resizeSearch(); 2103 self.$search.removeAttr('aria-controls'); 2104 self.$search.removeAttr('aria-activedescendant'); 2105 self.$search.trigger('focus'); 2106 }); 2107 2108 container.on('enable', function () { 2109 self.$search.prop('disabled', false); 2110 2111 self._transferTabIndex(); 2112 }); 2113 2114 container.on('disable', function () { 2115 self.$search.prop('disabled', true); 2116 }); 2117 2118 container.on('focus', function (evt) { 2119 self.$search.trigger('focus'); 2120 }); 2121 2122 container.on('results:focus', function (params) { 2123 if (params.data._resultId) { 2124 self.$search.attr('aria-activedescendant', params.data._resultId); 2125 } else { 2126 self.$search.removeAttr('aria-activedescendant'); 2127 } 2128 }); 2129 2130 this.$selection.on('focusin', '.select2-search--inline', function (evt) { 2131 self.trigger('focus', evt); 2132 }); 2133 2134 this.$selection.on('focusout', '.select2-search--inline', function (evt) { 2135 self._handleBlur(evt); 2136 }); 2137 2138 this.$selection.on('keydown', '.select2-search--inline', function (evt) { 2139 evt.stopPropagation(); 2140 2141 self.trigger('keypress', evt); 2142 2143 self._keyUpPrevented = evt.isDefaultPrevented(); 2144 2145 var key = evt.which; 2146 2147 if (key === KEYS.BACKSPACE && self.$search.val() === '') { 2148 var $previousChoice = self.$selection 2149 .find('.select2-selection__choice').last(); 2150 2151 if ($previousChoice.length > 0) { 2152 var item = Utils.GetData($previousChoice[0], 'data'); 2153 2154 self.searchRemoveChoice(item); 2155 2156 evt.preventDefault(); 2157 } 2158 } 2159 }); 2160 2161 this.$selection.on('click', '.select2-search--inline', function (evt) { 2162 if (self.$search.val()) { 2163 evt.stopPropagation(); 2164 } 2165 }); 2166 2167 // Try to detect the IE version should the `documentMode` property that 2168 // is stored on the document. This is only implemented in IE and is 2169 // slightly cleaner than doing a user agent check. 2170 // This property is not available in Edge, but Edge also doesn't have 2171 // this bug. 2172 var msie = document.documentMode; 2173 var disableInputEvents = msie && msie <= 11; 2174 2175 // Workaround for browsers which do not support the `input` event 2176 // This will prevent double-triggering of events for browsers which support 2177 // both the `keyup` and `input` events. 2178 this.$selection.on( 2179 'input.searchcheck', 2180 '.select2-search--inline', 2181 function (evt) { 2182 // IE will trigger the `input` event when a placeholder is used on a 2183 // search box. To get around this issue, we are forced to ignore all 2184 // `input` events in IE and keep using `keyup`. 2185 if (disableInputEvents) { 2186 self.$selection.off('input.search input.searchcheck'); 2187 return; 2188 } 2189 2190 // Unbind the duplicated `keyup` event 2191 self.$selection.off('keyup.search'); 2192 } 2193 ); 2194 2195 this.$selection.on( 2196 'keyup.search input.search', 2197 '.select2-search--inline', 2198 function (evt) { 2199 // IE will trigger the `input` event when a placeholder is used on a 2200 // search box. To get around this issue, we are forced to ignore all 2201 // `input` events in IE and keep using `keyup`. 2202 if (disableInputEvents && evt.type === 'input') { 2203 self.$selection.off('input.search input.searchcheck'); 2204 return; 2205 } 2206 2207 var key = evt.which; 2208 2209 // We can freely ignore events from modifier keys 2210 if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) { 2211 return; 2212 } 2213 2214 // Tabbing will be handled during the `keydown` phase 2215 if (key == KEYS.TAB) { 2216 return; 2217 } 2218 2219 self.handleSearch(evt); 2220 } 2221 ); 2222 }; 2223 2224 /** 2225 * This method will transfer the tabindex attribute from the rendered 2226 * selection to the search box. This allows for the search box to be used as 2227 * the primary focus instead of the selection container. 2228 * 2229 * @private 2230 */ 2231 Search.prototype._transferTabIndex = function (decorated) { 2232 this.$search.attr('tabindex', this.$selection.attr('tabindex')); 2233 this.$selection.attr('tabindex', '-1'); 2234 }; 2235 2236 Search.prototype.createPlaceholder = function (decorated, placeholder) { 2237 this.$search.attr('placeholder', placeholder.text); 2238 }; 2239 2240 Search.prototype.update = function (decorated, data) { 2241 var searchHadFocus = this.$search[0] == document.activeElement; 2242 2243 this.$search.attr('placeholder', ''); 2244 2245 decorated.call(this, data); 2246 2247 this.resizeSearch(); 2248 if (searchHadFocus) { 2249 this.$search.trigger('focus'); 2250 } 2251 }; 2252 2253 Search.prototype.handleSearch = function () { 2254 this.resizeSearch(); 2255 2256 if (!this._keyUpPrevented) { 2257 var input = this.$search.val(); 2258 2259 this.trigger('query', { 2260 term: input 2261 }); 2262 } 2263 2264 this._keyUpPrevented = false; 2265 }; 2266 2267 Search.prototype.searchRemoveChoice = function (decorated, item) { 2268 this.trigger('unselect', { 2269 data: item 2270 }); 2271 2272 this.$search.val(item.text); 2273 this.handleSearch(); 2274 }; 2275 2276 Search.prototype.resizeSearch = function () { 2277 this.$search.css('width', '25px'); 2278 2279 var width = '100%'; 2280 2281 if (this.$search.attr('placeholder') === '') { 2282 var minimumWidth = this.$search.val().length + 1; 2283 2284 width = (minimumWidth * 0.75) + 'em'; 2285 } 2286 2287 this.$search.css('width', width); 2288 }; 2289 2290 return Search; 2291 }); 2292 2293 S2.define('select2/selection/selectionCss', [ 2294 '../utils' 2295 ], function (Utils) { 2296 function SelectionCSS() { } 2297 2298 SelectionCSS.prototype.render = function (decorated) { 2299 var $selection = decorated.call(this); 2300 2301 var selectionCssClass = this.options.get('selectionCssClass') || ''; 2302 2303 if (selectionCssClass.indexOf(':all:') !== -1) { 2304 selectionCssClass = selectionCssClass.replace(':all:', ''); 2305 2306 Utils.copyNonInternalCssClasses($selection[0], this.$element[0]); 2307 } 2308 2309 $selection.addClass(selectionCssClass); 2310 2311 return $selection; 2312 }; 2313 2314 return SelectionCSS; 2315 }); 2316 2317 S2.define('select2/selection/eventRelay', [ 2318 'jquery' 2319 ], function ($) { 2320 function EventRelay() { } 2321 2322 EventRelay.prototype.bind = function (decorated, container, $container) { 2323 var self = this; 2324 var relayEvents = [ 2325 'open', 'opening', 2326 'close', 'closing', 2327 'select', 'selecting', 2328 'unselect', 'unselecting', 2329 'clear', 'clearing' 2330 ]; 2331 2332 var preventableEvents = [ 2333 'opening', 'closing', 'selecting', 'unselecting', 'clearing' 2334 ]; 2335 2336 decorated.call(this, container, $container); 2337 2338 container.on('*', function (name, params) { 2339 // Ignore events that should not be relayed 2340 if (relayEvents.indexOf(name) === -1) { 2341 return; 2342 } 2343 2344 // The parameters should always be an object 2345 params = params || {}; 2346 2347 // Generate the jQuery event for the Select2 event 2348 var evt = $.Event('select2:' + name, { 2349 params: params 2350 }); 2351 2352 self.$element.trigger(evt); 2353 2354 // Only handle preventable events if it was one 2355 if (preventableEvents.indexOf(name) === -1) { 2356 return; 2357 } 2358 2359 params.prevented = evt.isDefaultPrevented(); 2360 }); 2361 }; 2362 2363 return EventRelay; 2364 }); 2365 2366 S2.define('select2/translation', [ 2367 'jquery', 2368 'require' 2369 ], function ($, require) { 2370 function Translation(dict) { 2371 this.dict = dict || {}; 2372 } 2373 2374 Translation.prototype.all = function () { 2375 return this.dict; 2376 }; 2377 2378 Translation.prototype.get = function (key) { 2379 return this.dict[key]; 2380 }; 2381 2382 Translation.prototype.extend = function (translation) { 2383 this.dict = $.extend({}, translation.all(), this.dict); 2384 }; 2385 2386 // Static functions 2387 2388 Translation._cache = {}; 2389 2390 Translation.loadPath = function (path) { 2391 if (!(path in Translation._cache)) { 2392 var translations = require(path); 2393 2394 Translation._cache[path] = translations; 2395 } 2396 2397 return new Translation(Translation._cache[path]); 2398 }; 2399 2400 return Translation; 2401 }); 2402 2403 S2.define('select2/diacritics', [ 2404 2405 ], function () { 2406 var diacritics = { 2407 '\u24B6': 'A', 2408 '\uFF21': 'A', 2409 '\u00C0': 'A', 2410 '\u00C1': 'A', 2411 '\u00C2': 'A', 2412 '\u1EA6': 'A', 2413 '\u1EA4': 'A', 2414 '\u1EAA': 'A', 2415 '\u1EA8': 'A', 2416 '\u00C3': 'A', 2417 '\u0100': 'A', 2418 '\u0102': 'A', 2419 '\u1EB0': 'A', 2420 '\u1EAE': 'A', 2421 '\u1EB4': 'A', 2422 '\u1EB2': 'A', 2423 '\u0226': 'A', 2424 '\u01E0': 'A', 2425 '\u00C4': 'A', 2426 '\u01DE': 'A', 2427 '\u1EA2': 'A', 2428 '\u00C5': 'A', 2429 '\u01FA': 'A', 2430 '\u01CD': 'A', 2431 '\u0200': 'A', 2432 '\u0202': 'A', 2433 '\u1EA0': 'A', 2434 '\u1EAC': 'A', 2435 '\u1EB6': 'A', 2436 '\u1E00': 'A', 2437 '\u0104': 'A', 2438 '\u023A': 'A', 2439 '\u2C6F': 'A', 2440 '\uA732': 'AA', 2441 '\u00C6': 'AE', 2442 '\u01FC': 'AE', 2443 '\u01E2': 'AE', 2444 '\uA734': 'AO', 2445 '\uA736': 'AU', 2446 '\uA738': 'AV', 2447 '\uA73A': 'AV', 2448 '\uA73C': 'AY', 2449 '\u24B7': 'B', 2450 '\uFF22': 'B', 2451 '\u1E02': 'B', 2452 '\u1E04': 'B', 2453 '\u1E06': 'B', 2454 '\u0243': 'B', 2455 '\u0182': 'B', 2456 '\u0181': 'B', 2457 '\u24B8': 'C', 2458 '\uFF23': 'C', 2459 '\u0106': 'C', 2460 '\u0108': 'C', 2461 '\u010A': 'C', 2462 '\u010C': 'C', 2463 '\u00C7': 'C', 2464 '\u1E08': 'C', 2465 '\u0187': 'C', 2466 '\u023B': 'C', 2467 '\uA73E': 'C', 2468 '\u24B9': 'D', 2469 '\uFF24': 'D', 2470 '\u1E0A': 'D', 2471 '\u010E': 'D', 2472 '\u1E0C': 'D', 2473 '\u1E10': 'D', 2474 '\u1E12': 'D', 2475 '\u1E0E': 'D', 2476 '\u0110': 'D', 2477 '\u018B': 'D', 2478 '\u018A': 'D', 2479 '\u0189': 'D', 2480 '\uA779': 'D', 2481 '\u01F1': 'DZ', 2482 '\u01C4': 'DZ', 2483 '\u01F2': 'Dz', 2484 '\u01C5': 'Dz', 2485 '\u24BA': 'E', 2486 '\uFF25': 'E', 2487 '\u00C8': 'E', 2488 '\u00C9': 'E', 2489 '\u00CA': 'E', 2490 '\u1EC0': 'E', 2491 '\u1EBE': 'E', 2492 '\u1EC4': 'E', 2493 '\u1EC2': 'E', 2494 '\u1EBC': 'E', 2495 '\u0112': 'E', 2496 '\u1E14': 'E', 2497 '\u1E16': 'E', 2498 '\u0114': 'E', 2499 '\u0116': 'E', 2500 '\u00CB': 'E', 2501 '\u1EBA': 'E', 2502 '\u011A': 'E', 2503 '\u0204': 'E', 2504 '\u0206': 'E', 2505 '\u1EB8': 'E', 2506 '\u1EC6': 'E', 2507 '\u0228': 'E', 2508 '\u1E1C': 'E', 2509 '\u0118': 'E', 2510 '\u1E18': 'E', 2511 '\u1E1A': 'E', 2512 '\u0190': 'E', 2513 '\u018E': 'E', 2514 '\u24BB': 'F', 2515 '\uFF26': 'F', 2516 '\u1E1E': 'F', 2517 '\u0191': 'F', 2518 '\uA77B': 'F', 2519 '\u24BC': 'G', 2520 '\uFF27': 'G', 2521 '\u01F4': 'G', 2522 '\u011C': 'G', 2523 '\u1E20': 'G', 2524 '\u011E': 'G', 2525 '\u0120': 'G', 2526 '\u01E6': 'G', 2527 '\u0122': 'G', 2528 '\u01E4': 'G', 2529 '\u0193': 'G', 2530 '\uA7A0': 'G', 2531 '\uA77D': 'G', 2532 '\uA77E': 'G', 2533 '\u24BD': 'H', 2534 '\uFF28': 'H', 2535 '\u0124': 'H', 2536 '\u1E22': 'H', 2537 '\u1E26': 'H', 2538 '\u021E': 'H', 2539 '\u1E24': 'H', 2540 '\u1E28': 'H', 2541 '\u1E2A': 'H', 2542 '\u0126': 'H', 2543 '\u2C67': 'H', 2544 '\u2C75': 'H', 2545 '\uA78D': 'H', 2546 '\u24BE': 'I', 2547 '\uFF29': 'I', 2548 '\u00CC': 'I', 2549 '\u00CD': 'I', 2550 '\u00CE': 'I', 2551 '\u0128': 'I', 2552 '\u012A': 'I', 2553 '\u012C': 'I', 2554 '\u0130': 'I', 2555 '\u00CF': 'I', 2556 '\u1E2E': 'I', 2557 '\u1EC8': 'I', 2558 '\u01CF': 'I', 2559 '\u0208': 'I', 2560 '\u020A': 'I', 2561 '\u1ECA': 'I', 2562 '\u012E': 'I', 2563 '\u1E2C': 'I', 2564 '\u0197': 'I', 2565 '\u24BF': 'J', 2566 '\uFF2A': 'J', 2567 '\u0134': 'J', 2568 '\u0248': 'J', 2569 '\u24C0': 'K', 2570 '\uFF2B': 'K', 2571 '\u1E30': 'K', 2572 '\u01E8': 'K', 2573 '\u1E32': 'K', 2574 '\u0136': 'K', 2575 '\u1E34': 'K', 2576 '\u0198': 'K', 2577 '\u2C69': 'K', 2578 '\uA740': 'K', 2579 '\uA742': 'K', 2580 '\uA744': 'K', 2581 '\uA7A2': 'K', 2582 '\u24C1': 'L', 2583 '\uFF2C': 'L', 2584 '\u013F': 'L', 2585 '\u0139': 'L', 2586 '\u013D': 'L', 2587 '\u1E36': 'L', 2588 '\u1E38': 'L', 2589 '\u013B': 'L', 2590 '\u1E3C': 'L', 2591 '\u1E3A': 'L', 2592 '\u0141': 'L', 2593 '\u023D': 'L', 2594 '\u2C62': 'L', 2595 '\u2C60': 'L', 2596 '\uA748': 'L', 2597 '\uA746': 'L', 2598 '\uA780': 'L', 2599 '\u01C7': 'LJ', 2600 '\u01C8': 'Lj', 2601 '\u24C2': 'M', 2602 '\uFF2D': 'M', 2603 '\u1E3E': 'M', 2604 '\u1E40': 'M', 2605 '\u1E42': 'M', 2606 '\u2C6E': 'M', 2607 '\u019C': 'M', 2608 '\u24C3': 'N', 2609 '\uFF2E': 'N', 2610 '\u01F8': 'N', 2611 '\u0143': 'N', 2612 '\u00D1': 'N', 2613 '\u1E44': 'N', 2614 '\u0147': 'N', 2615 '\u1E46': 'N', 2616 '\u0145': 'N', 2617 '\u1E4A': 'N', 2618 '\u1E48': 'N', 2619 '\u0220': 'N', 2620 '\u019D': 'N', 2621 '\uA790': 'N', 2622 '\uA7A4': 'N', 2623 '\u01CA': 'NJ', 2624 '\u01CB': 'Nj', 2625 '\u24C4': 'O', 2626 '\uFF2F': 'O', 2627 '\u00D2': 'O', 2628 '\u00D3': 'O', 2629 '\u00D4': 'O', 2630 '\u1ED2': 'O', 2631 '\u1ED0': 'O', 2632 '\u1ED6': 'O', 2633 '\u1ED4': 'O', 2634 '\u00D5': 'O', 2635 '\u1E4C': 'O', 2636 '\u022C': 'O', 2637 '\u1E4E': 'O', 2638 '\u014C': 'O', 2639 '\u1E50': 'O', 2640 '\u1E52': 'O', 2641 '\u014E': 'O', 2642 '\u022E': 'O', 2643 '\u0230': 'O', 2644 '\u00D6': 'O', 2645 '\u022A': 'O', 2646 '\u1ECE': 'O', 2647 '\u0150': 'O', 2648 '\u01D1': 'O', 2649 '\u020C': 'O', 2650 '\u020E': 'O', 2651 '\u01A0': 'O', 2652 '\u1EDC': 'O', 2653 '\u1EDA': 'O', 2654 '\u1EE0': 'O', 2655 '\u1EDE': 'O', 2656 '\u1EE2': 'O', 2657 '\u1ECC': 'O', 2658 '\u1ED8': 'O', 2659 '\u01EA': 'O', 2660 '\u01EC': 'O', 2661 '\u00D8': 'O', 2662 '\u01FE': 'O', 2663 '\u0186': 'O', 2664 '\u019F': 'O', 2665 '\uA74A': 'O', 2666 '\uA74C': 'O', 2667 '\u0152': 'OE', 2668 '\u01A2': 'OI', 2669 '\uA74E': 'OO', 2670 '\u0222': 'OU', 2671 '\u24C5': 'P', 2672 '\uFF30': 'P', 2673 '\u1E54': 'P', 2674 '\u1E56': 'P', 2675 '\u01A4': 'P', 2676 '\u2C63': 'P', 2677 '\uA750': 'P', 2678 '\uA752': 'P', 2679 '\uA754': 'P', 2680 '\u24C6': 'Q', 2681 '\uFF31': 'Q', 2682 '\uA756': 'Q', 2683 '\uA758': 'Q', 2684 '\u024A': 'Q', 2685 '\u24C7': 'R', 2686 '\uFF32': 'R', 2687 '\u0154': 'R', 2688 '\u1E58': 'R', 2689 '\u0158': 'R', 2690 '\u0210': 'R', 2691 '\u0212': 'R', 2692 '\u1E5A': 'R', 2693 '\u1E5C': 'R', 2694 '\u0156': 'R', 2695 '\u1E5E': 'R', 2696 '\u024C': 'R', 2697 '\u2C64': 'R', 2698 '\uA75A': 'R', 2699 '\uA7A6': 'R', 2700 '\uA782': 'R', 2701 '\u24C8': 'S', 2702 '\uFF33': 'S', 2703 '\u1E9E': 'S', 2704 '\u015A': 'S', 2705 '\u1E64': 'S', 2706 '\u015C': 'S', 2707 '\u1E60': 'S', 2708 '\u0160': 'S', 2709 '\u1E66': 'S', 2710 '\u1E62': 'S', 2711 '\u1E68': 'S', 2712 '\u0218': 'S', 2713 '\u015E': 'S', 2714 '\u2C7E': 'S', 2715 '\uA7A8': 'S', 2716 '\uA784': 'S', 2717 '\u24C9': 'T', 2718 '\uFF34': 'T', 2719 '\u1E6A': 'T', 2720 '\u0164': 'T', 2721 '\u1E6C': 'T', 2722 '\u021A': 'T', 2723 '\u0162': 'T', 2724 '\u1E70': 'T', 2725 '\u1E6E': 'T', 2726 '\u0166': 'T', 2727 '\u01AC': 'T', 2728 '\u01AE': 'T', 2729 '\u023E': 'T', 2730 '\uA786': 'T', 2731 '\uA728': 'TZ', 2732 '\u24CA': 'U', 2733 '\uFF35': 'U', 2734 '\u00D9': 'U', 2735 '\u00DA': 'U', 2736 '\u00DB': 'U', 2737 '\u0168': 'U', 2738 '\u1E78': 'U', 2739 '\u016A': 'U', 2740 '\u1E7A': 'U', 2741 '\u016C': 'U', 2742 '\u00DC': 'U', 2743 '\u01DB': 'U', 2744 '\u01D7': 'U', 2745 '\u01D5': 'U', 2746 '\u01D9': 'U', 2747 '\u1EE6': 'U', 2748 '\u016E': 'U', 2749 '\u0170': 'U', 2750 '\u01D3': 'U', 2751 '\u0214': 'U', 2752 '\u0216': 'U', 2753 '\u01AF': 'U', 2754 '\u1EEA': 'U', 2755 '\u1EE8': 'U', 2756 '\u1EEE': 'U', 2757 '\u1EEC': 'U', 2758 '\u1EF0': 'U', 2759 '\u1EE4': 'U', 2760 '\u1E72': 'U', 2761 '\u0172': 'U', 2762 '\u1E76': 'U', 2763 '\u1E74': 'U', 2764 '\u0244': 'U', 2765 '\u24CB': 'V', 2766 '\uFF36': 'V', 2767 '\u1E7C': 'V', 2768 '\u1E7E': 'V', 2769 '\u01B2': 'V', 2770 '\uA75E': 'V', 2771 '\u0245': 'V', 2772 '\uA760': 'VY', 2773 '\u24CC': 'W', 2774 '\uFF37': 'W', 2775 '\u1E80': 'W', 2776 '\u1E82': 'W', 2777 '\u0174': 'W', 2778 '\u1E86': 'W', 2779 '\u1E84': 'W', 2780 '\u1E88': 'W', 2781 '\u2C72': 'W', 2782 '\u24CD': 'X', 2783 '\uFF38': 'X', 2784 '\u1E8A': 'X', 2785 '\u1E8C': 'X', 2786 '\u24CE': 'Y', 2787 '\uFF39': 'Y', 2788 '\u1EF2': 'Y', 2789 '\u00DD': 'Y', 2790 '\u0176': 'Y', 2791 '\u1EF8': 'Y', 2792 '\u0232': 'Y', 2793 '\u1E8E': 'Y', 2794 '\u0178': 'Y', 2795 '\u1EF6': 'Y', 2796 '\u1EF4': 'Y', 2797 '\u01B3': 'Y', 2798 '\u024E': 'Y', 2799 '\u1EFE': 'Y', 2800 '\u24CF': 'Z', 2801 '\uFF3A': 'Z', 2802 '\u0179': 'Z', 2803 '\u1E90': 'Z', 2804 '\u017B': 'Z', 2805 '\u017D': 'Z', 2806 '\u1E92': 'Z', 2807 '\u1E94': 'Z', 2808 '\u01B5': 'Z', 2809 '\u0224': 'Z', 2810 '\u2C7F': 'Z', 2811 '\u2C6B': 'Z', 2812 '\uA762': 'Z', 2813 '\u24D0': 'a', 2814 '\uFF41': 'a', 2815 '\u1E9A': 'a', 2816 '\u00E0': 'a', 2817 '\u00E1': 'a', 2818 '\u00E2': 'a', 2819 '\u1EA7': 'a', 2820 '\u1EA5': 'a', 2821 '\u1EAB': 'a', 2822 '\u1EA9': 'a', 2823 '\u00E3': 'a', 2824 '\u0101': 'a', 2825 '\u0103': 'a', 2826 '\u1EB1': 'a', 2827 '\u1EAF': 'a', 2828 '\u1EB5': 'a', 2829 '\u1EB3': 'a', 2830 '\u0227': 'a', 2831 '\u01E1': 'a', 2832 '\u00E4': 'a', 2833 '\u01DF': 'a', 2834 '\u1EA3': 'a', 2835 '\u00E5': 'a', 2836 '\u01FB': 'a', 2837 '\u01CE': 'a', 2838 '\u0201': 'a', 2839 '\u0203': 'a', 2840 '\u1EA1': 'a', 2841 '\u1EAD': 'a', 2842 '\u1EB7': 'a', 2843 '\u1E01': 'a', 2844 '\u0105': 'a', 2845 '\u2C65': 'a', 2846 '\u0250': 'a', 2847 '\uA733': 'aa', 2848 '\u00E6': 'ae', 2849 '\u01FD': 'ae', 2850 '\u01E3': 'ae', 2851 '\uA735': 'ao', 2852 '\uA737': 'au', 2853 '\uA739': 'av', 2854 '\uA73B': 'av', 2855 '\uA73D': 'ay', 2856 '\u24D1': 'b', 2857 '\uFF42': 'b', 2858 '\u1E03': 'b', 2859 '\u1E05': 'b', 2860 '\u1E07': 'b', 2861 '\u0180': 'b', 2862 '\u0183': 'b', 2863 '\u0253': 'b', 2864 '\u24D2': 'c', 2865 '\uFF43': 'c', 2866 '\u0107': 'c', 2867 '\u0109': 'c', 2868 '\u010B': 'c', 2869 '\u010D': 'c', 2870 '\u00E7': 'c', 2871 '\u1E09': 'c', 2872 '\u0188': 'c', 2873 '\u023C': 'c', 2874 '\uA73F': 'c', 2875 '\u2184': 'c', 2876 '\u24D3': 'd', 2877 '\uFF44': 'd', 2878 '\u1E0B': 'd', 2879 '\u010F': 'd', 2880 '\u1E0D': 'd', 2881 '\u1E11': 'd', 2882 '\u1E13': 'd', 2883 '\u1E0F': 'd', 2884 '\u0111': 'd', 2885 '\u018C': 'd', 2886 '\u0256': 'd', 2887 '\u0257': 'd', 2888 '\uA77A': 'd', 2889 '\u01F3': 'dz', 2890 '\u01C6': 'dz', 2891 '\u24D4': 'e', 2892 '\uFF45': 'e', 2893 '\u00E8': 'e', 2894 '\u00E9': 'e', 2895 '\u00EA': 'e', 2896 '\u1EC1': 'e', 2897 '\u1EBF': 'e', 2898 '\u1EC5': 'e', 2899 '\u1EC3': 'e', 2900 '\u1EBD': 'e', 2901 '\u0113': 'e', 2902 '\u1E15': 'e', 2903 '\u1E17': 'e', 2904 '\u0115': 'e', 2905 '\u0117': 'e', 2906 '\u00EB': 'e', 2907 '\u1EBB': 'e', 2908 '\u011B': 'e', 2909 '\u0205': 'e', 2910 '\u0207': 'e', 2911 '\u1EB9': 'e', 2912 '\u1EC7': 'e', 2913 '\u0229': 'e', 2914 '\u1E1D': 'e', 2915 '\u0119': 'e', 2916 '\u1E19': 'e', 2917 '\u1E1B': 'e', 2918 '\u0247': 'e', 2919 '\u025B': 'e', 2920 '\u01DD': 'e', 2921 '\u24D5': 'f', 2922 '\uFF46': 'f', 2923 '\u1E1F': 'f', 2924 '\u0192': 'f', 2925 '\uA77C': 'f', 2926 '\u24D6': 'g', 2927 '\uFF47': 'g', 2928 '\u01F5': 'g', 2929 '\u011D': 'g', 2930 '\u1E21': 'g', 2931 '\u011F': 'g', 2932 '\u0121': 'g', 2933 '\u01E7': 'g', 2934 '\u0123': 'g', 2935 '\u01E5': 'g', 2936 '\u0260': 'g', 2937 '\uA7A1': 'g', 2938 '\u1D79': 'g', 2939 '\uA77F': 'g', 2940 '\u24D7': 'h', 2941 '\uFF48': 'h', 2942 '\u0125': 'h', 2943 '\u1E23': 'h', 2944 '\u1E27': 'h', 2945 '\u021F': 'h', 2946 '\u1E25': 'h', 2947 '\u1E29': 'h', 2948 '\u1E2B': 'h', 2949 '\u1E96': 'h', 2950 '\u0127': 'h', 2951
2951 '\u2C68': 'h', 2952 '\u2C76': 'h', 2953 '\u0265': 'h', 2954 '\u0195': 'hv', 2955 '\u24D8': 'i', 2956 '\uFF49': 'i', 2957 '\u00EC': 'i', 2958 '\u00ED': 'i', 2959 '\u00EE': 'i', 2960 '\u0129': 'i', 2961 '\u012B': 'i', 2962 '\u012D': 'i', 2963 '\u00EF': 'i', 2964 '\u1E2F': 'i', 2965 '\u1EC9': 'i', 2966 '\u01D0': 'i', 2967 '\u0209': 'i', 2968 '\u020B': 'i', 2969 '\u1ECB': 'i', 2970 '\u012F': 'i', 2971 '\u1E2D': 'i', 2972 '\u0268': 'i', 2973 '\u0131': 'i', 2974 '\u24D9': 'j', 2975 '\uFF4A': 'j', 2976 '\u0135': 'j', 2977 '\u01F0': 'j', 2978 '\u0249': 'j', 2979 '\u24DA': 'k', 2980 '\uFF4B': 'k', 2981 '\u1E31': 'k', 2982 '\u01E9': 'k', 2983 '\u1E33': 'k', 2984 '\u0137': 'k', 2985 '\u1E35': 'k', 2986 '\u0199': 'k', 2987 '\u2C6A': 'k', 2988 '\uA741': 'k', 2989 '\uA743': 'k', 2990 '\uA745': 'k', 2991 '\uA7A3': 'k', 2992 '\u24DB': 'l', 2993 '\uFF4C': 'l', 2994 '\u0140': 'l', 2995 '\u013A': 'l', 2996 '\u013E': 'l', 2997 '\u1E37': 'l', 2998 '\u1E39': 'l', 2999 '\u013C': 'l', 3000 '\u1E3D': 'l', 3001 '\u1E3B': 'l', 3002 '\u017F': 'l', 3003 '\u0142': 'l', 3004 '\u019A': 'l', 3005 '\u026B': 'l', 3006 '\u2C61': 'l', 3007 '\uA749': 'l', 3008 '\uA781': 'l', 3009 '\uA747': 'l', 3010 '\u01C9': 'lj', 3011 '\u24DC': 'm', 3012 '\uFF4D': 'm', 3013 '\u1E3F': 'm', 3014 '\u1E41': 'm', 3015 '\u1E43': 'm', 3016 '\u0271': 'm', 3017 '\u026F': 'm', 3018 '\u24DD': 'n', 3019 '\uFF4E': 'n', 3020 '\u01F9': 'n', 3021 '\u0144': 'n', 3022 '\u00F1': 'n', 3023 '\u1E45': 'n', 3024 '\u0148': 'n', 3025 '\u1E47': 'n', 3026 '\u0146': 'n', 3027 '\u1E4B': 'n', 3028 '\u1E49': 'n', 3029 '\u019E': 'n', 3030 '\u0272': 'n', 3031 '\u0149': 'n', 3032 '\uA791': 'n', 3033 '\uA7A5': 'n', 3034 '\u01CC': 'nj', 3035 '\u24DE': 'o', 3036 '\uFF4F': 'o', 3037 '\u00F2': 'o', 3038 '\u00F3': 'o', 3039 '\u00F4': 'o', 3040 '\u1ED3': 'o', 3041 '\u1ED1': 'o', 3042 '\u1ED7': 'o', 3043 '\u1ED5': 'o', 3044 '\u00F5': 'o', 3045 '\u1E4D': 'o', 3046 '\u022D': 'o', 3047 '\u1E4F': 'o', 3048 '\u014D': 'o', 3049 '\u1E51': 'o', 3050 '\u1E53': 'o', 3051 '\u014F': 'o', 3052 '\u022F': 'o', 3053 '\u0231': 'o', 3054 '\u00F6': 'o', 3055 '\u022B': 'o', 3056 '\u1ECF': 'o', 3057 '\u0151': 'o', 3058 '\u01D2': 'o', 3059 '\u020D': 'o', 3060 '\u020F': 'o', 3061 '\u01A1': 'o', 3062 '\u1EDD': 'o', 3063 '\u1EDB': 'o', 3064 '\u1EE1': 'o', 3065 '\u1EDF': 'o', 3066 '\u1EE3': 'o', 3067 '\u1ECD': 'o', 3068 '\u1ED9': 'o', 3069 '\u01EB': 'o', 3070 '\u01ED': 'o', 3071 '\u00F8': 'o', 3072 '\u01FF': 'o', 3073 '\u0254': 'o', 3074 '\uA74B': 'o', 3075 '\uA74D': 'o', 3076 '\u0275': 'o', 3077 '\u0153': 'oe', 3078 '\u01A3': 'oi', 3079 '\u0223': 'ou', 3080 '\uA74F': 'oo', 3081 '\u24DF': 'p', 3082 '\uFF50': 'p', 3083 '\u1E55': 'p', 3084 '\u1E57': 'p', 3085 '\u01A5': 'p', 3086 '\u1D7D': 'p', 3087 '\uA751': 'p', 3088 '\uA753': 'p', 3089 '\uA755': 'p', 3090 '\u24E0': 'q', 3091 '\uFF51': 'q', 3092 '\u024B': 'q', 3093 '\uA757': 'q', 3094 '\uA759': 'q', 3095 '\u24E1': 'r', 3096 '\uFF52': 'r', 3097 '\u0155': 'r', 3098 '\u1E59': 'r', 3099 '\u0159': 'r', 3100 '\u0211': 'r', 3101 '\u0213': 'r', 3102 '\u1E5B': 'r', 3103 '\u1E5D': 'r', 3104 '\u0157': 'r', 3105 '\u1E5F': 'r', 3106 '\u024D': 'r', 3107 '\u027D': 'r', 3108 '\uA75B': 'r', 3109 '\uA7A7': 'r', 3110 '\uA783': 'r', 3111 '\u24E2': 's', 3112 '\uFF53': 's', 3113 '\u00DF': 's', 3114 '\u015B': 's', 3115 '\u1E65': 's', 3116 '\u015D': 's', 3117 '\u1E61': 's', 3118 '\u0161': 's', 3119 '\u1E67': 's', 3120 '\u1E63': 's', 3121 '\u1E69': 's', 3122 '\u0219': 's', 3123 '\u015F': 's', 3124 '\u023F': 's', 3125 '\uA7A9': 's', 3126 '\uA785': 's', 3127 '\u1E9B': 's', 3128 '\u24E3': 't', 3129 '\uFF54': 't', 3130 '\u1E6B': 't', 3131 '\u1E97': 't', 3132 '\u0165': 't', 3133 '\u1E6D': 't', 3134 '\u021B': 't', 3135 '\u0163': 't', 3136 '\u1E71': 't', 3137 '\u1E6F': 't', 3138 '\u0167': 't', 3139 '\u01AD': 't', 3140 '\u0288': 't', 3141 '\u2C66': 't', 3142 '\uA787': 't', 3143 '\uA729': 'tz', 3144 '\u24E4': 'u', 3145 '\uFF55': 'u', 3146 '\u00F9': 'u', 3147 '\u00FA': 'u', 3148 '\u00FB': 'u', 3149 '\u0169': 'u', 3150 '\u1E79': 'u', 3151 '\u016B': 'u', 3152 '\u1E7B': 'u', 3153 '\u016D': 'u', 3154 '\u00FC': 'u', 3155 '\u01DC': 'u', 3156 '\u01D8': 'u', 3157 '\u01D6': 'u', 3158 '\u01DA': 'u', 3159 '\u1EE7': 'u', 3160 '\u016F': 'u', 3161 '\u0171': 'u', 3162 '\u01D4': 'u', 3163 '\u0215': 'u', 3164 '\u0217': 'u', 3165 '\u01B0': 'u', 3166 '\u1EEB': 'u',
vendor: 86,407 bytes, lines 3167-6147
3167 '\u1EE9': 'u', 3168 '\u1EEF': 'u', 3169 '\u1EED': 'u', 3170 '\u1EF1': 'u', 3171 '\u1EE5': 'u', 3172 '\u1E73': 'u', 3173 '\u0173': 'u', 3174 '\u1E77': 'u', 3175 '\u1E75': 'u', 3176 '\u0289': 'u', 3177 '\u24E5': 'v', 3178 '\uFF56': 'v', 3179 '\u1E7D': 'v', 3180 '\u1E7F': 'v', 3181 '\u028B': 'v', 3182 '\uA75F': 'v', 3183 '\u028C': 'v', 3184 '\uA761': 'vy', 3185 '\u24E6': 'w', 3186 '\uFF57': 'w', 3187 '\u1E81': 'w', 3188 '\u1E83': 'w', 3189 '\u0175': 'w', 3190 '\u1E87': 'w', 3191 '\u1E85': 'w', 3192 '\u1E98': 'w', 3193 '\u1E89': 'w', 3194 '\u2C73': 'w', 3195 '\u24E7': 'x', 3196 '\uFF58': 'x', 3197 '\u1E8B': 'x', 3198 '\u1E8D': 'x', 3199 '\u24E8': 'y', 3200 '\uFF59': 'y', 3201 '\u1EF3': 'y', 3202 '\u00FD': 'y', 3203 '\u0177': 'y', 3204 '\u1EF9': 'y', 3205 '\u0233': 'y', 3206 '\u1E8F': 'y', 3207 '\u00FF': 'y', 3208 '\u1EF7': 'y', 3209 '\u1E99': 'y', 3210 '\u1EF5': 'y', 3211 '\u01B4': 'y', 3212 '\u024F': 'y', 3213 '\u1EFF': 'y', 3214 '\u24E9': 'z', 3215 '\uFF5A': 'z', 3216 '\u017A': 'z', 3217 '\u1E91': 'z', 3218 '\u017C': 'z', 3219 '\u017E': 'z', 3220 '\u1E93': 'z', 3221 '\u1E95': 'z', 3222 '\u01B6': 'z', 3223 '\u0225': 'z', 3224 '\u0240': 'z', 3225 '\u2C6C': 'z', 3226 '\uA763': 'z', 3227 '\u0386': '\u0391', 3228 '\u0388': '\u0395', 3229 '\u0389': '\u0397', 3230 '\u038A': '\u0399', 3231 '\u03AA': '\u0399', 3232 '\u038C': '\u039F', 3233 '\u038E': '\u03A5', 3234 '\u03AB': '\u03A5', 3235 '\u038F': '\u03A9', 3236 '\u03AC': '\u03B1', 3237 '\u03AD': '\u03B5', 3238 '\u03AE': '\u03B7', 3239 '\u03AF': '\u03B9', 3240 '\u03CA': '\u03B9', 3241 '\u0390': '\u03B9', 3242 '\u03CC': '\u03BF', 3243 '\u03CD': '\u03C5', 3244 '\u03CB': '\u03C5', 3245 '\u03B0': '\u03C5', 3246 '\u03CE': '\u03C9', 3247 '\u03C2': '\u03C3', 3248 '\u2019': '\'' 3249 }; 3250 3251 return diacritics; 3252 }); 3253 3254 S2.define('select2/data/base', [ 3255 '../utils' 3256 ], function (Utils) { 3257 function BaseAdapter($element, options) { 3258 BaseAdapter.__super__.constructor.call(this); 3259 } 3260 3261 Utils.Extend(BaseAdapter, Utils.Observable); 3262 3263 BaseAdapter.prototype.current = function (callback) { 3264 throw new Error('The `current` method must be defined in child classes.'); 3265 }; 3266 3267 BaseAdapter.prototype.query = function (params, callback) { 3268 throw new Error('The `query` method must be defined in child classes.'); 3269 }; 3270 3271 BaseAdapter.prototype.bind = function (container, $container) { 3272 // Can be implemented in subclasses 3273 }; 3274 3275 BaseAdapter.prototype.destroy = function () { 3276 // Can be implemented in subclasses 3277 }; 3278 3279 BaseAdapter.prototype.generateResultId = function (container, data) { 3280 var id = container.id + '-result-'; 3281 3282 id += Utils.generateChars(4); 3283 3284 if (data.id != null) { 3285 id += '-' + data.id.toString(); 3286 } else { 3287 id += '-' + Utils.generateChars(4); 3288 } 3289 return id; 3290 }; 3291 3292 return BaseAdapter; 3293 }); 3294 3295 S2.define('select2/data/select', [ 3296 './base', 3297 '../utils', 3298 'jquery' 3299 ], function (BaseAdapter, Utils, $) { 3300 function SelectAdapter($element, options) { 3301 this.$element = $element; 3302 this.options = options; 3303 3304 SelectAdapter.__super__.constructor.call(this); 3305 } 3306 3307 Utils.Extend(SelectAdapter, BaseAdapter); 3308 3309 SelectAdapter.prototype.current = function (callback) { 3310 var self = this; 3311 3312 var data = Array.prototype.map.call( 3313 this.$element[0].querySelectorAll(':checked'), 3314 function (selectedElement) { 3315 return self.item($(selectedElement)); 3316 } 3317 ); 3318 3319 callback(data); 3320 }; 3321 3322 SelectAdapter.prototype.select = function (data) { 3323 var self = this; 3324 3325 data.selected = true; 3326 3327 // If data.element is a DOM node, use it instead 3328 if ( 3329 data.element != null && data.element.tagName.toLowerCase() === 'option' 3330 ) { 3331 data.element.selected = true; 3332 3333 this.$element.trigger('input').trigger('change'); 3334 3335 return; 3336 } 3337 3338 if (this.$element.prop('multiple')) { 3339 this.current(function (currentData) { 3340 var val = []; 3341 3342 data = [data]; 3343 data.push.apply(data, currentData); 3344 3345 for (var d = 0; d < data.length; d++) { 3346 var id = data[d].id; 3347 3348 if (val.indexOf(id) === -1) { 3349 val.push(id); 3350 } 3351 } 3352 3353 self.$element.val(val); 3354 self.$element.trigger('input').trigger('change'); 3355 }); 3356 } else { 3357 var val = data.id; 3358 3359 this.$element.val(val); 3360 this.$element.trigger('input').trigger('change'); 3361 } 3362 }; 3363 3364 SelectAdapter.prototype.unselect = function (data) { 3365 var self = this; 3366 3367 if (!this.$element.prop('multiple')) { 3368 return; 3369 } 3370 3371 data.selected = false; 3372 3373 if ( 3374 data.element != null && 3375 data.element.tagName.toLowerCase() === 'option' 3376 ) { 3377 data.element.selected = false; 3378 3379 this.$element.trigger('input').trigger('change'); 3380 3381 return; 3382 } 3383 3384 this.current(function (currentData) { 3385 var val = []; 3386 3387 for (var d = 0; d < currentData.length; d++) { 3388 var id = currentData[d].id; 3389 3390 if (id !== data.id && val.indexOf(id) === -1) { 3391 val.push(id); 3392 } 3393 } 3394 3395 self.$element.val(val); 3396 3397 self.$element.trigger('input').trigger('change'); 3398 }); 3399 }; 3400 3401 SelectAdapter.prototype.bind = function (container, $container) { 3402 var self = this; 3403 3404 this.container = container; 3405 3406 container.on('select', function (params) { 3407 self.select(params.data); 3408 }); 3409 3410 container.on('unselect', function (params) { 3411 self.unselect(params.data); 3412 }); 3413 }; 3414 3415 SelectAdapter.prototype.destroy = function () { 3416 // Remove anything added to child elements 3417 this.$element.find('*').each(function () { 3418 // Remove any custom data set by Select2 3419 Utils.RemoveData(this); 3420 }); 3421 }; 3422 3423 SelectAdapter.prototype.query = function (params, callback) { 3424 var data = []; 3425 var self = this; 3426 3427 var $options = this.$element.children(); 3428 3429 $options.each(function () { 3430 if ( 3431 this.tagName.toLowerCase() !== 'option' && 3432 this.tagName.toLowerCase() !== 'optgroup' 3433 ) { 3434 return; 3435 } 3436 3437 var $option = $(this); 3438 3439 var option = self.item($option); 3440 3441 var matches = self.matches(params, option); 3442 3443 if (matches !== null) { 3444 data.push(matches); 3445 } 3446 }); 3447 3448 callback({ 3449 results: data 3450 }); 3451 }; 3452 3453 SelectAdapter.prototype.addOptions = function ($options) { 3454 this.$element.append($options); 3455 }; 3456 3457 SelectAdapter.prototype.option = function (data) { 3458 var option; 3459 3460 if (data.children) { 3461 option = document.createElement('optgroup'); 3462 option.label = data.text; 3463 } else { 3464 option = document.createElement('option'); 3465 3466 if (option.textContent !== undefined) { 3467 option.textContent = data.text; 3468 } else { 3469 option.innerText = data.text; 3470 } 3471 } 3472 3473 if (data.id !== undefined) { 3474 option.value = data.id; 3475 } 3476 3477 if (data.disabled) { 3478 option.disabled = true; 3479 } 3480 3481 if (data.selected) { 3482 option.selected = true; 3483 } 3484 3485 if (data.title) { 3486 option.title = data.title; 3487 } 3488 3489 var normalizedData = this._normalizeItem(data); 3490 normalizedData.element = option; 3491 3492 // Override the option's data with the combined data 3493 Utils.StoreData(option, 'data', normalizedData); 3494 3495 return $(option); 3496 }; 3497 3498 SelectAdapter.prototype.item = function ($option) { 3499 var data = {}; 3500 3501 data = Utils.GetData($option[0], 'data'); 3502 3503 if (data != null) { 3504 return data; 3505 } 3506 3507 var option = $option[0]; 3508 3509 if (option.tagName.toLowerCase() === 'option') { 3510 data = { 3511 id: $option.val(), 3512 text: $option.text(), 3513 disabled: $option.prop('disabled'), 3514 selected: $option.prop('selected'), 3515 title: $option.prop('title') 3516 }; 3517 } else if (option.tagName.toLowerCase() === 'optgroup') { 3518 data = { 3519 text: $option.prop('label'), 3520 children: [], 3521 title: $option.prop('title') 3522 }; 3523 3524 var $children = $option.children('option'); 3525 var children = []; 3526 3527 for (var c = 0; c < $children.length; c++) { 3528 var $child = $($children[c]); 3529 3530 var child = this.item($child); 3531 3532 children.push(child); 3533 } 3534 3535 data.children = children; 3536 } 3537 3538 data = this._normalizeItem(data); 3539 data.element = $option[0]; 3540 3541 Utils.StoreData($option[0], 'data', data); 3542 3543 return data; 3544 }; 3545 3546 SelectAdapter.prototype._normalizeItem = function (item) { 3547 if (item !== Object(item)) { 3548 item = { 3549 id: item, 3550 text: item 3551 }; 3552 } 3553 3554 item = $.extend({}, { 3555 text: '' 3556 }, item); 3557 3558 var defaults = { 3559 selected: false, 3560 disabled: false 3561 }; 3562 3563 if (item.id != null) { 3564 item.id = item.id.toString(); 3565 } 3566 3567 if (item.text != null) { 3568 item.text = item.text.toString(); 3569 } 3570 3571 if (item._resultId == null && item.id && this.container != null) { 3572 item._resultId = this.generateResultId(this.container, item); 3573 } 3574 3575 return $.extend({}, defaults, item); 3576 }; 3577 3578 SelectAdapter.prototype.matches = function (params, data) { 3579 var matcher = this.options.get('matcher'); 3580 3581 return matcher(params, data); 3582 }; 3583 3584 return SelectAdapter; 3585 }); 3586 3587 S2.define('select2/data/array', [ 3588 './select', 3589 '../utils', 3590 'jquery' 3591 ], function (SelectAdapter, Utils, $) { 3592 function ArrayAdapter($element, options) { 3593 this._dataToConvert = options.get('data') || []; 3594 3595 ArrayAdapter.__super__.constructor.call(this, $element, options); 3596 } 3597 3598 Utils.Extend(ArrayAdapter, SelectAdapter); 3599 3600 ArrayAdapter.prototype.bind = function (container, $container) { 3601 ArrayAdapter.__super__.bind.call(this, container, $container); 3602 3603 this.addOptions(this.convertToOptions(this._dataToConvert)); 3604 }; 3605 3606 ArrayAdapter.prototype.select = function (data) { 3607 var $option = this.$element.find('option').filter(function (i, elm) { 3608 return elm.value == data.id.toString(); 3609 }); 3610 3611 if ($option.length === 0) { 3612 $option = this.option(data); 3613 3614 this.addOptions($option); 3615 } 3616 3617 ArrayAdapter.__super__.select.call(this, data); 3618 }; 3619 3620 ArrayAdapter.prototype.convertToOptions = function (data) { 3621 var self = this; 3622 3623 var $existing = this.$element.find('option'); 3624 var existingIds = $existing.map(function () { 3625 return self.item($(this)).id; 3626 }).get(); 3627 3628 var $options = []; 3629 3630 // Filter out all items except for the one passed in the argument 3631 function onlyItem(item) { 3632 return function () { 3633 return $(this).val() == item.id; 3634 }; 3635 } 3636 3637 for (var d = 0; d < data.length; d++) { 3638 var item = this._normalizeItem(data[d]); 3639 3640 // Skip items which were pre-loaded, only merge the data 3641 if (existingIds.indexOf(item.id) >= 0) { 3642 var $existingOption = $existing.filter(onlyItem(item)); 3643 3644 var existingData = this.item($existingOption); 3645 var newData = $.extend(true, {}, item, existingData); 3646 3647 var $newOption = this.option(newData); 3648 3649 $existingOption.replaceWith($newOption); 3650 3651 continue; 3652 } 3653 3654 var $option = this.option(item); 3655 3656 if (item.children) { 3657 var $children = this.convertToOptions(item.children); 3658 3659 $option.append($children); 3660 } 3661 3662 $options.push($option); 3663 } 3664 3665 return $options; 3666 }; 3667 3668 return ArrayAdapter; 3669 }); 3670 3671 S2.define('select2/data/ajax', [ 3672 './array', 3673 '../utils', 3674 'jquery' 3675 ], function (ArrayAdapter, Utils, $) { 3676 function AjaxAdapter($element, options) { 3677 this.ajaxOptions = this._applyDefaults(options.get('ajax')); 3678 3679 if (this.ajaxOptions.processResults != null) { 3680 this.processResults = this.ajaxOptions.processResults; 3681 } 3682 3683 AjaxAdapter.__super__.constructor.call(this, $element, options); 3684 } 3685 3686 Utils.Extend(AjaxAdapter, ArrayAdapter); 3687 3688 AjaxAdapter.prototype._applyDefaults = function (options) { 3689 var defaults = { 3690 data: function (params) { 3691 return $.extend({}, params, { 3692 q: params.term 3693 }); 3694 }, 3695 transport: function (params, success, failure) { 3696 var $request = $.ajax(params); 3697 3698 $request.then(success); 3699 $request.fail(failure); 3700 3701 return $request; 3702 } 3703 }; 3704 3705 return $.extend({}, defaults, options, true); 3706 }; 3707 3708 AjaxAdapter.prototype.processResults = function (results) { 3709 return results; 3710 }; 3711 3712 AjaxAdapter.prototype.query = function (params, callback) { 3713 var matches = []; 3714 var self = this; 3715 3716 if (this._request != null) { 3717 // JSONP requests cannot always be aborted 3718 if (typeof this._request.abort === 'function') { 3719 this._request.abort(); 3720 } 3721 3722 this._request = null; 3723 } 3724 3725 var options = $.extend({ 3726 type: 'GET' 3727 }, this.ajaxOptions); 3728 3729 if (typeof options.url === 'function') { 3730 options.url = options.url.call(this.$element, params); 3731 } 3732 3733 if (typeof options.data === 'function') { 3734 options.data = options.data.call(this.$element, params); 3735 } 3736 3737 function request() { 3738 var $request = options.transport(options, function (data) { 3739 var results = self.processResults(data, params); 3740 3741 if (self.options.get('debug') && window.console && console.error) { 3742 // Check to make sure that the response included a `results` key. 3743 if (!results || !results.results || !Array.isArray(results.results)) { 3744 console.error( 3745 'Select2: The AJAX results did not return an array in the ' + 3746 '`results` key of the response.' 3747 ); 3748 } 3749 } 3750 3751 callback(results); 3752 }, function () { 3753 // Attempt to detect if a request was aborted 3754 // Only works if the transport exposes a status property 3755 if ('status' in $request && 3756 ($request.status === 0 || $request.status === '0')) { 3757 return; 3758 } 3759 3760 self.trigger('results:message', { 3761 message: 'errorLoading' 3762 }); 3763 }); 3764 3765 self._request = $request; 3766 } 3767 3768 if (this.ajaxOptions.delay && params.term != null) { 3769 if (this._queryTimeout) { 3770 window.clearTimeout(this._queryTimeout); 3771 } 3772 3773 this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay); 3774 } else { 3775 request(); 3776 } 3777 }; 3778 3779 return AjaxAdapter; 3780 }); 3781 3782 S2.define('select2/data/tags', [ 3783 'jquery' 3784 ], function ($) { 3785 function Tags(decorated, $element, options) { 3786 var tags = options.get('tags'); 3787 3788 var createTag = options.get('createTag'); 3789 3790 if (createTag !== undefined) { 3791 this.createTag = createTag; 3792 } 3793 3794 var insertTag = options.get('insertTag'); 3795 3796 if (insertTag !== undefined) { 3797 this.insertTag = insertTag; 3798 } 3799 3800 decorated.call(this, $element, options); 3801 3802 if (Array.isArray(tags)) { 3803 for (var t = 0; t < tags.length; t++) { 3804 var tag = tags[t]; 3805 var item = this._normalizeItem(tag); 3806 3807 var $option = this.option(item); 3808 3809 this.$element.append($option); 3810 } 3811 } 3812 } 3813 3814 Tags.prototype.query = function (decorated, params, callback) { 3815 var self = this; 3816 3817 this._removeOldTags(); 3818 3819 if (params.term == null || params.page != null) { 3820 decorated.call(this, params, callback); 3821 return; 3822 } 3823 3824 function wrapper(obj, child) { 3825 var data = obj.results; 3826 3827 for (var i = 0; i < data.length; i++) { 3828 var option = data[i]; 3829 3830 var checkChildren = ( 3831 option.children != null && 3832 !wrapper({ 3833 results: option.children 3834 }, true) 3835 ); 3836 3837 var optionText = (option.text || '').toUpperCase(); 3838 var paramsTerm = (params.term || '').toUpperCase(); 3839 3840 var checkText = optionText === paramsTerm; 3841 3842 if (checkText || checkChildren) { 3843 if (child) { 3844 return false; 3845 } 3846 3847 obj.data = data; 3848 callback(obj); 3849 3850 return; 3851 } 3852 } 3853 3854 if (child) { 3855 return true; 3856 } 3857 3858 var tag = self.createTag(params); 3859 3860 if (tag != null) { 3861 var $option = self.option(tag); 3862 $option.attr('data-select2-tag', 'true'); 3863 3864 self.addOptions([$option]); 3865 3866 self.insertTag(data, tag); 3867 } 3868 3869 obj.results = data; 3870 3871 callback(obj); 3872 } 3873 3874 decorated.call(this, params, wrapper); 3875 }; 3876 3877 Tags.prototype.createTag = function (decorated, params) { 3878 if (params.term == null) { 3879 return null; 3880 } 3881 3882 var term = params.term.trim(); 3883 3884 if (term === '') { 3885 return null; 3886 } 3887 3888 return { 3889 id: term, 3890 text: term 3891 }; 3892 }; 3893 3894 Tags.prototype.insertTag = function (_, data, tag) { 3895 data.unshift(tag); 3896 }; 3897 3898 Tags.prototype._removeOldTags = function (_) { 3899 var $options = this.$element.find('option[data-select2-tag]'); 3900 3901 $options.each(function () { 3902 if (this.selected) { 3903 return; 3904 } 3905 3906 $(this).remove(); 3907 }); 3908 }; 3909 3910 return Tags; 3911 }); 3912 3913 S2.define('select2/data/tokenizer', [ 3914 'jquery' 3915 ], function ($) { 3916 function Tokenizer(decorated, $element, options) { 3917 var tokenizer = options.get('tokenizer'); 3918 3919 if (tokenizer !== undefined) { 3920 this.tokenizer = tokenizer; 3921 } 3922 3923 decorated.call(this, $element, options); 3924 } 3925 3926 Tokenizer.prototype.bind = function (decorated, container, $container) { 3927 decorated.call(this, container, $container); 3928 3929 this.$search = container.dropdown.$search || container.selection.$search || 3930 $container.find('.select2-search__field'); 3931 }; 3932 3933 Tokenizer.prototype.query = function (decorated, params, callback) { 3934 var self = this; 3935 3936 function createAndSelect(data) { 3937 // Normalize the data object so we can use it for checks 3938 var item = self._normalizeItem(data); 3939 3940 // Check if the data object already exists as a tag 3941 // Select it if it doesn't 3942 var $existingOptions = self.$element.find('option').filter(function () { 3943 return $(this).val() === item.id; 3944 }); 3945 3946 // If an existing option wasn't found for it, create the option 3947 if (!$existingOptions.length) { 3948 var $option = self.option(item); 3949 $option.attr('data-select2-tag', true); 3950 3951 self._removeOldTags(); 3952 self.addOptions([$option]); 3953 } 3954 3955 // Select the item, now that we know there is an option for it 3956 select(item); 3957 } 3958 3959 function select(data) { 3960 self.trigger('select', { 3961 data: data 3962 }); 3963 } 3964 3965 params.term = params.term || ''; 3966 3967 var tokenData = this.tokenizer(params, this.options, createAndSelect); 3968 3969 if (tokenData.term !== params.term) { 3970 // Replace the search term if we have the search box 3971 if (this.$search.length) { 3972 this.$search.val(tokenData.term); 3973 this.$search.trigger('focus'); 3974 } 3975 3976 params.term = tokenData.term; 3977 } 3978 3979 decorated.call(this, params, callback); 3980 }; 3981 3982 Tokenizer.prototype.tokenizer = function (_, params, options, callback) { 3983 var separators = options.get('tokenSeparators') || []; 3984 var term = params.term; 3985 var i = 0; 3986 3987 var createTag = this.createTag || function (params) { 3988 return { 3989 id: params.term, 3990 text: params.term 3991 }; 3992 }; 3993 3994 while (i < term.length) { 3995 var termChar = term[i]; 3996 3997 if (separators.indexOf(termChar) === -1) { 3998 i++; 3999 4000 continue; 4001 } 4002 4003 var part = term.substr(0, i); 4004 var partParams = $.extend({}, params, { 4005 term: part 4006 }); 4007 4008 var data = createTag(partParams); 4009 4010 if (data == null) { 4011 i++; 4012 continue; 4013 } 4014 4015 callback(data); 4016 4017 // Reset the term to not include the tokenized portion 4018 term = term.substr(i + 1) || ''; 4019 i = 0; 4020 } 4021 4022 return { 4023 term: term 4024 }; 4025 }; 4026 4027 return Tokenizer; 4028 }); 4029 4030 S2.define('select2/data/minimumInputLength', [ 4031 4032 ], function () { 4033 function MinimumInputLength(decorated, $e, options) { 4034 this.minimumInputLength = options.get('minimumInputLength'); 4035 4036 decorated.call(this, $e, options); 4037 } 4038 4039 MinimumInputLength.prototype.query = function (decorated, params, callback) { 4040 params.term = params.term || ''; 4041 4042 if (params.term.length < this.minimumInputLength) { 4043 this.trigger('results:message', { 4044 message: 'inputTooShort', 4045 args: { 4046 minimum: this.minimumInputLength, 4047 input: params.term, 4048 params: params 4049 } 4050 }); 4051 4052 return; 4053 } 4054 4055 decorated.call(this, params, callback); 4056 }; 4057 4058 return MinimumInputLength; 4059 }); 4060 4061 S2.define('select2/data/maximumInputLength', [ 4062 4063 ], function () { 4064 function MaximumInputLength(decorated, $e, options) { 4065 this.maximumInputLength = options.get('maximumInputLength'); 4066 4067 decorated.call(this, $e, options); 4068 } 4069 4070 MaximumInputLength.prototype.query = function (decorated, params, callback) { 4071 params.term = params.term || ''; 4072 4073 if (this.maximumInputLength > 0 && 4074 params.term.length > this.maximumInputLength) { 4075 this.trigger('results:message', { 4076 message: 'inputTooLong', 4077 args: { 4078 maximum: this.maximumInputLength, 4079 input: params.term, 4080 params: params 4081 } 4082 }); 4083 4084 return; 4085 } 4086 4087 decorated.call(this, params, callback); 4088 }; 4089 4090 return MaximumInputLength; 4091 }); 4092 4093 S2.define('select2/data/maximumSelectionLength', [ 4094 4095 ], function () { 4096 function MaximumSelectionLength(decorated, $e, options) { 4097 this.maximumSelectionLength = options.get('maximumSelectionLength'); 4098 4099 decorated.call(this, $e, options); 4100 } 4101 4102 MaximumSelectionLength.prototype.bind = 4103 function (decorated, container, $container) { 4104 var self = this; 4105 4106 decorated.call(this, container, $container); 4107 4108 container.on('select', function () { 4109 self._checkIfMaximumSelected(); 4110 }); 4111 }; 4112 4113 MaximumSelectionLength.prototype.query = 4114 function (decorated, params, callback) { 4115 var self = this; 4116 4117 this._checkIfMaximumSelected(function () { 4118 decorated.call(self, params, callback); 4119 }); 4120 }; 4121 4122 MaximumSelectionLength.prototype._checkIfMaximumSelected = 4123 function (_, successCallback) { 4124 var self = this; 4125 4126 this.current(function (currentData) { 4127 var count = currentData != null ? currentData.length : 0; 4128 if (self.maximumSelectionLength > 0 && 4129 count >= self.maximumSelectionLength) { 4130 self.trigger('results:message', { 4131 message: 'maximumSelected', 4132 args: { 4133 maximum: self.maximumSelectionLength 4134 } 4135 }); 4136 return; 4137 } 4138 4139 if (successCallback) { 4140 successCallback(); 4141 } 4142 }); 4143 }; 4144 4145 return MaximumSelectionLength; 4146 }); 4147 4148 S2.define('select2/dropdown', [ 4149 'jquery', 4150 './utils' 4151 ], function ($, Utils) { 4152 function Dropdown($element, options) { 4153 this.$element = $element; 4154 this.options = options; 4155 4156 Dropdown.__super__.constructor.call(this); 4157 } 4158 4159 Utils.Extend(Dropdown, Utils.Observable); 4160 4161 Dropdown.prototype.render = function () { 4162 var $dropdown = $( 4163 '<span class="select2-dropdown">' + 4164 '<span class="select2-results"></span>' + 4165 '</span>' 4166 ); 4167 4168 $dropdown.attr('dir', this.options.get('dir')); 4169 4170 this.$dropdown = $dropdown; 4171 4172 return $dropdown; 4173 }; 4174 4175 Dropdown.prototype.bind = function () { 4176 // Should be implemented in subclasses 4177 }; 4178 4179 Dropdown.prototype.position = function ($dropdown, $container) { 4180 // Should be implemented in subclasses 4181 }; 4182 4183 Dropdown.prototype.destroy = function () { 4184 // Remove the dropdown from the DOM 4185 this.$dropdown.remove(); 4186 }; 4187 4188 return Dropdown; 4189 }); 4190 4191 S2.define('select2/dropdown/search', [ 4192 'jquery' 4193 ], function ($) { 4194 function Search() { } 4195 4196 Search.prototype.render = function (decorated) { 4197 var $rendered = decorated.call(this); 4198 var searchLabel = this.options.get('translations').get('search'); 4199 4200 var $search = $( 4201 '<span class="select2-search select2-search--dropdown">' + 4202 '<input class="select2-search__field" type="search" tabindex="-1"' + 4203 ' autocorrect="off" autocapitalize="none"' + 4204 ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' + 4205 '</span>' 4206 ); 4207 4208 this.$searchContainer = $search; 4209 this.$search = $search.find('input'); 4210 4211 this.$search.prop('autocomplete', this.options.get('autocomplete')); 4212 this.$search.attr('aria-label', searchLabel()); 4213 4214 $rendered.prepend($search); 4215 4216 return $rendered; 4217 }; 4218 4219 Search.prototype.bind = function (decorated, container, $container) { 4220 var self = this; 4221 4222 var resultsId = container.id + '-results'; 4223 4224 decorated.call(this, container, $container); 4225 4226 this.$search.on('keydown', function (evt) { 4227 self.trigger('keypress', evt); 4228 4229 self._keyUpPrevented = evt.isDefaultPrevented(); 4230 }); 4231 4232 // Workaround for browsers which do not support the `input` event 4233 // This will prevent double-triggering of events for browsers which support 4234 // both the `keyup` and `input` events. 4235 this.$search.on('input', function (evt) { 4236 // Unbind the duplicated `keyup` event 4237 $(this).off('keyup'); 4238 }); 4239 4240 this.$search.on('keyup input', function (evt) { 4241 self.handleSearch(evt); 4242 }); 4243 4244 container.on('open', function () { 4245 self.$search.attr('tabindex', 0); 4246 self.$search.attr('aria-controls', resultsId); 4247 4248 self.$search.trigger('focus'); 4249 4250 window.setTimeout(function () { 4251 self.$search.trigger('focus'); 4252 }, 0); 4253 }); 4254 4255 container.on('close', function () { 4256 self.$search.attr('tabindex', -1); 4257 self.$search.removeAttr('aria-controls'); 4258 self.$search.removeAttr('aria-activedescendant'); 4259 4260 self.$search.val(''); 4261 self.$search.trigger('blur'); 4262 }); 4263 4264 container.on('focus', function () { 4265 if (!container.isOpen()) { 4266 self.$search.trigger('focus'); 4267 } 4268 }); 4269 4270 container.on('results:all', function (params) { 4271 if (params.query.term == null || params.query.term === '') { 4272 var showSearch = self.showSearch(params); 4273 4274 if (showSearch) { 4275 self.$searchContainer[0].classList.remove('select2-search--hide'); 4276 } else { 4277 self.$searchContainer[0].classList.add('select2-search--hide'); 4278 } 4279 } 4280 }); 4281 4282 container.on('results:focus', function (params) { 4283 if (params.data._resultId) { 4284 self.$search.attr('aria-activedescendant', params.data._resultId); 4285 } else { 4286 self.$search.removeAttr('aria-activedescendant'); 4287 } 4288 }); 4289 }; 4290 4291 Search.prototype.handleSearch = function (evt) { 4292 if (!this._keyUpPrevented) { 4293 var input = this.$search.val(); 4294 4295 this.trigger('query', { 4296 term: input 4297 }); 4298 } 4299 4300 this._keyUpPrevented = false; 4301 }; 4302 4303 Search.prototype.showSearch = function (_, params) { 4304 return true; 4305 }; 4306 4307 return Search; 4308 }); 4309 4310 S2.define('select2/dropdown/hidePlaceholder', [ 4311 4312 ], function () { 4313 function HidePlaceholder(decorated, $element, options, dataAdapter) { 4314 this.placeholder = this.normalizePlaceholder(options.get('placeholder')); 4315 4316 decorated.call(this, $element, options, dataAdapter); 4317 } 4318 4319 HidePlaceholder.prototype.append = function (decorated, data) { 4320 data.results = this.removePlaceholder(data.results); 4321 4322 decorated.call(this, data); 4323 }; 4324 4325 HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) { 4326 if (typeof placeholder === 'string') { 4327 placeholder = { 4328 id: '', 4329 text: placeholder 4330 }; 4331 } 4332 4333 return placeholder; 4334 }; 4335 4336 HidePlaceholder.prototype.removePlaceholder = function (_, data) { 4337 var modifiedData = data.slice(0); 4338 4339 for (var d = data.length - 1; d >= 0; d--) { 4340 var item = data[d]; 4341 4342 if (this.placeholder.id === item.id) { 4343 modifiedData.splice(d, 1); 4344 } 4345 } 4346 4347 return modifiedData; 4348 }; 4349 4350 return HidePlaceholder; 4351 }); 4352 4353 S2.define('select2/dropdown/infiniteScroll', [ 4354 'jquery' 4355 ], function ($) { 4356 function InfiniteScroll(decorated, $element, options, dataAdapter) { 4357 this.lastParams = {}; 4358 4359 decorated.call(this, $element, options, dataAdapter); 4360 4361 this.$loadingMore = this.createLoadingMore(); 4362 this.loading = false; 4363 } 4364 4365 InfiniteScroll.prototype.append = function (decorated, data) { 4366 this.$loadingMore.remove(); 4367 this.loading = false; 4368 4369 decorated.call(this, data); 4370 4371 if (this.showLoadingMore(data)) { 4372 this.$results.append(this.$loadingMore); 4373 this.loadMoreIfNeeded(); 4374 } 4375 }; 4376 4377 InfiniteScroll.prototype.bind = function (decorated, container, $container) { 4378 var self = this; 4379 4380 decorated.call(this, container, $container); 4381 4382 container.on('query', function (params) { 4383 self.lastParams = params; 4384 self.loading = true; 4385 }); 4386 4387 container.on('query:append', function (params) { 4388 self.lastParams = params; 4389 self.loading = true; 4390 }); 4391 4392 this.$results.on('scroll', this.loadMoreIfNeeded.bind(this)); 4393 }; 4394 4395 InfiniteScroll.prototype.loadMoreIfNeeded = function () { 4396 var isLoadMoreVisible = $.contains( 4397 document.documentElement, 4398 this.$loadingMore[0] 4399 ); 4400 4401 if (this.loading || !isLoadMoreVisible) { 4402 return; 4403 } 4404 4405 var currentOffset = this.$results.offset().top + 4406 this.$results.outerHeight(false); 4407 var loadingMoreOffset = this.$loadingMore.offset().top + 4408 this.$loadingMore.outerHeight(false); 4409 4410 if (currentOffset + 50 >= loadingMoreOffset) { 4411 this.loadMore(); 4412 } 4413 }; 4414 4415 InfiniteScroll.prototype.loadMore = function () { 4416 this.loading = true; 4417 4418 var params = $.extend({}, { page: 1 }, this.lastParams); 4419 4420 params.page++; 4421 4422 this.trigger('query:append', params); 4423 }; 4424 4425 InfiniteScroll.prototype.showLoadingMore = function (_, data) { 4426 return data.pagination && data.pagination.more; 4427 }; 4428 4429 InfiniteScroll.prototype.createLoadingMore = function () { 4430 var $option = $( 4431 '<li ' + 4432 'class="select2-results__option select2-results__option--load-more"' + 4433 'role="option" aria-disabled="true"></li>' 4434 ); 4435 4436 var message = this.options.get('translations').get('loadingMore'); 4437 4438 $option.html(message(this.lastParams)); 4439 4440 return $option; 4441 }; 4442 4443 return InfiniteScroll; 4444 }); 4445 4446 S2.define('select2/dropdown/attachBody', [ 4447 'jquery', 4448 '../utils' 4449 ], function ($, Utils) { 4450 function AttachBody(decorated, $element, options) { 4451 this.$dropdownParent = $(options.get('dropdownParent') || document.body); 4452 4453 decorated.call(this, $element, options); 4454 } 4455 4456 AttachBody.prototype.bind = function (decorated, container, $container) { 4457 var self = this; 4458 4459 decorated.call(this, container, $container); 4460 4461 container.on('open', function () { 4462 self._showDropdown(); 4463 self._attachPositioningHandler(container); 4464 4465 // Must bind after the results handlers to ensure correct sizing 4466 self._bindContainerResultHandlers(container); 4467 }); 4468 4469 container.on('close', function () { 4470 self._hideDropdown(); 4471 self._detachPositioningHandler(container); 4472 }); 4473 4474 this.$dropdownContainer.on('mousedown', function (evt) { 4475 evt.stopPropagation(); 4476 }); 4477 }; 4478 4479 AttachBody.prototype.destroy = function (decorated) { 4480 decorated.call(this); 4481 4482 this.$dropdownContainer.remove(); 4483 }; 4484 4485 AttachBody.prototype.position = function (decorated, $dropdown, $container) { 4486 // Clone all of the container classes 4487 $dropdown.attr('class', $container.attr('class')); 4488 4489 $dropdown[0].classList.remove('select2'); 4490 $dropdown[0].classList.add('select2-container--open'); 4491 4492 $dropdown.css({ 4493 position: 'absolute', 4494 top: -999999 4495 }); 4496 4497 this.$container = $container; 4498 }; 4499 4500 AttachBody.prototype.render = function (decorated) { 4501 var $container = $('<span></span>'); 4502 4503 var $dropdown = decorated.call(this); 4504 $container.append($dropdown); 4505 4506 this.$dropdownContainer = $container; 4507 4508 return $container; 4509 }; 4510 4511 AttachBody.prototype._hideDropdown = function (decorated) { 4512 this.$dropdownContainer.detach(); 4513 }; 4514 4515 AttachBody.prototype._bindContainerResultHandlers = 4516 function (decorated, container) { 4517 4518 // These should only be bound once 4519 if (this._containerResultsHandlersBound) { 4520 return; 4521 } 4522 4523 var self = this; 4524 4525 container.on('results:all', function () { 4526 self._positionDropdown(); 4527 self._resizeDropdown(); 4528 }); 4529 4530 container.on('results:append', function () { 4531 self._positionDropdown(); 4532 self._resizeDropdown(); 4533 }); 4534 4535 container.on('results:message', function () { 4536 self._positionDropdown(); 4537 self._resizeDropdown(); 4538 }); 4539 4540 container.on('select', function () { 4541 self._positionDropdown(); 4542 self._resizeDropdown(); 4543 }); 4544 4545 container.on('unselect', function () { 4546 self._positionDropdown(); 4547 self._resizeDropdown(); 4548 }); 4549 4550 this._containerResultsHandlersBound = true; 4551 }; 4552 4553 AttachBody.prototype._attachPositioningHandler = 4554 function (decorated, container) { 4555 var self = this; 4556 4557 var scrollEvent = 'scroll.select2.' + container.id; 4558 var resizeEvent = 'resize.select2.' + container.id; 4559 var orientationEvent = 'orientationchange.select2.' + container.id; 4560 4561 var $watchers = this.$container.parents().filter(Utils.hasScroll); 4562 $watchers.each(function () { 4563 Utils.StoreData(this, 'select2-scroll-position', { 4564 x: $(this).scrollLeft(), 4565 y: $(this).scrollTop() 4566 }); 4567 }); 4568 4569 $watchers.on(scrollEvent, function (ev) { 4570 var position = Utils.GetData(this, 'select2-scroll-position'); 4571 $(this).scrollTop(position.y); 4572 }); 4573 4574 $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent, 4575 function (e) { 4576 self._positionDropdown(); 4577 self._resizeDropdown(); 4578 }); 4579 }; 4580 4581 AttachBody.prototype._detachPositioningHandler = 4582 function (decorated, container) { 4583 var scrollEvent = 'scroll.select2.' + container.id; 4584 var resizeEvent = 'resize.select2.' + container.id; 4585 var orientationEvent = 'orientationchange.select2.' + container.id; 4586 4587 var $watchers = this.$container.parents().filter(Utils.hasScroll); 4588 $watchers.off(scrollEvent); 4589 4590 $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent); 4591 }; 4592 4593 AttachBody.prototype._positionDropdown = function () { 4594 var $window = $(window); 4595 4596 var isCurrentlyAbove = this.$dropdown[0].classList 4597 .contains('select2-dropdown--above'); 4598 var isCurrentlyBelow = this.$dropdown[0].classList 4599 .contains('select2-dropdown--below'); 4600 4601 var newDirection = null; 4602 4603 var offset = this.$container.offset(); 4604 4605 offset.bottom = offset.top + this.$container.outerHeight(false); 4606 4607 var container = { 4608 height: this.$container.outerHeight(false) 4609 }; 4610 4611 container.top = offset.top; 4612 container.bottom = offset.top + container.height; 4613 if ($('#wpadminbar').length > 0) { 4614 // container.top = offset.top + $('#wpadminbar').outerHeight(); 4615 // container.bottom = offset.top + container.height - $('#wpadminbar').outerHeight(); 4616 } 4617 4618 var dropdown = { 4619 height: this.$dropdown.outerHeight(false) 4620 }; 4621 4622 var viewport = { 4623 top: $window.scrollTop(), 4624 bottom: $window.scrollTop() + $window.height() 4625 }; 4626 4627 var enoughRoomAbove = viewport.top < (offset.top - dropdown.height); 4628 var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height); 4629 4630 var css = { 4631 left: offset.left, 4632 top: container.bottom 4633 }; 4634 4635 // Determine what the parent element is to use for calculating the offset 4636 var $offsetParent = this.$dropdownParent; 4637 4638 // For statically positioned elements, we need to get the element 4639 // that is determining the offset 4640 if ($offsetParent.css('position') === 'static') { 4641 $offsetParent = $offsetParent.offsetParent(); 4642 } 4643 4644 var parentOffset = { 4645 top: 0, 4646 left: 0 4647 }; 4648 4649 if ( 4650 $.contains(document.body, $offsetParent[0]) || 4651 $offsetParent[0].isConnected 4652 ) { 4653 parentOffset = $offsetParent.offset(); 4654 } 4655 4656 css.top -= parentOffset.top; 4657 css.left -= parentOffset.left; 4658 4659 if (!isCurrentlyAbove && !isCurrentlyBelow) { 4660 newDirection = 'below'; 4661 } 4662 4663 if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) { 4664 newDirection = 'above'; 4665 } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) { 4666 newDirection = 'below'; 4667 } 4668 4669 if (newDirection == 'above' || 4670 (isCurrentlyAbove && newDirection !== 'below')) { 4671 css.top = container.top - parentOffset.top - dropdown.height; 4672 } 4673 4674 if (newDirection != null) { 4675 this.$dropdown[0].classList.remove('select2-dropdown--below'); 4676 this.$dropdown[0].classList.remove('select2-dropdown--above'); 4677 this.$dropdown[0].classList.add('select2-dropdown--' + newDirection); 4678 4679 this.$container[0].classList.remove('select2-container--below'); 4680 this.$container[0].classList.remove('select2-container--above'); 4681 this.$container[0].classList.add('select2-container--' + newDirection); 4682 } 4683 4684 this.$dropdownContainer.css(css); 4685 }; 4686 4687 AttachBody.prototype._resizeDropdown = function () { 4688 var css = { 4689 width: this.$container.outerWidth(false) + 'px' 4690 }; 4691 4692 if (this.options.get('dropdownAutoWidth')) { 4693 css.minWidth = css.width; 4694 css.position = 'relative'; 4695 css.width = 'auto'; 4696 } 4697 4698 this.$dropdown.css(css); 4699 }; 4700 4701 AttachBody.prototype._showDropdown = function (decorated) { 4702 this.$dropdownContainer.appendTo(this.$dropdownParent); 4703 4704 this._positionDropdown(); 4705 this._resizeDropdown(); 4706 }; 4707 4708 return AttachBody; 4709 }); 4710 4711 S2.define('select2/dropdown/minimumResultsForSearch', [ 4712 4713 ], function () { 4714 function countResults(data) { 4715 var count = 0; 4716 4717 for (var d = 0; d < data.length; d++) { 4718 var item = data[d]; 4719 4720 if (item.children) { 4721 count += countResults(item.children); 4722 } else { 4723 count++; 4724 } 4725 } 4726 4727 return count; 4728 } 4729 4730 function MinimumResultsForSearch(decorated, $element, options, dataAdapter) { 4731 this.minimumResultsForSearch = options.get('minimumResultsForSearch'); 4732 4733 if (this.minimumResultsForSearch < 0) { 4734 this.minimumResultsForSearch = Infinity; 4735 } 4736 4737 decorated.call(this, $element, options, dataAdapter); 4738 } 4739 4740 MinimumResultsForSearch.prototype.showSearch = function (decorated, params) { 4741 if (countResults(params.data.results) < this.minimumResultsForSearch) { 4742 return false; 4743 } 4744 4745 return decorated.call(this, params); 4746 }; 4747 4748 return MinimumResultsForSearch; 4749 }); 4750 4751 S2.define('select2/dropdown/selectOnClose', [ 4752 '../utils' 4753 ], function (Utils) { 4754 function SelectOnClose() { } 4755 4756 SelectOnClose.prototype.bind = function (decorated, container, $container) { 4757 var self = this; 4758 4759 decorated.call(this, container, $container); 4760 4761 container.on('close', function (params) { 4762 self._handleSelectOnClose(params); 4763 }); 4764 }; 4765 4766 SelectOnClose.prototype._handleSelectOnClose = function (_, params) { 4767 if (params && params.originalSelect2Event != null) { 4768 var event = params.originalSelect2Event; 4769 4770 // Don't select an item if the close event was triggered from a select or 4771 // unselect event 4772 if (event._type === 'select' || event._type === 'unselect') { 4773 return; 4774 } 4775 } 4776 4777 var $highlightedResults = this.getHighlightedResults(); 4778 4779 // Only select highlighted results 4780 if ($highlightedResults.length < 1) { 4781 return; 4782 } 4783 4784 var data = Utils.GetData($highlightedResults[0], 'data'); 4785 4786 // Don't re-select already selected resulte 4787 if ( 4788 (data.element != null && data.element.selected) || 4789 (data.element == null && data.selected) 4790 ) { 4791 return; 4792 } 4793 4794 this.trigger('select', { 4795 data: data 4796 }); 4797 }; 4798 4799 return SelectOnClose; 4800 }); 4801 4802 S2.define('select2/dropdown/closeOnSelect', [ 4803 4804 ], function () { 4805 function CloseOnSelect() { } 4806 4807 CloseOnSelect.prototype.bind = function (decorated, container, $container) { 4808 var self = this; 4809 4810 decorated.call(this, container, $container); 4811 4812 container.on('select', function (evt) { 4813 self._selectTriggered(evt); 4814 }); 4815 4816 container.on('unselect', function (evt) { 4817 self._selectTriggered(evt); 4818 }); 4819 }; 4820 4821 CloseOnSelect.prototype._selectTriggered = function (_, evt) { 4822 var originalEvent = evt.originalEvent; 4823 4824 // Don't close if the control key is being held 4825 if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) { 4826 return; 4827 } 4828 4829 this.trigger('close', { 4830 originalEvent: originalEvent, 4831 originalSelect2Event: evt 4832 }); 4833 }; 4834 4835 return CloseOnSelect; 4836 }); 4837 4838 S2.define('select2/dropdown/dropdownCss', [ 4839 '../utils' 4840 ], function (Utils) { 4841 function DropdownCSS() { } 4842 4843 DropdownCSS.prototype.render = function (decorated) { 4844 var $dropdown = decorated.call(this); 4845 4846 var dropdownCssClass = this.options.get('dropdownCssClass') || ''; 4847 4848 if (dropdownCssClass.indexOf(':all:') !== -1) { 4849 dropdownCssClass = dropdownCssClass.replace(':all:', ''); 4850 4851 Utils.copyNonInternalCssClasses($dropdown[0], this.$element[0]); 4852 } 4853 4854 $dropdown.addClass(dropdownCssClass); 4855 4856 return $dropdown; 4857 }; 4858 4859 return DropdownCSS; 4860 }); 4861 4862 S2.define('select2/dropdown/tagsSearchHighlight', [ 4863 '../utils' 4864 ], function (Utils) { 4865 function TagsSearchHighlight() { } 4866 4867 TagsSearchHighlight.prototype.highlightFirstItem = function (decorated) { 4868 var $options = this.$results 4869 .find( 4870 '.select2-results__option--selectable' + 4871 ':not(.select2-results__option--selected)' 4872 ); 4873 4874 if ($options.length > 0) { 4875 var $firstOption = $options.first(); 4876 var data = Utils.GetData($firstOption[0], 'data'); 4877 var firstElement = data.element; 4878 4879 if (firstElement && firstElement.getAttribute) { 4880 if (firstElement.getAttribute('data-select2-tag') === 'true') { 4881 $firstOption.trigger('mouseenter'); 4882 4883 return; 4884 } 4885 } 4886 } 4887 4888 decorated.call(this); 4889 }; 4890 4891 return TagsSearchHighlight; 4892 }); 4893 4894 S2.define('select2/i18n/en', [], function () { 4895 // English 4896 return { 4897 errorLoading: function () { 4898 return 'The results could not be loaded.'; 4899 }, 4900 inputTooLong: function (args) { 4901 var overChars = args.input.length - args.maximum; 4902 4903 var message = 'Please delete ' + overChars + ' character'; 4904 4905 if (overChars != 1) { 4906 message += 's'; 4907 } 4908 4909 return message; 4910 }, 4911 inputTooShort: function (args) { 4912 var remainingChars = args.minimum - args.input.length; 4913 4914 var message = 'Please enter ' + remainingChars + ' or more characters'; 4915 4916 return message; 4917 }, 4918 loadingMore: function () { 4919 return 'Loading more results…'; 4920 }, 4921 maximumSelected: function (args) { 4922 var message = 'You can only select ' + args.maximum + ' item'; 4923 4924 if (args.maximum != 1) { 4925 message += 's'; 4926 } 4927 4928 return message; 4929 }, 4930 noResults: function () { 4931 return 'No results found'; 4932 }, 4933 searching: function () { 4934 return 'Searching…'; 4935 }, 4936 removeAllItems: function () { 4937 return 'Remove all items'; 4938 }, 4939 removeItem: function () { 4940 return 'Remove item'; 4941 }, 4942 search: function () { 4943 return 'Search'; 4944 } 4945 }; 4946 }); 4947 4948 S2.define('select2/defaults', [ 4949 'jquery', 4950 4951 './results', 4952 4953 './selection/single', 4954 './selection/multiple', 4955 './selection/placeholder', 4956 './selection/allowClear', 4957 './selection/search', 4958 './selection/selectionCss', 4959 './selection/eventRelay', 4960 4961 './utils', 4962 './translation', 4963 './diacritics', 4964 4965 './data/select', 4966 './data/array', 4967 './data/ajax', 4968 './data/tags', 4969 './data/tokenizer', 4970 './data/minimumInputLength', 4971 './data/maximumInputLength', 4972 './data/maximumSelectionLength', 4973 4974 './dropdown', 4975 './dropdown/search', 4976 './dropdown/hidePlaceholder', 4977 './dropdown/infiniteScroll', 4978 './dropdown/attachBody', 4979 './dropdown/minimumResultsForSearch', 4980 './dropdown/selectOnClose', 4981 './dropdown/closeOnSelect', 4982 './dropdown/dropdownCss', 4983 './dropdown/tagsSearchHighlight', 4984 4985 './i18n/en' 4986 ], function ($, 4987 4988 ResultsList, 4989 4990 SingleSelection, MultipleSelection, Placeholder, AllowClear, 4991 SelectionSearch, SelectionCSS, EventRelay, 4992 4993 Utils, Translation, DIACRITICS, 4994 4995 SelectData, ArrayData, AjaxData, Tags, Tokenizer, 4996 MinimumInputLength, MaximumInputLength, MaximumSelectionLength, 4997 4998 Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll, 4999 AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect, 5000 DropdownCSS, TagsSearchHighlight, 5001 5002 EnglishTranslation) { 5003 function Defaults() { 5004 this.reset(); 5005 } 5006 5007 Defaults.prototype.apply = function (options) { 5008 options = $.extend(true, {}, this.defaults, options); 5009 5010 if (options.dataAdapter == null) { 5011 if (options.ajax != null) { 5012 options.dataAdapter = AjaxData; 5013 } else if (options.data != null) { 5014 options.dataAdapter = ArrayData; 5015 } else { 5016 options.dataAdapter = SelectData; 5017 } 5018 5019 if (options.minimumInputLength > 0) { 5020 options.dataAdapter = Utils.Decorate( 5021 options.dataAdapter, 5022 MinimumInputLength 5023 ); 5024 } 5025 5026 if (options.maximumInputLength > 0) { 5027 options.dataAdapter = Utils.Decorate( 5028 options.dataAdapter, 5029 MaximumInputLength 5030 ); 5031 } 5032 5033 if (options.maximumSelectionLength > 0) { 5034 options.dataAdapter = Utils.Decorate( 5035 options.dataAdapter, 5036 MaximumSelectionLength 5037 ); 5038 } 5039 5040 if (options.tags) { 5041 options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags); 5042 } 5043 5044 if (options.tokenSeparators != null || options.tokenizer != null) { 5045 options.dataAdapter = Utils.Decorate( 5046 options.dataAdapter, 5047 Tokenizer 5048 ); 5049 } 5050 } 5051 5052 if (options.resultsAdapter == null) { 5053 options.resultsAdapter = ResultsList; 5054 5055 if (options.ajax != null) { 5056 options.resultsAdapter = Utils.Decorate( 5057 options.resultsAdapter, 5058 InfiniteScroll 5059 ); 5060 } 5061 5062 if (options.placeholder != null) { 5063 options.resultsAdapter = Utils.Decorate( 5064 options.resultsAdapter, 5065 HidePlaceholder 5066 ); 5067 } 5068 5069 if (options.selectOnClose) { 5070 options.resultsAdapter = Utils.Decorate( 5071 options.resultsAdapter, 5072 SelectOnClose 5073 ); 5074 } 5075 5076 if (options.tags) { 5077 options.resultsAdapter = Utils.Decorate( 5078 options.resultsAdapter, 5079 TagsSearchHighlight 5080 ); 5081 } 5082 } 5083 5084 if (options.dropdownAdapter == null) { 5085 if (options.multiple) { 5086 options.dropdownAdapter = Dropdown; 5087 } else { 5088 var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch); 5089 5090 options.dropdownAdapter = SearchableDropdown; 5091 } 5092 5093 if (options.minimumResultsForSearch !== 0) { 5094 options.dropdownAdapter = Utils.Decorate( 5095 options.dropdownAdapter, 5096 MinimumResultsForSearch 5097 ); 5098 } 5099 5100 if (options.closeOnSelect) { 5101 options.dropdownAdapter = Utils.Decorate( 5102 options.dropdownAdapter, 5103 CloseOnSelect 5104 ); 5105 } 5106 5107 if (options.dropdownCssClass != null) { 5108 options.dropdownAdapter = Utils.Decorate( 5109 options.dropdownAdapter, 5110 DropdownCSS 5111 ); 5112 } 5113 5114 options.dropdownAdapter = Utils.Decorate( 5115 options.dropdownAdapter, 5116 AttachBody 5117 ); 5118 } 5119 5120 if (options.selectionAdapter == null) { 5121 if (options.multiple) { 5122 options.selectionAdapter = MultipleSelection; 5123 } else { 5124 options.selectionAdapter = SingleSelection; 5125 } 5126 5127 // Add the placeholder mixin if a placeholder was specified 5128 if (options.placeholder != null) { 5129 options.selectionAdapter = Utils.Decorate( 5130 options.selectionAdapter, 5131 Placeholder 5132 ); 5133 } 5134 5135 if (options.allowClear) { 5136 options.selectionAdapter = Utils.Decorate( 5137 options.selectionAdapter, 5138 AllowClear 5139 ); 5140 } 5141 5142 if (options.multiple) { 5143 options.selectionAdapter = Utils.Decorate( 5144 options.selectionAdapter, 5145 SelectionSearch 5146 ); 5147 } 5148 5149 if (options.selectionCssClass != null) { 5150 options.selectionAdapter = Utils.Decorate( 5151 options.selectionAdapter, 5152 SelectionCSS 5153 ); 5154 } 5155 5156 options.selectionAdapter = Utils.Decorate( 5157 options.selectionAdapter, 5158 EventRelay 5159 ); 5160 } 5161 5162 // If the defaults were not previously applied from an element, it is 5163 // possible for the language option to have not been resolved 5164 options.language = this._resolveLanguage(options.language); 5165 5166 // Always fall back to English since it will always be complete 5167 options.language.push('en'); 5168 5169 var uniqueLanguages = []; 5170 5171 for (var l = 0; l < options.language.length; l++) { 5172 var language = options.language[l]; 5173 5174 if (uniqueLanguages.indexOf(language) === -1) { 5175 uniqueLanguages.push(language); 5176 } 5177 } 5178 5179 options.language = uniqueLanguages; 5180 5181 options.translations = this._processTranslations( 5182 options.language, 5183 options.debug 5184 ); 5185 5186 return options; 5187 }; 5188 5189 Defaults.prototype.reset = function () { 5190 function stripDiacritics(text) { 5191 // Used 'uni range + named function' from http://jsperf.com/diacritics/18 5192 function match(a) { 5193 return DIACRITICS[a] || a; 5194 } 5195 5196 return text.replace(/[^\u0000-\u007E]/g, match); 5197 } 5198 5199 function matcher(params, data) { 5200 // Always return the object if there is nothing to compare 5201 if (params.term == null || params.term.trim() === '') { 5202 return data; 5203 } 5204 5205 // Do a recursive check for options with children 5206 if (data.children && data.children.length > 0) { 5207 // Clone the data object if there are children 5208 // This is required as we modify the object to remove any non-matches 5209 var match = $.extend(true, {}, data); 5210 5211 // Check each child of the option 5212 for (var c = data.children.length - 1; c >= 0; c--) { 5213 var child = data.children[c]; 5214 5215 var matches = matcher(params, child); 5216 5217 // If there wasn't a match, remove the object in the array 5218 if (matches == null) { 5219 match.children.splice(c, 1); 5220 } 5221 } 5222 5223 // If any children matched, return the new object 5224 if (match.children.length > 0) { 5225 return match; 5226 } 5227 5228 // If there were no matching children, check just the plain object 5229 return matcher(params, match); 5230 } 5231 5232 var original = stripDiacritics(data.text).toUpperCase(); 5233 var term = stripDiacritics(params.term).toUpperCase(); 5234 5235 // Check if the text contains the term 5236 if (original.indexOf(term) > -1) { 5237 return data; 5238 } 5239 5240 // If it doesn't contain the term, don't return anything 5241 return null; 5242 } 5243 5244 this.defaults = { 5245 amdLanguageBase: './i18n/', 5246 autocomplete: 'off', 5247 closeOnSelect: true, 5248 debug: false, 5249 dropdownAutoWidth: false, 5250 escapeMarkup: Utils.escapeMarkup, 5251 language: {}, 5252 matcher: matcher, 5253 minimumInputLength: 0, 5254 maximumInputLength: 0, 5255 maximumSelectionLength: 0, 5256 minimumResultsForSearch: 0, 5257 selectOnClose: false, 5258 scrollAfterSelect: false, 5259 sorter: function (data) { 5260 return data; 5261 }, 5262 templateResult: function (result) { 5263 return result.text; 5264 }, 5265 templateSelection: function (selection) { 5266 return selection.text; 5267 }, 5268 theme: 'default', 5269 width: 'resolve' 5270 }; 5271 }; 5272 5273 Defaults.prototype.applyFromElement = function (options, $element) { 5274 var optionLanguage = options.language; 5275 var defaultLanguage = this.defaults.language; 5276 var elementLanguage = $element.prop('lang'); 5277 var parentLanguage = $element.closest('[lang]').prop('lang'); 5278 5279 var languages = Array.prototype.concat.call( 5280 this._resolveLanguage(elementLanguage), 5281 this._resolveLanguage(optionLanguage), 5282 this._resolveLanguage(defaultLanguage), 5283 this._resolveLanguage(parentLanguage) 5284 ); 5285 5286 options.language = languages; 5287 5288 return options; 5289 }; 5290 5291 Defaults.prototype._resolveLanguage = function (language) { 5292 if (!language) { 5293 return []; 5294 } 5295 5296 if ($.isEmptyObject(language)) { 5297 return []; 5298 } 5299 5300 if ($.isPlainObject(language)) { 5301 return [language]; 5302 } 5303 5304 var languages; 5305 5306 if (!Array.isArray(language)) { 5307 languages = [language]; 5308 } else { 5309 languages = language; 5310 } 5311 5312 var resolvedLanguages = []; 5313 5314 for (var l = 0; l < languages.length; l++) { 5315 resolvedLanguages.push(languages[l]); 5316 5317 if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) { 5318 // Extract the region information if it is included 5319 var languageParts = languages[l].split('-'); 5320 var baseLanguage = languageParts[0]; 5321 5322 resolvedLanguages.push(baseLanguage); 5323 } 5324 } 5325 5326 return resolvedLanguages; 5327 }; 5328 5329 Defaults.prototype._processTranslations = function (languages, debug) { 5330 var translations = new Translation(); 5331 5332 for (var l = 0; l < languages.length; l++) { 5333 var languageData = new Translation(); 5334 5335 var language = languages[l]; 5336 5337 if (typeof language === 'string') { 5338 try { 5339 // Try to load it with the original name 5340 languageData = Translation.loadPath(language); 5341 } catch (e) { 5342 try { 5343 // If we couldn't load it, check if it wasn't the full path 5344 language = this.defaults.amdLanguageBase + language; 5345 languageData = Translation.loadPath(language); 5346 } catch (ex) { 5347 // The translation could not be loaded at all. Sometimes this is 5348 // because of a configuration problem, other times this can be 5349 // because of how Select2 helps load all possible translation files 5350 if (debug && window.console && console.warn) { 5351 console.warn( 5352 'Select2: The language file for "' + language + '" could ' + 5353 'not be automatically loaded. A fallback will be used instead.' 5354 ); 5355 } 5356 } 5357 } 5358 } else if ($.isPlainObject(language)) { 5359 languageData = new Translation(language); 5360 } else { 5361 languageData = language; 5362 } 5363 5364 translations.extend(languageData); 5365 } 5366 5367 return translations; 5368 }; 5369 5370 Defaults.prototype.set = function (key, value) { 5371 var camelKey = $.camelCase(key); 5372 5373 var data = {}; 5374 data[camelKey] = value; 5375 5376 var convertedData = Utils._convertData(data); 5377 5378 $.extend(true, this.defaults, convertedData); 5379 }; 5380 5381 var defaults = new Defaults(); 5382 5383 return defaults; 5384 }); 5385 5386 S2.define('select2/options', [ 5387 'jquery', 5388 './defaults', 5389 './utils' 5390 ], function ($, Defaults, Utils) { 5391 function Options(options, $element) { 5392 this.options = options; 5393 5394 if ($element != null) { 5395 this.fromElement($element); 5396 } 5397 5398 if ($element != null) { 5399 this.options = Defaults.applyFromElement(this.options, $element); 5400 } 5401 5402 this.options = Defaults.apply(this.options); 5403 } 5404 5405 Options.prototype.fromElement = function ($e) { 5406 var excludedData = ['select2']; 5407 5408 if (this.options.multiple == null) { 5409 this.options.multiple = $e.prop('multiple'); 5410 } 5411 5412 if (this.options.disabled == null) { 5413 this.options.disabled = $e.prop('disabled'); 5414 } 5415 5416 if (this.options.autocomplete == null && $e.prop('autocomplete')) { 5417 this.options.autocomplete = $e.prop('autocomplete'); 5418 } 5419 5420 if (this.options.dir == null) { 5421 if ($e.prop('dir')) { 5422 this.options.dir = $e.prop('dir'); 5423 } else if ($e.closest('[dir]').prop('dir')) { 5424 this.options.dir = $e.closest('[dir]').prop('dir'); 5425 } else { 5426 this.options.dir = 'ltr'; 5427 } 5428 } 5429 5430 $e.prop('disabled', this.options.disabled); 5431 $e.prop('multiple', this.options.multiple); 5432 5433 if (Utils.GetData($e[0], 'select2Tags')) { 5434 if (this.options.debug && window.console && console.warn) { 5435 console.warn( 5436 'Select2: The `data-select2-tags` attribute has been changed to ' + 5437 'use the `data-data` and `data-tags="true"` attributes and will be ' + 5438 'removed in future versions of Select2.' 5439 ); 5440 } 5441 5442 Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags')); 5443 Utils.StoreData($e[0], 'tags', true); 5444 } 5445 5446 if (Utils.GetData($e[0], 'ajaxUrl')) { 5447 if (this.options.debug && window.console && console.warn) { 5448 console.warn( 5449 'Select2: The `data-ajax-url` attribute has been changed to ' + 5450 '`data-ajax--url` and support for the old attribute will be removed' + 5451 ' in future versions of Select2.' 5452 ); 5453 } 5454 5455 $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl')); 5456 Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl')); 5457 } 5458 5459 var dataset = {}; 5460 5461 function upperCaseLetter(_, letter) { 5462 return letter.toUpperCase(); 5463 } 5464 5465 // Pre-load all of the attributes which are prefixed with `data-` 5466 for (var attr = 0; attr < $e[0].attributes.length; attr++) { 5467 var attributeName = $e[0].attributes[attr].name; 5468 var prefix = 'data-'; 5469 5470 if (attributeName.substr(0, prefix.length) == prefix) { 5471 // Get the contents of the attribute after `data-` 5472 var dataName = attributeName.substring(prefix.length); 5473 5474 // Get the data contents from the consistent source 5475 // This is more than likely the jQuery data helper 5476 var dataValue = Utils.GetData($e[0], dataName); 5477 5478 // camelCase the attribute name to match the spec 5479 var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter); 5480 5481 // Store the data attribute contents into the dataset since 5482 dataset[camelDataName] = dataValue; 5483 } 5484 } 5485 5486 // Prefer the element's `dataset` attribute if it exists 5487 // jQuery 1.x does not correctly handle data attributes with multiple dashes 5488 if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) { 5489 dataset = $.extend(true, {}, $e[0].dataset, dataset); 5490 } 5491 5492 // Prefer our internal data cache if it exists 5493 var data = $.extend(true, {}, Utils.GetData($e[0]), dataset); 5494 5495 data = Utils._convertData(data); 5496 5497 for (var key in data) { 5498 if (excludedData.indexOf(key) > -1) { 5499 continue; 5500 } 5501 5502 if ($.isPlainObject(this.options[key])) { 5503 $.extend(this.options[key], data[key]); 5504 } else { 5505 this.options[key] = data[key]; 5506 } 5507 } 5508 5509 return this; 5510 }; 5511 5512 Options.prototype.get = function (key) { 5513 return this.options[key]; 5514 }; 5515 5516 Options.prototype.set = function (key, val) { 5517 this.options[key] = val; 5518 }; 5519 5520 return Options; 5521 }); 5522 5523 S2.define('select2/core', [ 5524 'jquery', 5525 './options', 5526 './utils', 5527 './keys' 5528 ], function ($, Options, Utils, KEYS) { 5529 var Select2 = function ($element, options) { 5530 if (Utils.GetData($element[0], 'select2') != null) { 5531 Utils.GetData($element[0], 'select2').destroy(); 5532 } 5533 5534 this.$element = $element; 5535 5536 this.id = this._generateId($element); 5537 5538 options = options || {}; 5539 5540 this.options = new Options(options, $element); 5541 5542 Select2.__super__.constructor.call(this); 5543 5544 // Set up the tabindex 5545 5546 var tabindex = $element.attr('tabindex') || 0; 5547 Utils.StoreData($element[0], 'old-tabindex', tabindex); 5548 $element.attr('tabindex', '-1'); 5549 5550 // Set up containers and adapters 5551 5552 var DataAdapter = this.options.get('dataAdapter'); 5553 this.dataAdapter = new DataAdapter($element, this.options); 5554 5555 var $container = this.render(); 5556 5557 this._placeContainer($container); 5558 5559 var SelectionAdapter = this.options.get('selectionAdapter'); 5560 this.selection = new SelectionAdapter($element, this.options); 5561 this.$selection = this.selection.render(); 5562 5563 this.selection.position(this.$selection, $container); 5564 5565 var DropdownAdapter = this.options.get('dropdownAdapter'); 5566 this.dropdown = new DropdownAdapter($element, this.options); 5567 this.$dropdown = this.dropdown.render(); 5568 5569 this.dropdown.position(this.$dropdown, $container); 5570 5571 var ResultsAdapter = this.options.get('resultsAdapter'); 5572 this.results = new ResultsAdapter($element, this.options, this.dataAdapter); 5573 this.$results = this.results.render(); 5574 5575 this.results.position(this.$results, this.$dropdown); 5576 5577 // Bind events 5578 5579 var self = this; 5580 5581 // Bind the container to all of the adapters 5582 this._bindAdapters(); 5583 5584 // Register any DOM event handlers 5585 this._registerDomEvents(); 5586 5587 // Register any internal event handlers 5588 this._registerDataEvents(); 5589 this._registerSelectionEvents(); 5590 this._registerDropdownEvents(); 5591 this._registerResultsEvents(); 5592 this._registerEvents(); 5593 5594 // Set the initial state 5595 this.dataAdapter.current(function (initialData) { 5596 self.trigger('selection:update', { 5597 data: initialData 5598 }); 5599 }); 5600 5601 // Hide the original select 5602 $element[0].classList.add('select2-hidden-accessible'); 5603 $element.attr('aria-hidden', 'true'); 5604 5605 // Synchronize any monitored attributes 5606 this._syncAttributes(); 5607 5608 Utils.StoreData($element[0], 'select2', this); 5609 5610 // Ensure backwards compatibility with $element.data('select2'). 5611 $element.data('select2', this); 5612 }; 5613 5614 Utils.Extend(Select2, Utils.Observable); 5615 5616 Select2.prototype._generateId = function ($element) { 5617 var id = ''; 5618 5619 if ($element.attr('id') != null) { 5620 id = $element.attr('id'); 5621 } else if ($element.attr('name') != null) { 5622 id = $element.attr('name') + '-' + Utils.generateChars(2); 5623 } else { 5624 id = Utils.generateChars(4); 5625 } 5626 5627 id = id.replace(/(:|\.|\[|\]|,)/g, ''); 5628 id = 'select2-' + id; 5629 5630 return id; 5631 }; 5632 5633 Select2.prototype._placeContainer = function ($container) { 5634 $container.insertAfter(this.$element); 5635 5636 var width = this._resolveWidth(this.$element, this.options.get('width')); 5637 5638 if (width != null) { 5639 $container.css('width', width); 5640 } 5641 }; 5642 5643 Select2.prototype._resolveWidth = function ($element, method) { 5644 var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i; 5645 5646 if (method == 'resolve') { 5647 var styleWidth = this._resolveWidth($element, 'style'); 5648 5649 if (styleWidth != null) { 5650 return styleWidth; 5651 } 5652 5653 return this._resolveWidth($element, 'element'); 5654 } 5655 5656 if (method == 'element') { 5657 var elementWidth = $element.outerWidth(false); 5658 5659 if (elementWidth <= 0) { 5660 return 'auto'; 5661 } 5662 5663 return elementWidth + 'px'; 5664 } 5665 5666 if (method == 'style') { 5667 var style = $element.attr('style'); 5668 5669 if (typeof (style) !== 'string') { 5670 return null; 5671 } 5672 5673 var attrs = style.split(';'); 5674 5675 for (var i = 0, l = attrs.length; i < l; i = i + 1) { 5676 var attr = attrs[i].replace(/\s/g, ''); 5677 var matches = attr.match(WIDTH); 5678 5679 if (matches !== null && matches.length >= 1) { 5680 return matches[1]; 5681 } 5682 } 5683 5684 return null; 5685 } 5686 5687 if (method == 'computedstyle') { 5688 var computedStyle = window.getComputedStyle($element[0]); 5689 5690 return computedStyle.width; 5691 } 5692 5693 return method; 5694 }; 5695 5696 Select2.prototype._bindAdapters = function () { 5697 this.dataAdapter.bind(this, this.$container); 5698 this.selection.bind(this, this.$container); 5699 5700 this.dropdown.bind(this, this.$container); 5701 this.results.bind(this, this.$container); 5702 }; 5703 5704 Select2.prototype._registerDomEvents = function () { 5705 var self = this; 5706 5707 this.$element.on('change.select2', function () { 5708 self.dataAdapter.current(function (data) { 5709 self.trigger('selection:update', { 5710 data: data 5711 }); 5712 }); 5713 }); 5714 5715 this.$element.on('focus.select2', function (evt) { 5716 self.trigger('focus', evt); 5717 }); 5718 5719 this._syncA = Utils.bind(this._syncAttributes, this); 5720 this._syncS = Utils.bind(this._syncSubtree, this); 5721 5722 this._observer = new window.MutationObserver(function (mutations) { 5723 self._syncA(); 5724 self._syncS(mutations); 5725 }); 5726 this._observer.observe(this.$element[0], { 5727 attributes: true, 5728 childList: true, 5729 subtree: false 5730 }); 5731 }; 5732 5733 Select2.prototype._registerDataEvents = function () { 5734 var self = this; 5735 5736 this.dataAdapter.on('*', function (name, params) { 5737 self.trigger(name, params); 5738 }); 5739 }; 5740 5741 Select2.prototype._registerSelectionEvents = function () { 5742 var self = this; 5743 var nonRelayEvents = ['toggle', 'focus']; 5744 5745 this.selection.on('toggle', function () { 5746 self.toggleDropdown(); 5747 }); 5748 5749 this.selection.on('focus', function (params) { 5750 self.focus(params); 5751 }); 5752 5753 this.selection.on('*', function (name, params) { 5754 if (nonRelayEvents.indexOf(name) !== -1) { 5755 return; 5756 } 5757 5758 self.trigger(name, params); 5759 }); 5760 }; 5761 5762 Select2.prototype._registerDropdownEvents = function () { 5763 var self = this; 5764 5765 this.dropdown.on('*', function (name, params) { 5766 self.trigger(name, params); 5767 }); 5768 }; 5769 5770 Select2.prototype._registerResultsEvents = function () { 5771 var self = this; 5772 5773 this.results.on('*', function (name, params) { 5774 self.trigger(name, params); 5775 }); 5776 }; 5777 5778 Select2.prototype._registerEvents = function () { 5779 var self = this; 5780 5781 this.on('open', function () { 5782 self.$container[0].classList.add('select2-container--open'); 5783 }); 5784 5785 this.on('close', function () { 5786 self.$container[0].classList.remove('select2-container--open'); 5787 }); 5788 5789 this.on('enable', function () { 5790 self.$container[0].classList.remove('select2-container--disabled'); 5791 }); 5792 5793 this.on('disable', function () { 5794 self.$container[0].classList.add('select2-container--disabled'); 5795 }); 5796 5797 this.on('blur', function () { 5798 self.$container[0].classList.remove('select2-container--focus'); 5799 }); 5800 5801 this.on('query', function (params) { 5802 if (!self.isOpen()) { 5803 self.trigger('open', {}); 5804 } 5805 5806 this.dataAdapter.query(params, function (data) { 5807 self.trigger('results:all', { 5808 data: data, 5809 query: params 5810 }); 5811 }); 5812 }); 5813 5814 this.on('query:append', function (params) { 5815 this.dataAdapter.query(params, function (data) { 5816 self.trigger('results:append', { 5817 data: data, 5818 query: params 5819 }); 5820 }); 5821 }); 5822 5823 this.on('keypress', function (evt) { 5824 var key = evt.which; 5825 5826 if (self.isOpen()) { 5827 if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) { 5828 self.close(evt); 5829 5830 evt.preventDefault(); 5831 } else if (key === KEYS.ENTER || key === KEYS.TAB) { 5832 self.trigger('results:select', {}); 5833 5834 evt.preventDefault(); 5835 } else if ((key === KEYS.SPACE && evt.ctrlKey)) { 5836 self.trigger('results:toggle', {}); 5837 5838 evt.preventDefault(); 5839 } else if (key === KEYS.UP) { 5840 self.trigger('results:previous', {}); 5841 5842 evt.preventDefault(); 5843 } else if (key === KEYS.DOWN) { 5844 self.trigger('results:next', {}); 5845 5846 evt.preventDefault(); 5847 } 5848 } else { 5849 if (key === KEYS.ENTER || key === KEYS.SPACE || 5850 (key === KEYS.DOWN && evt.altKey)) { 5851 self.open(); 5852 5853 evt.preventDefault(); 5854 } 5855 } 5856 }); 5857 }; 5858 5859 Select2.prototype._syncAttributes = function () { 5860 this.options.set('disabled', this.$element.prop('disabled')); 5861 5862 if (this.isDisabled()) { 5863 if (this.isOpen()) { 5864 this.close(); 5865 } 5866 5867 this.trigger('disable', {}); 5868 } else { 5869 this.trigger('enable', {}); 5870 } 5871 }; 5872 5873 Select2.prototype._isChangeMutation = function (mutations) { 5874 var self = this; 5875 5876 if (mutations.addedNodes && mutations.addedNodes.length > 0) { 5877 for (var n = 0; n < mutations.addedNodes.length; n++) { 5878 var node = mutations.addedNodes[n]; 5879 5880 if (node.selected) { 5881 return true; 5882 } 5883 } 5884 } else if (mutations.removedNodes && mutations.removedNodes.length > 0) { 5885 return true; 5886 } else if (Array.isArray(mutations)) { 5887 return mutations.some(function (mutation) { 5888 return self._isChangeMutation(mutation); 5889 }); 5890 } 5891 5892 return false; 5893 }; 5894 5895 Select2.prototype._syncSubtree = function (mutations) { 5896 var changed = this._isChangeMutation(mutations); 5897 var self = this; 5898 5899 // Only re-pull the data if we think there is a change 5900 if (changed) { 5901 this.dataAdapter.current(function (currentData) { 5902 self.trigger('selection:update', { 5903 data: currentData 5904 }); 5905 }); 5906 } 5907 }; 5908 5909 /** 5910 * Override the trigger method to automatically trigger pre-events when 5911 * there are events that can be prevented. 5912 */ 5913 Select2.prototype.trigger = function (name, args) { 5914 var actualTrigger = Select2.__super__.trigger; 5915 var preTriggerMap = { 5916 'open': 'opening', 5917 'close': 'closing', 5918 'select': 'selecting', 5919 'unselect': 'unselecting', 5920 'clear': 'clearing' 5921 }; 5922 5923 if (args === undefined) { 5924 args = {}; 5925 } 5926 5927 if (name in preTriggerMap) { 5928 var preTriggerName = preTriggerMap[name]; 5929 var preTriggerArgs = { 5930 prevented: false, 5931 name: name, 5932 args: args 5933 }; 5934 5935 actualTrigger.call(this, preTriggerName, preTriggerArgs); 5936 5937 if (preTriggerArgs.prevented) { 5938 args.prevented = true; 5939 5940 return; 5941 } 5942 } 5943 5944 actualTrigger.call(this, name, args); 5945 }; 5946 5947 Select2.prototype.toggleDropdown = function () { 5948 if (this.isDisabled()) { 5949 return; 5950 } 5951 5952 if (this.isOpen()) { 5953 this.close(); 5954 } else { 5955 this.open(); 5956 } 5957 }; 5958 5959 Select2.prototype.open = function () { 5960 if (this.isOpen()) { 5961 return; 5962 } 5963 5964 if (this.isDisabled()) { 5965 return; 5966 } 5967 5968 this.trigger('query', {}); 5969 }; 5970 5971 Select2.prototype.close = function (evt) { 5972 if (!this.isOpen()) { 5973 return; 5974 } 5975 5976 this.trigger('close', { originalEvent: evt }); 5977 }; 5978 5979 /** 5980 * Helper method to abstract the "enabled" (not "disabled") state of this 5981 * object. 5982 * 5983 * @return {true} if the instance is not disabled. 5984 * @return {false} if the instance is disabled. 5985 */ 5986 Select2.prototype.isEnabled = function () { 5987 return !this.isDisabled(); 5988 }; 5989 5990 /** 5991 * Helper method to abstract the "disabled" state of this object. 5992 * 5993 * @return {true} if the disabled option is true. 5994 * @return {false} if the disabled option is false. 5995 */ 5996 Select2.prototype.isDisabled = function () { 5997 return this.options.get('disabled'); 5998 }; 5999 6000 Select2.prototype.isOpen = function () { 6001 return this.$container[0].classList.contains('select2-container--open'); 6002 }; 6003 6004 Select2.prototype.hasFocus = function () { 6005 return this.$container[0].classList.contains('select2-container--focus'); 6006 }; 6007 6008 Select2.prototype.focus = function (data) { 6009 // No need to re-trigger focus events if we are already focused 6010 if (this.hasFocus()) { 6011 return; 6012 } 6013 6014 this.$container[0].classList.add('select2-container--focus'); 6015 this.trigger('focus', {}); 6016 }; 6017 6018 Select2.prototype.enable = function (args) { 6019 if (this.options.get('debug') && window.console && console.warn) { 6020 console.warn( 6021 'Select2: The `select2("enable")` method has been deprecated and will' + 6022 ' be removed in later Select2 versions. Use $element.prop("disabled")' + 6023 ' instead.' 6024 ); 6025 } 6026 6027 if (args == null || args.length === 0) { 6028 args = [true]; 6029 } 6030 6031 var disabled = !args[0]; 6032 6033 this.$element.prop('disabled', disabled); 6034 }; 6035 6036 Select2.prototype.data = function () { 6037 if (this.options.get('debug') && 6038 arguments.length > 0 && window.console && console.warn) { 6039 console.warn( 6040 'Select2: Data can no longer be set using `select2("data")`. You ' + 6041 'should consider setting the value instead using `$element.val()`.' 6042 ); 6043 } 6044 6045 var data = []; 6046 6047 this.dataAdapter.current(function (currentData) { 6048 data = currentData; 6049 }); 6050 6051 return data; 6052 }; 6053 6054 Select2.prototype.val = function (args) { 6055 if (this.options.get('debug') && window.console && console.warn) { 6056 console.warn( 6057 'Select2: The `select2("val")` method has been deprecated and will be' + 6058 ' removed in later Select2 versions. Use $element.val() instead.' 6059 ); 6060 } 6061 6062 if (args == null || args.length === 0) { 6063 return this.$element.val(); 6064 } 6065 6066 var newVal = args[0]; 6067 6068 if (Array.isArray(newVal)) { 6069 newVal = newVal.map(function (obj) { 6070 return obj.toString(); 6071 }); 6072 } 6073 6074 this.$element.val(newVal).trigger('input').trigger('change'); 6075 }; 6076 6077 Select2.prototype.destroy = function () { 6078 Utils.RemoveData(this.$container[0]); 6079 this.$container.remove(); 6080 6081 this._observer.disconnect(); 6082 this._observer = null; 6083 6084 this._syncA = null; 6085 this._syncS = null; 6086 6087 this.$element.off('.select2'); 6088 this.$element.attr('tabindex', 6089 Utils.GetData(this.$element[0], 'old-tabindex')); 6090 6091 this.$element[0].classList.remove('select2-hidden-accessible'); 6092 this.$element.attr('aria-hidden', 'false'); 6093 Utils.RemoveData(this.$element[0]); 6094 this.$element.removeData('select2'); 6095 6096 this.dataAdapter.destroy(); 6097 this.selection.destroy(); 6098 this.dropdown.destroy(); 6099 this.results.destroy(); 6100 6101 this.dataAdapter = null; 6102 this.selection = null; 6103 this.dropdown = null; 6104 this.results = null; 6105 }; 6106 6107 Select2.prototype.render = function () { 6108 var $container = $( 6109 '<span class="select2 select2-container">' + 6110 '<span class="selection"></span>' + 6111 '<span class="dropdown-wrapper" aria-hidden="true"></span>' + 6112 '</span>' 6113 ); 6114 6115 $container.attr('dir', this.options.get('dir')); 6116 6117 this.$container = $container; 6118 6119 this.$container[0].classList 6120 .add('select2-container--' + this.options.get('theme')); 6121 6122 Utils.StoreData($container[0], 'element', this.$element); 6123 6124 return $container; 6125 }; 6126 6127 return Select2; 6128 }); 6129 6130 S2.define('select2/dropdown/attachContainer', [ 6131 6132 ], function () { 6133 function AttachContainer(decorated, $element, options) { 6134 decorated.call(this, $element, options); 6135 } 6136 6137 AttachContainer.prototype.position = 6138 function (decorated, $dropdown, $container) { 6139 var $dropdownContainer = $container.find('.dropdown-wrapper'); 6140 $dropdownContainer.append($dropdown); 6141 6142 $dropdown[0].classList.add('select2-dropdown--below'); 6143 $container[0].classList.add('select2-container--below'); 6144 }; 6145 6146 return AttachContainer; 6147 });
vendor: 9,124 bytes, lines 6148-6425
6148 6149 S2.define('select2/dropdown/stopPropagation', [ 6150 6151 ], function () { 6152 function StopPropagation() { } 6153 6154 StopPropagation.prototype.bind = function (decorated, container, $container) { 6155 decorated.call(this, container, $container); 6156 6157 var stoppedEvents = [ 6158 'blur', 6159 'change', 6160 'click', 6161 'dblclick', 6162 'focus', 6163 'focusin', 6164 'focusout', 6165 'input', 6166 'keydown', 6167 'keyup', 6168 'keypress', 6169 'mousedown', 6170 'mouseenter', 6171 'mouseleave', 6172 'mousemove', 6173 'mouseover', 6174 'mouseup', 6175 'search', 6176 'touchend', 6177 'touchstart' 6178 ]; 6179 6180 this.$dropdown.on(stoppedEvents.join(' '), function (evt) { 6181 evt.stopPropagation(); 6182 }); 6183 }; 6184 6185 return StopPropagation; 6186 }); 6187 6188 S2.define('select2/selection/stopPropagation', [ 6189 6190 ], function () { 6191 function StopPropagation() { } 6192 6193 StopPropagation.prototype.bind = function (decorated, container, $container) { 6194 decorated.call(this, container, $container); 6195 6196 var stoppedEvents = [ 6197 'blur', 6198 'change', 6199 'click', 6200 'dblclick', 6201 'focus', 6202 'focusin', 6203 'focusout', 6204 'input', 6205 'keydown', 6206 'keyup', 6207 'keypress', 6208 'mousedown', 6209 'mouseenter', 6210 'mouseleave', 6211 'mousemove', 6212 'mouseover', 6213 'mouseup', 6214 'search', 6215 'touchend', 6216 'touchstart' 6217 ]; 6218 6219 this.$selection.on(stoppedEvents.join(' '), function (evt) { 6220 evt.stopPropagation(); 6221 }); 6222 }; 6223 6224 return StopPropagation; 6225 }); 6226 6227 /*! 6228 * jQuery Mousewheel 3.1.13 6229 * 6230 * Copyright jQuery Foundation and other contributors 6231 * Released under the MIT license 6232 * http://jquery.org/license 6233 */ 6234 6235 (function (factory) { 6236 if (typeof S2.define === 'function' && S2.define.amd) { 6237 // AMD. Register as an anonymous module. 6238 S2.define('jquery-mousewheel', ['jquery'], factory); 6239 } else if (typeof exports === 'object') { 6240 // Node/CommonJS style for Browserify 6241 module.exports = factory; 6242 } else { 6243 // Browser globals 6244 factory(jQuery); 6245 } 6246 }(function ($) { 6247 6248 var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'], 6249 toBind = ('onwheel' in document || document.documentMode >= 9) ? 6250 ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'], 6251 slice = Array.prototype.slice, 6252 nullLowestDeltaTimeout, lowestDelta; 6253 6254 if ($.event.fixHooks) { 6255 for (var i = toFix.length; i;) { 6256 $.event.fixHooks[toFix[--i]] = $.event.mouseHooks; 6257 } 6258 } 6259 6260 var special = $.event.special.mousewheel = { 6261 version: '3.1.12', 6262 6263 setup: function () { 6264 if (this.addEventListener) { 6265 for (var i = toBind.length; i;) { 6266 this.addEventListener(toBind[--i], handler, false); 6267 } 6268 } else { 6269 this.onmousewheel = handler; 6270 } 6271 // Store the line height and page height for this particular element 6272 $.data(this, 'mousewheel-line-height', special.getLineHeight(this)); 6273 $.data(this, 'mousewheel-page-height', special.getPageHeight(this)); 6274 }, 6275 6276 teardown: function () { 6277 if (this.removeEventListener) { 6278 for (var i = toBind.length; i;) { 6279 this.removeEventListener(toBind[--i], handler, false); 6280 } 6281 } else { 6282 this.onmousewheel = null; 6283 } 6284 // Clean up the data we added to the element 6285 $.removeData(this, 'mousewheel-line-height'); 6286 $.removeData(this, 'mousewheel-page-height'); 6287 }, 6288 6289 getLineHeight: function (elem) { 6290 var $elem = $(elem), 6291 $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent'](); 6292 if (!$parent.length) { 6293 $parent = $('body'); 6294 } 6295 return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16; 6296 }, 6297 6298 getPageHeight: function (elem) { 6299 return $(elem).height(); 6300 }, 6301 6302 settings: { 6303 adjustOldDeltas: true, // see shouldAdjustOldDeltas() below 6304 normalizeOffset: true // calls getBoundingClientRect for each event 6305 } 6306 }; 6307 6308 $.fn.extend({ 6309 mousewheel: function (fn) { 6310 return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel'); 6311 }, 6312 6313 unmousewheel: function (fn) { 6314 return this.unbind('mousewheel', fn); 6315 } 6316 }); 6317 6318 6319 function handler(event) { 6320 var orgEvent = event || window.event, 6321 args = slice.call(arguments, 1), 6322 delta = 0, 6323 deltaX = 0, 6324 deltaY = 0, 6325 absDelta = 0, 6326 offsetX = 0, 6327 offsetY = 0; 6328 event = $.event.fix(orgEvent); 6329 event.type = 'mousewheel'; 6330 6331 // Old school scrollwheel delta 6332 if ('detail' in orgEvent) { deltaY = orgEvent.detail * -1; } 6333 if ('wheelDelta' in orgEvent) { deltaY = orgEvent.wheelDelta; } 6334 if ('wheelDeltaY' in orgEvent) { deltaY = orgEvent.wheelDeltaY; } 6335 if ('wheelDeltaX' in orgEvent) { deltaX = orgEvent.wheelDeltaX * -1; } 6336 6337 // Firefox < 17 horizontal scrolling related to DOMMouseScroll event 6338 if ('axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) { 6339 deltaX = deltaY * -1; 6340 deltaY = 0; 6341 } 6342 6343 // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy 6344 delta = deltaY === 0 ? deltaX : deltaY; 6345 6346 // New school wheel delta (wheel event) 6347 if ('deltaY' in orgEvent) { 6348 deltaY = orgEvent.deltaY * -1; 6349 delta = deltaY; 6350 } 6351 if ('deltaX' in orgEvent) { 6352 deltaX = orgEvent.deltaX; 6353 if (deltaY === 0) { delta = deltaX * -1; } 6354 } 6355 6356 // No change actually happened, no reason to go any further 6357 if (deltaY === 0 && deltaX === 0) { return; } 6358 6359 // Need to convert lines and pages to pixels if we aren't already in pixels 6360 // There are three delta modes: 6361 // * deltaMode 0 is by pixels, nothing to do 6362 // * deltaMode 1 is by lines 6363 // * deltaMode 2 is by pages 6364 if (orgEvent.deltaMode === 1) { 6365 var lineHeight = $.data(this, 'mousewheel-line-height'); 6366 delta *= lineHeight; 6367 deltaY *= lineHeight; 6368 deltaX *= lineHeight; 6369 } else if (orgEvent.deltaMode === 2) { 6370 var pageHeight = $.data(this, 'mousewheel-page-height'); 6371 delta *= pageHeight; 6372 deltaY *= pageHeight; 6373 deltaX *= pageHeight; 6374 } 6375 6376 // Store lowest absolute delta to normalize the delta values 6377 absDelta = Math.max(Math.abs(deltaY), Math.abs(deltaX)); 6378 6379 if (!lowestDelta || absDelta < lowestDelta) { 6380 lowestDelta = absDelta; 6381 6382 // Adjust older deltas if necessary 6383 if (shouldAdjustOldDeltas(orgEvent, absDelta)) { 6384 lowestDelta /= 40; 6385 } 6386 } 6387 6388 // Adjust older deltas if necessary 6389 if (shouldAdjustOldDeltas(orgEvent, absDelta)) { 6390 // Divide all the things by 40! 6391 delta /= 40; 6392 deltaX /= 40; 6393 deltaY /= 40; 6394 } 6395 6396 // Get a whole, normalized value for the deltas 6397 delta = Math[delta >= 1 ? 'floor' : 'ceil'](delta / lowestDelta); 6398 deltaX = Math[deltaX >= 1 ? 'floor' : 'ceil'](deltaX / lowestDelta); 6399 deltaY = Math[deltaY >= 1 ? 'floor' : 'ceil'](deltaY / lowestDelta); 6400 6401 // Normalise offsetX and offsetY properties 6402 if (special.settings.normalizeOffset && this.getBoundingClientRect) { 6403 var boundingRect = this.getBoundingClientRect(); 6404 offsetX = event.clientX - boundingRect.left; 6405 offsetY = event.clientY - boundingRect.top; 6406 } 6407 6408 // Add information to the event object 6409 event.deltaX = deltaX; 6410 event.deltaY = deltaY; 6411 event.deltaFactor = lowestDelta; 6412 event.offsetX = offsetX; 6413 event.offsetY = offsetY; 6414 // Go ahead and set deltaMode to 0 since we converted to pixels 6415 // Although this is a little odd since we overwrite the deltaX/Y 6416 // properties with normalized deltas. 6417 event.deltaMode = 0; 6418 6419 // Add event and delta to the front of the arguments 6420 args.unshift(event, delta, deltaX, deltaY); 6421 6422 // Clearout lowestDelta after sometime to better 6423 // handle multiple device types that give different 6424 // a different lowestDelta 6425 // Ex: trackpad = 3 and mouse wheel = 120
vendor: 3,428 bytes, lines 6426-6526
6426 if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); } 6427 nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200); 6428 6429 return ($.event.dispatch || $.event.handle).apply(this, args); 6430 } 6431 6432 function nullLowestDelta() { 6433 lowestDelta = null; 6434 } 6435 6436 function shouldAdjustOldDeltas(orgEvent, absDelta) { 6437 // If this is an older event and the delta is divisable by 120, 6438 // then we are assuming that the browser is treating this as an 6439 // older mouse wheel event and that we should divide the deltas 6440 // by 40 to try and get a more usable deltaFactor. 6441 // Side note, this actually impacts the reported scroll distance 6442 // in older browsers and can cause scrolling to be slower than native. 6443 // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false. 6444 return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0; 6445 } 6446 6447 })); 6448 6449 S2.define('jquery.select2', [ 6450 'jquery', 6451 'jquery-mousewheel', 6452 6453 './select2/core', 6454 './select2/defaults', 6455 './select2/utils' 6456 ], function ($, _, Select2, Defaults, Utils) { 6457 if ($.fn.select2 == null) { 6458 // All methods that should return the element 6459 var thisMethods = ['open', 'close', 'destroy']; 6460 6461 $.fn.select2 = function (options) { 6462 options = options || {}; 6463 6464 if (typeof options === 'object') { 6465 this.each(function () { 6466 var instanceOptions = $.extend(true, {}, options); 6467 6468 var instance = new Select2($(this), instanceOptions); 6469 }); 6470 6471 return this; 6472 } else if (typeof options === 'string') { 6473 var ret; 6474 var args = Array.prototype.slice.call(arguments, 1); 6475 6476 this.each(function () { 6477 var instance = Utils.GetData(this, 'select2'); 6478 6479 if (instance == null && window.console && console.error) { 6480 console.error( 6481 'The select2(\'' + options + '\') method was called on an ' + 6482 'element that is not using Select2.' 6483 ); 6484 } 6485 6486 ret = instance[options].apply(instance, args); 6487 }); 6488 6489 // Check if we should be returning `this` 6490 if (thisMethods.indexOf(options) > -1) { 6491 return this; 6492 } 6493 6494 return ret; 6495 } else { 6496 throw new Error('Invalid arguments for Select2: ' + options); 6497 } 6498 }; 6499 } 6500 6501 if ($.fn.select2.defaults == null) { 6502 $.fn.select2.defaults = Defaults; 6503 } 6504 6505 return Select2; 6506 }); 6507 6508 // Return the AMD loader configuration so it can be used outside of this file 6509 return { 6510 define: S2.define, 6511 require: S2.require 6512 }; 6513 }()); 6514 6515 // Autoload the jQuery bindings 6516 // We know that all of the modules exist above this, so we're safe 6517 var select2 = S2.require('jquery.select2'); 6518 6519 // Hold the AMD module references on the jQuery function that was just loaded 6520 // This allows Select2 to use the internal loader outside of this file, such 6521 // as in the language files. 6522 jQuery.fn.select2.amd = S2; 6523 6524 // Return the Select2 instance for anyone who is importing it. 6525 return select2; 6526}));
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.