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