PluginProbe
WP Ultimate Post Grid / 2.8.0
WP Ultimate Post Grid v2.8.0
4.1.1 trunk 1.5 1.6 1.7 1.7.1 1.7.2 1.8 1.9 2.0 2.1 2.2 2.3 2.4.0 2.5.0 2.6.0 2.7.0 2.8.0 2.8.2 3.0.0 3.3.0 3.4.0 3.5.0 3.6.0 3.7.0 All 32 releases
wp-ultimate-post-grid / vendor / select2 / js / select2.js

select2.js in WP Ultimate Post Grid 2.8.0, at vendor/select2/js/select2.js

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