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