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