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