You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2020/04/23 09:53:36 UTC
[myfaces-tobago] 08/08: Tobago-1999: update select2 to version
4.0.13
This is an automated email from the ASF dual-hosted git repository.
weber pushed a commit to branch TOBAGO-1999_Select2
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git
commit 0d98a30db55a37adebb5bad3dde99d4478ed6105
Author: Volker Weber <v....@inexso.de>
AuthorDate: Thu Apr 23 11:31:03 2020 +0200
Tobago-1999: update select2 to version 4.0.13
---
.../src/main/resources/META-INF/tobago-config.xml | 8 +-
.../contrib/select2/select2-4.0.8.full.min.js | 2 -
.../script/contrib/select2/select2-4.0.8.min.js | 2 -
.../{select2-4.0.8.full.js => select2.full.js} | 459 +++++++++++++++------
.../script/contrib/select2/select2.full.min.js | 2 +
.../select2/{select2-4.0.8.js => select2.js} | 453 ++++++++++++++------
.../standard/script/contrib/select2/select2.min.js | 2 +
.../standard/standard/script/tobago-select2.js | 70 +++-
.../style/contrib/select2/select2-4.0.8.min.css | 1 -
.../select2/{select2-4.0.8.css => select2.css} | 3 +-
.../standard/style/contrib/select2/select2.min.css | 1 +
11 files changed, 753 insertions(+), 250 deletions(-)
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
index 3c75847..66bd380 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
@@ -402,11 +402,11 @@
<script priority="10" name="script/contrib/jquery-3.5.0.js"/>
<script priority="20" name="script/contrib/jquery-ui-1.10.4.custom.js"/>
<script priority="30" name="script/contrib/jquery-ui-timepicker-addon-1.4.5.js"/>
- <script priority="35" name="script/contrib/select2/select2-4.0.8.full.js"/>
+ <script priority="35" name="script/contrib/select2/select2.full.js"/>
<script priority="40" name="script/tobago.js"/>
<style priority="10" name="style/contrib/ui-lightness/jquery-ui-1.10.4.custom.css"/>
<style priority="20" name="style/contrib/jquery-ui-timepicker-addon-1.4.5.css"/>
- <style priority="25" name="style/contrib/select2/select2-4.0.8.css"/>
+ <style priority="25" name="style/contrib/select2/select2.css"/>
<style priority="30" name="style/tobago.css"/>
<!-- backward compatibility -->
<style priority="40" name="style/style.css"/>
@@ -415,7 +415,7 @@
<script priority="10" name="script/contrib/jquery-3.5.0.js"/>
<script priority="20" name="script/contrib/jquery-ui-1.10.4.custom.js"/>
<script priority="30" name="script/contrib/jquery-ui-timepicker-addon-1.4.5.js"/>
- <script priority="35" name="script/contrib/select2/select2-4.0.8.full.js"/>
+ <script priority="35" name="script/contrib/select2/select2.full.js"/>
<script priority="40" name="script/tobago.js"/>
<script priority="50" name="script/tobago-calendar.js"/>
<script priority="60" name="script/tobago-console.js"/>
@@ -434,7 +434,7 @@
<script priority="180" name="script/tobago-logging.js"/>
<style priority="10" name="style/contrib/ui-lightness/jquery-ui-1.10.4.custom.css"/>
<style priority="20" name="style/contrib/jquery-ui-timepicker-addon-1.4.5.css"/>
- <style priority="25" name="style/contrib/select2/select2-4.0.8.css"/>
+ <style priority="25" name="style/contrib/select2/select2.css"/>
<style priority="30" name="style/tobago.css"/>
<!-- backward compatibility -->
<style priority="40" name="style/style.css"/>
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.full.min.js b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.full.min.js
deleted file mode 100644
index 1d0460d..0000000
--- a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.full.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! Select2 4.0.8 | https://github.com/select2/select2/blob/master/LICENSE.md */
-!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(d){var e=function(){if(d&&d.fn&&d.fn.select2&&d.fn.select2.amd)var e=d.fn.select2.amd;var t,n,i,h,o,s,f,g,m,v,y,_,r,a,w,l;function b(e,t){return r.call(e,t)}function c(e,t){var n,i,r,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["* [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.min.js b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.min.js
deleted file mode 100644
index 9def5ae..0000000
--- a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! Select2 4.0.8 | https://github.com/select2/select2/blob/master/LICENSE.md */
-!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(u){var e=function(){if(u&&u.fn&&u.fn.select2&&u.fn.select2.amd)var e=u.fn.select2.amd;var t,n,r,h,o,s,f,g,m,v,y,_,i,a,w;function b(e,t){return i.call(e,t)}function l(e,t){var n,r,i,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"] [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.full.js b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.full.js
similarity index 94%
rename from tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.full.js
rename to tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.full.js
index efb27b2..358572a 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.full.js
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.full.js
@@ -1,5 +1,5 @@
/*!
- * Select2 4.0.8
+ * Select2 4.0.13
* https://select2.github.io
*
* Released under the MIT license
@@ -832,6 +832,8 @@ S2.define('select2/utils',[
if (Utils.__cache[id] != null) {
delete Utils.__cache[id];
}
+
+ element.removeAttribute('data-select2-id');
};
return Utils;
@@ -853,7 +855,7 @@ S2.define('select2/results',[
Results.prototype.render = function () {
var $results = $(
- '<ul class="select2-results__options" role="tree"></ul>'
+ '<ul class="select2-results__options" role="listbox"></ul>'
);
if (this.options.get('multiple')) {
@@ -876,7 +878,7 @@ S2.define('select2/results',[
this.hideLoading();
var $message = $(
- '<li role="treeitem" aria-live="assertive"' +
+ '<li role="alert" aria-live="assertive"' +
' class="select2-results__option"></li>'
);
@@ -1010,7 +1012,7 @@ S2.define('select2/results',[
option.className = 'select2-results__option';
var attrs = {
- 'role': 'treeitem',
+ 'role': 'option',
'aria-selected': 'false'
};
@@ -1430,6 +1432,7 @@ S2.define('select2/selection/base',[
$selection.attr('title', this.$element.attr('title'));
$selection.attr('tabindex', this._tabindex);
+ $selection.attr('aria-disabled', 'false');
this.$selection = $selection;
@@ -1439,7 +1442,6 @@ S2.define('select2/selection/base',[
BaseSelection.prototype.bind = function (container, $container) {
var self = this;
- var id = container.id + '-container';
var resultsId = container.id + '-results';
this.container = container;
@@ -1489,10 +1491,12 @@ S2.define('select2/selection/base',[
container.on('enable', function () {
self.$selection.attr('tabindex', self._tabindex);
+ self.$selection.attr('aria-disabled', 'false');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
+ self.$selection.attr('aria-disabled', 'true');
});
};
@@ -1515,7 +1519,6 @@ S2.define('select2/selection/base',[
};
BaseSelection.prototype._attachCloseHandler = function (container) {
- var self = this;
$(document.body).on('mousedown.select2.' + container.id, function (e) {
var $target = $(e.target);
@@ -1525,8 +1528,6 @@ S2.define('select2/selection/base',[
var $all = $('.select2.select2-container--open');
$all.each(function () {
- var $this = $(this);
-
if (this == $select[0]) {
return;
}
@@ -1555,6 +1556,27 @@ S2.define('select2/selection/base',[
throw new Error('The `update` method must be defined in child classes.');
};
+ /**
+ * Helper method to abstract the "enabled" (not "disabled") state of this
+ * object.
+ *
+ * @return {true} if the instance is not disabled.
+ * @return {false} if the instance is disabled.
+ */
+ BaseSelection.prototype.isEnabled = function () {
+ return !this.isDisabled();
+ };
+
+ /**
+ * Helper method to abstract the "disabled" state of this object.
+ *
+ * @return {true} if the disabled option is true.
+ * @return {false} if the disabled option is false.
+ */
+ BaseSelection.prototype.isDisabled = function () {
+ return this.options.get('disabled');
+ };
+
return BaseSelection;
});
@@ -1653,7 +1675,14 @@ S2.define('select2/selection/single',[
var formatted = this.display(selection, $rendered);
$rendered.empty().append(formatted);
- $rendered.attr('title', selection.title || selection.text);
+
+ var title = selection.title || selection.text;
+
+ if (title) {
+ $rendered.attr('title', title);
+ } else {
+ $rendered.removeAttr('title');
+ }
};
return SingleSelection;
@@ -1698,7 +1727,7 @@ S2.define('select2/selection/multiple',[
'.select2-selection__choice__remove',
function (evt) {
// Ignore the event if it is disabled
- if (self.options.get('disabled')) {
+ if (self.isDisabled()) {
return;
}
@@ -1756,7 +1785,12 @@ S2.define('select2/selection/multiple',[
var formatted = this.display(selection, $selection);
$selection.append(formatted);
- $selection.attr('title', selection.title || selection.text);
+
+ var title = selection.title || selection.text;
+
+ if (title) {
+ $selection.attr('title', title);
+ }
Utils.StoreData($selection[0], 'data', selection);
@@ -1854,7 +1888,7 @@ S2.define('select2/selection/allowClear',[
AllowClear.prototype._handleClear = function (_, evt) {
// Ignore the event if it is disabled
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
return;
}
@@ -1897,7 +1931,7 @@ S2.define('select2/selection/allowClear',[
}
}
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
this.trigger('toggle', {});
};
@@ -1920,7 +1954,7 @@ S2.define('select2/selection/allowClear',[
return;
}
- var removeAll = this.options.get('translations').get('removeAllItems');
+ var removeAll = this.options.get('translations').get('removeAllItems');
var $remove = $(
'<span class="select2-selection__clear" title="' + removeAll() +'">' +
@@ -1949,7 +1983,7 @@ S2.define('select2/selection/search',[
'<li class="select2-search select2-search--inline">' +
'<input class="select2-search__field" type="search" tabindex="-1"' +
' autocomplete="off" autocorrect="off" autocapitalize="none"' +
- ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
+ ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
'</li>'
);
@@ -1966,14 +2000,18 @@ S2.define('select2/selection/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
+
decorated.call(this, container, $container);
container.on('open', function () {
+ self.$search.attr('aria-controls', resultsId);
self.$search.trigger('focus');
});
container.on('close', function () {
self.$search.val('');
+ self.$search.removeAttr('aria-controls');
self.$search.removeAttr('aria-activedescendant');
self.$search.trigger('focus');
});
@@ -1993,7 +2031,11 @@ S2.define('select2/selection/search',[
});
container.on('results:focus', function (params) {
- self.$search.attr('aria-activedescendant', params.id);
+ if (params.data._resultId) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ } else {
+ self.$search.removeAttr('aria-activedescendant');
+ }
});
this.$selection.on('focusin', '.select2-search--inline', function (evt) {
@@ -2027,6 +2069,12 @@ S2.define('select2/selection/search',[
}
});
+ this.$selection.on('click', '.select2-search--inline', function (evt) {
+ if (self.$search.val()) {
+ evt.stopPropagation();
+ }
+ });
+
// Try to detect the IE version should the `documentMode` property that
// is stored on the document. This is only implemented in IE and is
// slightly cleaner than doing a user agent check.
@@ -2145,7 +2193,7 @@ S2.define('select2/selection/search',[
var width = '';
if (this.$search.attr('placeholder') !== '') {
- width = this.$selection.find('.select2-selection__rendered').innerWidth();
+ width = this.$selection.find('.select2-selection__rendered').width();
} else {
var minimumWidth = this.$search.val().length + 1;
@@ -3174,7 +3222,7 @@ S2.define('select2/data/select',[
if ($(data.element).is('option')) {
data.element.selected = true;
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
return;
}
@@ -3195,13 +3243,13 @@ S2.define('select2/data/select',[
}
self.$element.val(val);
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
} else {
var val = data.id;
this.$element.val(val);
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
}
};
@@ -3217,7 +3265,7 @@ S2.define('select2/data/select',[
if ($(data.element).is('option')) {
data.element.selected = false;
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
return;
}
@@ -3235,7 +3283,7 @@ S2.define('select2/data/select',[
self.$element.val(val);
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
};
@@ -3428,15 +3476,19 @@ S2.define('select2/data/array',[
'jquery'
], function (SelectAdapter, Utils, $) {
function ArrayAdapter ($element, options) {
- var data = options.get('data') || [];
+ this._dataToConvert = options.get('data') || [];
ArrayAdapter.__super__.constructor.call(this, $element, options);
-
- this.addOptions(this.convertToOptions(data));
}
Utils.Extend(ArrayAdapter, SelectAdapter);
+ ArrayAdapter.prototype.bind = function (container, $container) {
+ ArrayAdapter.__super__.bind.call(this, container, $container);
+
+ this.addOptions(this.convertToOptions(this._dataToConvert));
+ };
+
ArrayAdapter.prototype.select = function (data) {
var $option = this.$element.find('option').filter(function (i, elm) {
return elm.value == data.id.toString();
@@ -3726,8 +3778,6 @@ S2.define('select2/data/tags',[
};
Tags.prototype._removeOldTags = function (_) {
- var tag = this._lastTag;
-
var $options = this.$element.find('option[data-select2-tag]');
$options.each(function () {
@@ -3931,10 +3981,30 @@ S2.define('select2/data/maximumSelectionLength',[
decorated.call(this, $e, options);
}
+ MaximumSelectionLength.prototype.bind =
+ function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('select', function () {
+ self._checkIfMaximumSelected();
+ });
+ };
+
MaximumSelectionLength.prototype.query =
function (decorated, params, callback) {
var self = this;
+ this._checkIfMaximumSelected(function () {
+ decorated.call(self, params, callback);
+ });
+ };
+
+ MaximumSelectionLength.prototype._checkIfMaximumSelected =
+ function (_, successCallback) {
+ var self = this;
+
this.current(function (currentData) {
var count = currentData != null ? currentData.length : 0;
if (self.maximumSelectionLength > 0 &&
@@ -3947,7 +4017,10 @@ S2.define('select2/data/maximumSelectionLength',[
});
return;
}
- decorated.call(self, params, callback);
+
+ if (successCallback) {
+ successCallback();
+ }
});
};
@@ -4010,7 +4083,7 @@ S2.define('select2/dropdown/search',[
'<span class="select2-search select2-search--dropdown">' +
'<input class="select2-search__field" type="search" tabindex="-1"' +
' autocomplete="off" autocorrect="off" autocapitalize="none"' +
- ' spellcheck="false" role="textbox" />' +
+ ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
'</span>'
);
@@ -4025,6 +4098,8 @@ S2.define('select2/dropdown/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
+
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
@@ -4047,6 +4122,7 @@ S2.define('select2/dropdown/search',[
container.on('open', function () {
self.$search.attr('tabindex', 0);
+ self.$search.attr('aria-controls', resultsId);
self.$search.trigger('focus');
@@ -4057,6 +4133,8 @@ S2.define('select2/dropdown/search',[
container.on('close', function () {
self.$search.attr('tabindex', -1);
+ self.$search.removeAttr('aria-controls');
+ self.$search.removeAttr('aria-activedescendant');
self.$search.val('');
self.$search.trigger('blur');
@@ -4079,6 +4157,14 @@ S2.define('select2/dropdown/search',[
}
}
});
+
+ container.on('results:focus', function (params) {
+ if (params.data._resultId) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ } else {
+ self.$search.removeAttr('aria-activedescendant');
+ }
+ });
};
Search.prototype.handleSearch = function (evt) {
@@ -4223,7 +4309,7 @@ S2.define('select2/dropdown/infiniteScroll',[
var $option = $(
'<li ' +
'class="select2-results__option select2-results__option--load-more"' +
- 'role="treeitem" aria-disabled="true"></li>'
+ 'role="option" aria-disabled="true"></li>'
);
var message = this.options.get('translations').get('loadingMore');
@@ -4241,7 +4327,7 @@ S2.define('select2/dropdown/attachBody',[
'../utils'
], function ($, Utils) {
function AttachBody (decorated, $element, options) {
- this.$dropdownParent = options.get('dropdownParent') || $(document.body);
+ this.$dropdownParent = $(options.get('dropdownParent') || document.body);
decorated.call(this, $element, options);
}
@@ -4249,27 +4335,14 @@ S2.define('select2/dropdown/attachBody',[
AttachBody.prototype.bind = function (decorated, container, $container) {
var self = this;
- var setupResultsEvents = false;
-
decorated.call(this, container, $container);
container.on('open', function () {
self._showDropdown();
self._attachPositioningHandler(container);
- if (!setupResultsEvents) {
- setupResultsEvents = true;
-
- container.on('results:all', function () {
- self._positionDropdown();
- self._resizeDropdown();
- });
-
- container.on('results:append', function () {
- self._positionDropdown();
- self._resizeDropdown();
- });
- }
+ // Must bind after the results handlers to ensure correct sizing
+ self._bindContainerResultHandlers(container);
});
container.on('close', function () {
@@ -4318,6 +4391,44 @@ S2.define('select2/dropdown/attachBody',[
this.$dropdownContainer.detach();
};
+ AttachBody.prototype._bindContainerResultHandlers =
+ function (decorated, container) {
+
+ // These should only be bound once
+ if (this._containerResultsHandlersBound) {
+ return;
+ }
+
+ var self = this;
+
+ container.on('results:all', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:append', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:message', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('select', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('unselect', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ this._containerResultsHandlersBound = true;
+ };
+
AttachBody.prototype._attachPositioningHandler =
function (decorated, container) {
var self = this;
@@ -4403,7 +4514,17 @@ S2.define('select2/dropdown/attachBody',[
$offsetParent = $offsetParent.offsetParent();
}
- var parentOffset = $offsetParent.offset();
+ var parentOffset = {
+ top: 0,
+ left: 0
+ };
+
+ if (
+ $.contains(document.body, $offsetParent[0]) ||
+ $offsetParent[0].isConnected
+ ) {
+ parentOffset = $offsetParent.offset();
+ }
css.top -= parentOffset.top;
css.left -= parentOffset.left;
@@ -4868,66 +4989,29 @@ S2.define('select2/defaults',[
);
}
- if (typeof options.language === 'string') {
- // Check if the language is specified with a region
- if (options.language.indexOf('-') > 0) {
- // Extract the region information if it is included
- var languageParts = options.language.split('-');
- var baseLanguage = languageParts[0];
-
- options.language = [options.language, baseLanguage];
- } else {
- options.language = [options.language];
- }
- }
-
- if ($.isArray(options.language)) {
- var languages = new Translation();
- options.language.push('en');
+ // If the defaults were not previously applied from an element, it is
+ // possible for the language option to have not been resolved
+ options.language = this._resolveLanguage(options.language);
- var languageNames = options.language;
+ // Always fall back to English since it will always be complete
+ options.language.push('en');
- for (var l = 0; l < languageNames.length; l++) {
- var name = languageNames[l];
- var language = {};
-
- try {
- // Try to load it with the original name
- language = Translation.loadPath(name);
- } catch (e) {
- try {
- // If we couldn't load it, check if it wasn't the full path
- name = this.defaults.amdLanguageBase + name;
- language = Translation.loadPath(name);
- } catch (ex) {
- // The translation could not be loaded at all. Sometimes this is
- // because of a configuration problem, other times this can be
- // because of how Select2 helps load all possible translation files.
- if (options.debug && window.console && console.warn) {
- console.warn(
- 'Select2: The language file for "' + name + '" could not be ' +
- 'automatically loaded. A fallback will be used instead.'
- );
- }
+ var uniqueLanguages = [];
- continue;
- }
- }
+ for (var l = 0; l < options.language.length; l++) {
+ var language = options.language[l];
- languages.extend(language);
+ if (uniqueLanguages.indexOf(language) === -1) {
+ uniqueLanguages.push(language);
}
+ }
- options.translations = languages;
- } else {
- var baseTranslation = Translation.loadPath(
- this.defaults.amdLanguageBase + 'en'
- );
- var customTranslation = new Translation(options.language);
-
- customTranslation.extend(baseTranslation);
+ options.language = uniqueLanguages;
- options.translations = customTranslation;
- }
+ options.translations = this._processTranslations(
+ options.language,
+ options.debug
+ );
return options;
};
@@ -4994,7 +5078,7 @@ S2.define('select2/defaults',[
debug: false,
dropdownAutoWidth: false,
escapeMarkup: Utils.escapeMarkup,
- language: EnglishTranslation,
+ language: {},
matcher: matcher,
minimumInputLength: 0,
maximumInputLength: 0,
@@ -5016,6 +5100,103 @@ S2.define('select2/defaults',[
};
};
+ Defaults.prototype.applyFromElement = function (options, $element) {
+ var optionLanguage = options.language;
+ var defaultLanguage = this.defaults.language;
+ var elementLanguage = $element.prop('lang');
+ var parentLanguage = $element.closest('[lang]').prop('lang');
+
+ var languages = Array.prototype.concat.call(
+ this._resolveLanguage(elementLanguage),
+ this._resolveLanguage(optionLanguage),
+ this._resolveLanguage(defaultLanguage),
+ this._resolveLanguage(parentLanguage)
+ );
+
+ options.language = languages;
+
+ return options;
+ };
+
+ Defaults.prototype._resolveLanguage = function (language) {
+ if (!language) {
+ return [];
+ }
+
+ if ($.isEmptyObject(language)) {
+ return [];
+ }
+
+ if ($.isPlainObject(language)) {
+ return [language];
+ }
+
+ var languages;
+
+ if (!$.isArray(language)) {
+ languages = [language];
+ } else {
+ languages = language;
+ }
+
+ var resolvedLanguages = [];
+
+ for (var l = 0; l < languages.length; l++) {
+ resolvedLanguages.push(languages[l]);
+
+ if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) {
+ // Extract the region information if it is included
+ var languageParts = languages[l].split('-');
+ var baseLanguage = languageParts[0];
+
+ resolvedLanguages.push(baseLanguage);
+ }
+ }
+
+ return resolvedLanguages;
+ };
+
+ Defaults.prototype._processTranslations = function (languages, debug) {
+ var translations = new Translation();
+
+ for (var l = 0; l < languages.length; l++) {
+ var languageData = new Translation();
+
+ var language = languages[l];
+
+ if (typeof language === 'string') {
+ try {
+ // Try to load it with the original name
+ languageData = Translation.loadPath(language);
+ } catch (e) {
+ try {
+ // If we couldn't load it, check if it wasn't the full path
+ language = this.defaults.amdLanguageBase + language;
+ languageData = Translation.loadPath(language);
+ } catch (ex) {
+ // The translation could not be loaded at all. Sometimes this is
+ // because of a configuration problem, other times this can be
+ // because of how Select2 helps load all possible translation files
+ if (debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The language file for "' + language + '" could ' +
+ 'not be automatically loaded. A fallback will be used instead.'
+ );
+ }
+ }
+ }
+ } else if ($.isPlainObject(language)) {
+ languageData = new Translation(language);
+ } else {
+ languageData = language;
+ }
+
+ translations.extend(languageData);
+ }
+
+ return translations;
+ };
+
Defaults.prototype.set = function (key, value) {
var camelKey = $.camelCase(key);
@@ -5045,6 +5226,10 @@ S2.define('select2/options',[
this.fromElement($element);
}
+ if ($element != null) {
+ this.options = Defaults.applyFromElement(this.options, $element);
+ }
+
this.options = Defaults.apply(this.options);
if ($element && $element.is('input')) {
@@ -5068,14 +5253,6 @@ S2.define('select2/options',[
this.options.disabled = $e.prop('disabled');
}
- if (this.options.language == null) {
- if ($e.prop('lang')) {
- this.options.language = $e.prop('lang').toLowerCase();
- } else if ($e.closest('[lang]').prop('lang')) {
- this.options.language = $e.closest('[lang]').prop('lang');
- }
- }
-
if (this.options.dir == null) {
if ($e.prop('dir')) {
this.options.dir = $e.prop('dir');
@@ -5389,8 +5566,8 @@ S2.define('select2/core',[
if (observer != null) {
this._observer = new observer(function (mutations) {
- $.each(mutations, self._syncA);
- $.each(mutations, self._syncS);
+ self._syncA();
+ self._syncS(null, mutations);
});
this._observer.observe(this.$element[0], {
attributes: true,
@@ -5512,7 +5689,7 @@ S2.define('select2/core',[
if (self.isOpen()) {
if (key === KEYS.ESC || key === KEYS.TAB ||
(key === KEYS.UP && evt.altKey)) {
- self.close();
+ self.close(evt);
evt.preventDefault();
} else if (key === KEYS.ENTER) {
@@ -5546,7 +5723,7 @@ S2.define('select2/core',[
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
if (this.isOpen()) {
this.close();
}
@@ -5557,7 +5734,7 @@ S2.define('select2/core',[
}
};
- Select2.prototype._syncSubtree = function (evt, mutations) {
+ Select2.prototype._isChangeMutation = function (evt, mutations) {
var changed = false;
var self = this;
@@ -5585,7 +5762,22 @@ S2.define('select2/core',[
}
} else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
changed = true;
+ } else if ($.isArray(mutations)) {
+ $.each(mutations, function(evt, mutation) {
+ if (self._isChangeMutation(evt, mutation)) {
+ // We've found a change mutation.
+ // Let's escape from the loop and continue
+ changed = true;
+ return false;
+ }
+ });
}
+ return changed;
+ };
+
+ Select2.prototype._syncSubtree = function (evt, mutations) {
+ var changed = this._isChangeMutation(evt, mutations);
+ var self = this;
// Only re-pull the data if we think there is a change
if (changed) {
@@ -5636,7 +5828,7 @@ S2.define('select2/core',[
};
Select2.prototype.toggleDropdown = function () {
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
return;
}
@@ -5652,15 +5844,40 @@ S2.define('select2/core',[
return;
}
+ if (this.isDisabled()) {
+ return;
+ }
+
this.trigger('query', {});
};
- Select2.prototype.close = function () {
+ Select2.prototype.close = function (evt) {
if (!this.isOpen()) {
return;
}
- this.trigger('close', {});
+ this.trigger('close', { originalEvent : evt });
+ };
+
+ /**
+ * Helper method to abstract the "enabled" (not "disabled") state of this
+ * object.
+ *
+ * @return {true} if the instance is not disabled.
+ * @return {false} if the instance is disabled.
+ */
+ Select2.prototype.isEnabled = function () {
+ return !this.isDisabled();
+ };
+
+ /**
+ * Helper method to abstract the "disabled" state of this object.
+ *
+ * @return {true} if the disabled option is true.
+ * @return {false} if the disabled option is false.
+ */
+ Select2.prototype.isDisabled = function () {
+ return this.options.get('disabled');
};
Select2.prototype.isOpen = function () {
@@ -5737,7 +5954,7 @@ S2.define('select2/core',[
});
}
- this.$element.val(newVal).trigger('change');
+ this.$element.val(newVal).trigger('input').trigger('change');
};
Select2.prototype.destroy = function () {
@@ -6072,13 +6289,13 @@ S2.define('select2/compat/inputData',[
});
this.$element.val(data.id);
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
} else {
var value = this.$element.val();
value += this._valueSeparator + data.id;
this.$element.val(value);
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
}
};
@@ -6101,7 +6318,7 @@ S2.define('select2/compat/inputData',[
}
self.$element.val(values.join(self._valueSeparator));
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
};
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.full.min.js b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.full.min.js
new file mode 100644
index 0000000..fa78191
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.full.min.js
@@ -0,0 +1,2 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(d){var e=function(){if(d&&d.fn&&d.fn.select2&&d.fn.select2.amd)var e=d.fn.select2.amd;var t,n,i,h,o,s,f,g,m,v,y,_,r,a,w,l;function b(e,t){return r.call(e,t)}function c(e,t){var n,i,r,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["* [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.js b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.js
similarity index 93%
rename from tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.js
rename to tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.js
index d33caac..fcfb5ab 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2-4.0.8.js
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.js
@@ -1,5 +1,5 @@
/*!
- * Select2 4.0.8
+ * Select2 4.0.13
* https://select2.github.io
*
* Released under the MIT license
@@ -832,6 +832,8 @@ S2.define('select2/utils',[
if (Utils.__cache[id] != null) {
delete Utils.__cache[id];
}
+
+ element.removeAttribute('data-select2-id');
};
return Utils;
@@ -853,7 +855,7 @@ S2.define('select2/results',[
Results.prototype.render = function () {
var $results = $(
- '<ul class="select2-results__options" role="tree"></ul>'
+ '<ul class="select2-results__options" role="listbox"></ul>'
);
if (this.options.get('multiple')) {
@@ -876,7 +878,7 @@ S2.define('select2/results',[
this.hideLoading();
var $message = $(
- '<li role="treeitem" aria-live="assertive"' +
+ '<li role="alert" aria-live="assertive"' +
' class="select2-results__option"></li>'
);
@@ -1010,7 +1012,7 @@ S2.define('select2/results',[
option.className = 'select2-results__option';
var attrs = {
- 'role': 'treeitem',
+ 'role': 'option',
'aria-selected': 'false'
};
@@ -1430,6 +1432,7 @@ S2.define('select2/selection/base',[
$selection.attr('title', this.$element.attr('title'));
$selection.attr('tabindex', this._tabindex);
+ $selection.attr('aria-disabled', 'false');
this.$selection = $selection;
@@ -1439,7 +1442,6 @@ S2.define('select2/selection/base',[
BaseSelection.prototype.bind = function (container, $container) {
var self = this;
- var id = container.id + '-container';
var resultsId = container.id + '-results';
this.container = container;
@@ -1489,10 +1491,12 @@ S2.define('select2/selection/base',[
container.on('enable', function () {
self.$selection.attr('tabindex', self._tabindex);
+ self.$selection.attr('aria-disabled', 'false');
});
container.on('disable', function () {
self.$selection.attr('tabindex', '-1');
+ self.$selection.attr('aria-disabled', 'true');
});
};
@@ -1515,7 +1519,6 @@ S2.define('select2/selection/base',[
};
BaseSelection.prototype._attachCloseHandler = function (container) {
- var self = this;
$(document.body).on('mousedown.select2.' + container.id, function (e) {
var $target = $(e.target);
@@ -1525,8 +1528,6 @@ S2.define('select2/selection/base',[
var $all = $('.select2.select2-container--open');
$all.each(function () {
- var $this = $(this);
-
if (this == $select[0]) {
return;
}
@@ -1555,6 +1556,27 @@ S2.define('select2/selection/base',[
throw new Error('The `update` method must be defined in child classes.');
};
+ /**
+ * Helper method to abstract the "enabled" (not "disabled") state of this
+ * object.
+ *
+ * @return {true} if the instance is not disabled.
+ * @return {false} if the instance is disabled.
+ */
+ BaseSelection.prototype.isEnabled = function () {
+ return !this.isDisabled();
+ };
+
+ /**
+ * Helper method to abstract the "disabled" state of this object.
+ *
+ * @return {true} if the disabled option is true.
+ * @return {false} if the disabled option is false.
+ */
+ BaseSelection.prototype.isDisabled = function () {
+ return this.options.get('disabled');
+ };
+
return BaseSelection;
});
@@ -1653,7 +1675,14 @@ S2.define('select2/selection/single',[
var formatted = this.display(selection, $rendered);
$rendered.empty().append(formatted);
- $rendered.attr('title', selection.title || selection.text);
+
+ var title = selection.title || selection.text;
+
+ if (title) {
+ $rendered.attr('title', title);
+ } else {
+ $rendered.removeAttr('title');
+ }
};
return SingleSelection;
@@ -1698,7 +1727,7 @@ S2.define('select2/selection/multiple',[
'.select2-selection__choice__remove',
function (evt) {
// Ignore the event if it is disabled
- if (self.options.get('disabled')) {
+ if (self.isDisabled()) {
return;
}
@@ -1756,7 +1785,12 @@ S2.define('select2/selection/multiple',[
var formatted = this.display(selection, $selection);
$selection.append(formatted);
- $selection.attr('title', selection.title || selection.text);
+
+ var title = selection.title || selection.text;
+
+ if (title) {
+ $selection.attr('title', title);
+ }
Utils.StoreData($selection[0], 'data', selection);
@@ -1854,7 +1888,7 @@ S2.define('select2/selection/allowClear',[
AllowClear.prototype._handleClear = function (_, evt) {
// Ignore the event if it is disabled
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
return;
}
@@ -1897,7 +1931,7 @@ S2.define('select2/selection/allowClear',[
}
}
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
this.trigger('toggle', {});
};
@@ -1920,7 +1954,7 @@ S2.define('select2/selection/allowClear',[
return;
}
- var removeAll = this.options.get('translations').get('removeAllItems');
+ var removeAll = this.options.get('translations').get('removeAllItems');
var $remove = $(
'<span class="select2-selection__clear" title="' + removeAll() +'">' +
@@ -1949,7 +1983,7 @@ S2.define('select2/selection/search',[
'<li class="select2-search select2-search--inline">' +
'<input class="select2-search__field" type="search" tabindex="-1"' +
' autocomplete="off" autocorrect="off" autocapitalize="none"' +
- ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
+ ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
'</li>'
);
@@ -1966,14 +2000,18 @@ S2.define('select2/selection/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
+
decorated.call(this, container, $container);
container.on('open', function () {
+ self.$search.attr('aria-controls', resultsId);
self.$search.trigger('focus');
});
container.on('close', function () {
self.$search.val('');
+ self.$search.removeAttr('aria-controls');
self.$search.removeAttr('aria-activedescendant');
self.$search.trigger('focus');
});
@@ -1993,7 +2031,11 @@ S2.define('select2/selection/search',[
});
container.on('results:focus', function (params) {
- self.$search.attr('aria-activedescendant', params.id);
+ if (params.data._resultId) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ } else {
+ self.$search.removeAttr('aria-activedescendant');
+ }
});
this.$selection.on('focusin', '.select2-search--inline', function (evt) {
@@ -2027,6 +2069,12 @@ S2.define('select2/selection/search',[
}
});
+ this.$selection.on('click', '.select2-search--inline', function (evt) {
+ if (self.$search.val()) {
+ evt.stopPropagation();
+ }
+ });
+
// Try to detect the IE version should the `documentMode` property that
// is stored on the document. This is only implemented in IE and is
// slightly cleaner than doing a user agent check.
@@ -2145,7 +2193,7 @@ S2.define('select2/selection/search',[
var width = '';
if (this.$search.attr('placeholder') !== '') {
- width = this.$selection.find('.select2-selection__rendered').innerWidth();
+ width = this.$selection.find('.select2-selection__rendered').width();
} else {
var minimumWidth = this.$search.val().length + 1;
@@ -3174,7 +3222,7 @@ S2.define('select2/data/select',[
if ($(data.element).is('option')) {
data.element.selected = true;
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
return;
}
@@ -3195,13 +3243,13 @@ S2.define('select2/data/select',[
}
self.$element.val(val);
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
} else {
var val = data.id;
this.$element.val(val);
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
}
};
@@ -3217,7 +3265,7 @@ S2.define('select2/data/select',[
if ($(data.element).is('option')) {
data.element.selected = false;
- this.$element.trigger('change');
+ this.$element.trigger('input').trigger('change');
return;
}
@@ -3235,7 +3283,7 @@ S2.define('select2/data/select',[
self.$element.val(val);
- self.$element.trigger('change');
+ self.$element.trigger('input').trigger('change');
});
};
@@ -3428,15 +3476,19 @@ S2.define('select2/data/array',[
'jquery'
], function (SelectAdapter, Utils, $) {
function ArrayAdapter ($element, options) {
- var data = options.get('data') || [];
+ this._dataToConvert = options.get('data') || [];
ArrayAdapter.__super__.constructor.call(this, $element, options);
-
- this.addOptions(this.convertToOptions(data));
}
Utils.Extend(ArrayAdapter, SelectAdapter);
+ ArrayAdapter.prototype.bind = function (container, $container) {
+ ArrayAdapter.__super__.bind.call(this, container, $container);
+
+ this.addOptions(this.convertToOptions(this._dataToConvert));
+ };
+
ArrayAdapter.prototype.select = function (data) {
var $option = this.$element.find('option').filter(function (i, elm) {
return elm.value == data.id.toString();
@@ -3726,8 +3778,6 @@ S2.define('select2/data/tags',[
};
Tags.prototype._removeOldTags = function (_) {
- var tag = this._lastTag;
-
var $options = this.$element.find('option[data-select2-tag]');
$options.each(function () {
@@ -3931,10 +3981,30 @@ S2.define('select2/data/maximumSelectionLength',[
decorated.call(this, $e, options);
}
+ MaximumSelectionLength.prototype.bind =
+ function (decorated, container, $container) {
+ var self = this;
+
+ decorated.call(this, container, $container);
+
+ container.on('select', function () {
+ self._checkIfMaximumSelected();
+ });
+ };
+
MaximumSelectionLength.prototype.query =
function (decorated, params, callback) {
var self = this;
+ this._checkIfMaximumSelected(function () {
+ decorated.call(self, params, callback);
+ });
+ };
+
+ MaximumSelectionLength.prototype._checkIfMaximumSelected =
+ function (_, successCallback) {
+ var self = this;
+
this.current(function (currentData) {
var count = currentData != null ? currentData.length : 0;
if (self.maximumSelectionLength > 0 &&
@@ -3947,7 +4017,10 @@ S2.define('select2/data/maximumSelectionLength',[
});
return;
}
- decorated.call(self, params, callback);
+
+ if (successCallback) {
+ successCallback();
+ }
});
};
@@ -4010,7 +4083,7 @@ S2.define('select2/dropdown/search',[
'<span class="select2-search select2-search--dropdown">' +
'<input class="select2-search__field" type="search" tabindex="-1"' +
' autocomplete="off" autocorrect="off" autocapitalize="none"' +
- ' spellcheck="false" role="textbox" />' +
+ ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
'</span>'
);
@@ -4025,6 +4098,8 @@ S2.define('select2/dropdown/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
+
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
@@ -4047,6 +4122,7 @@ S2.define('select2/dropdown/search',[
container.on('open', function () {
self.$search.attr('tabindex', 0);
+ self.$search.attr('aria-controls', resultsId);
self.$search.trigger('focus');
@@ -4057,6 +4133,8 @@ S2.define('select2/dropdown/search',[
container.on('close', function () {
self.$search.attr('tabindex', -1);
+ self.$search.removeAttr('aria-controls');
+ self.$search.removeAttr('aria-activedescendant');
self.$search.val('');
self.$search.trigger('blur');
@@ -4079,6 +4157,14 @@ S2.define('select2/dropdown/search',[
}
}
});
+
+ container.on('results:focus', function (params) {
+ if (params.data._resultId) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ } else {
+ self.$search.removeAttr('aria-activedescendant');
+ }
+ });
};
Search.prototype.handleSearch = function (evt) {
@@ -4223,7 +4309,7 @@ S2.define('select2/dropdown/infiniteScroll',[
var $option = $(
'<li ' +
'class="select2-results__option select2-results__option--load-more"' +
- 'role="treeitem" aria-disabled="true"></li>'
+ 'role="option" aria-disabled="true"></li>'
);
var message = this.options.get('translations').get('loadingMore');
@@ -4241,7 +4327,7 @@ S2.define('select2/dropdown/attachBody',[
'../utils'
], function ($, Utils) {
function AttachBody (decorated, $element, options) {
- this.$dropdownParent = options.get('dropdownParent') || $(document.body);
+ this.$dropdownParent = $(options.get('dropdownParent') || document.body);
decorated.call(this, $element, options);
}
@@ -4249,27 +4335,14 @@ S2.define('select2/dropdown/attachBody',[
AttachBody.prototype.bind = function (decorated, container, $container) {
var self = this;
- var setupResultsEvents = false;
-
decorated.call(this, container, $container);
container.on('open', function () {
self._showDropdown();
self._attachPositioningHandler(container);
- if (!setupResultsEvents) {
- setupResultsEvents = true;
-
- container.on('results:all', function () {
- self._positionDropdown();
- self._resizeDropdown();
- });
-
- container.on('results:append', function () {
- self._positionDropdown();
- self._resizeDropdown();
- });
- }
+ // Must bind after the results handlers to ensure correct sizing
+ self._bindContainerResultHandlers(container);
});
container.on('close', function () {
@@ -4318,6 +4391,44 @@ S2.define('select2/dropdown/attachBody',[
this.$dropdownContainer.detach();
};
+ AttachBody.prototype._bindContainerResultHandlers =
+ function (decorated, container) {
+
+ // These should only be bound once
+ if (this._containerResultsHandlersBound) {
+ return;
+ }
+
+ var self = this;
+
+ container.on('results:all', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:append', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('results:message', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('select', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ container.on('unselect', function () {
+ self._positionDropdown();
+ self._resizeDropdown();
+ });
+
+ this._containerResultsHandlersBound = true;
+ };
+
AttachBody.prototype._attachPositioningHandler =
function (decorated, container) {
var self = this;
@@ -4403,7 +4514,17 @@ S2.define('select2/dropdown/attachBody',[
$offsetParent = $offsetParent.offsetParent();
}
- var parentOffset = $offsetParent.offset();
+ var parentOffset = {
+ top: 0,
+ left: 0
+ };
+
+ if (
+ $.contains(document.body, $offsetParent[0]) ||
+ $offsetParent[0].isConnected
+ ) {
+ parentOffset = $offsetParent.offset();
+ }
css.top -= parentOffset.top;
css.left -= parentOffset.left;
@@ -4868,66 +4989,29 @@ S2.define('select2/defaults',[
);
}
- if (typeof options.language === 'string') {
- // Check if the language is specified with a region
- if (options.language.indexOf('-') > 0) {
- // Extract the region information if it is included
- var languageParts = options.language.split('-');
- var baseLanguage = languageParts[0];
-
- options.language = [options.language, baseLanguage];
- } else {
- options.language = [options.language];
- }
- }
-
- if ($.isArray(options.language)) {
- var languages = new Translation();
- options.language.push('en');
+ // If the defaults were not previously applied from an element, it is
+ // possible for the language option to have not been resolved
+ options.language = this._resolveLanguage(options.language);
- var languageNames = options.language;
+ // Always fall back to English since it will always be complete
+ options.language.push('en');
- for (var l = 0; l < languageNames.length; l++) {
- var name = languageNames[l];
- var language = {};
-
- try {
- // Try to load it with the original name
- language = Translation.loadPath(name);
- } catch (e) {
- try {
- // If we couldn't load it, check if it wasn't the full path
- name = this.defaults.amdLanguageBase + name;
- language = Translation.loadPath(name);
- } catch (ex) {
- // The translation could not be loaded at all. Sometimes this is
- // because of a configuration problem, other times this can be
- // because of how Select2 helps load all possible translation files.
- if (options.debug && window.console && console.warn) {
- console.warn(
- 'Select2: The language file for "' + name + '" could not be ' +
- 'automatically loaded. A fallback will be used instead.'
- );
- }
+ var uniqueLanguages = [];
- continue;
- }
- }
+ for (var l = 0; l < options.language.length; l++) {
+ var language = options.language[l];
- languages.extend(language);
+ if (uniqueLanguages.indexOf(language) === -1) {
+ uniqueLanguages.push(language);
}
+ }
- options.translations = languages;
- } else {
- var baseTranslation = Translation.loadPath(
- this.defaults.amdLanguageBase + 'en'
- );
- var customTranslation = new Translation(options.language);
-
- customTranslation.extend(baseTranslation);
+ options.language = uniqueLanguages;
- options.translations = customTranslation;
- }
+ options.translations = this._processTranslations(
+ options.language,
+ options.debug
+ );
return options;
};
@@ -4994,7 +5078,7 @@ S2.define('select2/defaults',[
debug: false,
dropdownAutoWidth: false,
escapeMarkup: Utils.escapeMarkup,
- language: EnglishTranslation,
+ language: {},
matcher: matcher,
minimumInputLength: 0,
maximumInputLength: 0,
@@ -5016,6 +5100,103 @@ S2.define('select2/defaults',[
};
};
+ Defaults.prototype.applyFromElement = function (options, $element) {
+ var optionLanguage = options.language;
+ var defaultLanguage = this.defaults.language;
+ var elementLanguage = $element.prop('lang');
+ var parentLanguage = $element.closest('[lang]').prop('lang');
+
+ var languages = Array.prototype.concat.call(
+ this._resolveLanguage(elementLanguage),
+ this._resolveLanguage(optionLanguage),
+ this._resolveLanguage(defaultLanguage),
+ this._resolveLanguage(parentLanguage)
+ );
+
+ options.language = languages;
+
+ return options;
+ };
+
+ Defaults.prototype._resolveLanguage = function (language) {
+ if (!language) {
+ return [];
+ }
+
+ if ($.isEmptyObject(language)) {
+ return [];
+ }
+
+ if ($.isPlainObject(language)) {
+ return [language];
+ }
+
+ var languages;
+
+ if (!$.isArray(language)) {
+ languages = [language];
+ } else {
+ languages = language;
+ }
+
+ var resolvedLanguages = [];
+
+ for (var l = 0; l < languages.length; l++) {
+ resolvedLanguages.push(languages[l]);
+
+ if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) {
+ // Extract the region information if it is included
+ var languageParts = languages[l].split('-');
+ var baseLanguage = languageParts[0];
+
+ resolvedLanguages.push(baseLanguage);
+ }
+ }
+
+ return resolvedLanguages;
+ };
+
+ Defaults.prototype._processTranslations = function (languages, debug) {
+ var translations = new Translation();
+
+ for (var l = 0; l < languages.length; l++) {
+ var languageData = new Translation();
+
+ var language = languages[l];
+
+ if (typeof language === 'string') {
+ try {
+ // Try to load it with the original name
+ languageData = Translation.loadPath(language);
+ } catch (e) {
+ try {
+ // If we couldn't load it, check if it wasn't the full path
+ language = this.defaults.amdLanguageBase + language;
+ languageData = Translation.loadPath(language);
+ } catch (ex) {
+ // The translation could not be loaded at all. Sometimes this is
+ // because of a configuration problem, other times this can be
+ // because of how Select2 helps load all possible translation files
+ if (debug && window.console && console.warn) {
+ console.warn(
+ 'Select2: The language file for "' + language + '" could ' +
+ 'not be automatically loaded. A fallback will be used instead.'
+ );
+ }
+ }
+ }
+ } else if ($.isPlainObject(language)) {
+ languageData = new Translation(language);
+ } else {
+ languageData = language;
+ }
+
+ translations.extend(languageData);
+ }
+
+ return translations;
+ };
+
Defaults.prototype.set = function (key, value) {
var camelKey = $.camelCase(key);
@@ -5045,6 +5226,10 @@ S2.define('select2/options',[
this.fromElement($element);
}
+ if ($element != null) {
+ this.options = Defaults.applyFromElement(this.options, $element);
+ }
+
this.options = Defaults.apply(this.options);
if ($element && $element.is('input')) {
@@ -5068,14 +5253,6 @@ S2.define('select2/options',[
this.options.disabled = $e.prop('disabled');
}
- if (this.options.language == null) {
- if ($e.prop('lang')) {
- this.options.language = $e.prop('lang').toLowerCase();
- } else if ($e.closest('[lang]').prop('lang')) {
- this.options.language = $e.closest('[lang]').prop('lang');
- }
- }
-
if (this.options.dir == null) {
if ($e.prop('dir')) {
this.options.dir = $e.prop('dir');
@@ -5389,8 +5566,8 @@ S2.define('select2/core',[
if (observer != null) {
this._observer = new observer(function (mutations) {
- $.each(mutations, self._syncA);
- $.each(mutations, self._syncS);
+ self._syncA();
+ self._syncS(null, mutations);
});
this._observer.observe(this.$element[0], {
attributes: true,
@@ -5512,7 +5689,7 @@ S2.define('select2/core',[
if (self.isOpen()) {
if (key === KEYS.ESC || key === KEYS.TAB ||
(key === KEYS.UP && evt.altKey)) {
- self.close();
+ self.close(evt);
evt.preventDefault();
} else if (key === KEYS.ENTER) {
@@ -5546,7 +5723,7 @@ S2.define('select2/core',[
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
if (this.isOpen()) {
this.close();
}
@@ -5557,7 +5734,7 @@ S2.define('select2/core',[
}
};
- Select2.prototype._syncSubtree = function (evt, mutations) {
+ Select2.prototype._isChangeMutation = function (evt, mutations) {
var changed = false;
var self = this;
@@ -5585,7 +5762,22 @@ S2.define('select2/core',[
}
} else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
changed = true;
+ } else if ($.isArray(mutations)) {
+ $.each(mutations, function(evt, mutation) {
+ if (self._isChangeMutation(evt, mutation)) {
+ // We've found a change mutation.
+ // Let's escape from the loop and continue
+ changed = true;
+ return false;
+ }
+ });
}
+ return changed;
+ };
+
+ Select2.prototype._syncSubtree = function (evt, mutations) {
+ var changed = this._isChangeMutation(evt, mutations);
+ var self = this;
// Only re-pull the data if we think there is a change
if (changed) {
@@ -5636,7 +5828,7 @@ S2.define('select2/core',[
};
Select2.prototype.toggleDropdown = function () {
- if (this.options.get('disabled')) {
+ if (this.isDisabled()) {
return;
}
@@ -5652,15 +5844,40 @@ S2.define('select2/core',[
return;
}
+ if (this.isDisabled()) {
+ return;
+ }
+
this.trigger('query', {});
};
- Select2.prototype.close = function () {
+ Select2.prototype.close = function (evt) {
if (!this.isOpen()) {
return;
}
- this.trigger('close', {});
+ this.trigger('close', { originalEvent : evt });
+ };
+
+ /**
+ * Helper method to abstract the "enabled" (not "disabled") state of this
+ * object.
+ *
+ * @return {true} if the instance is not disabled.
+ * @return {false} if the instance is disabled.
+ */
+ Select2.prototype.isEnabled = function () {
+ return !this.isDisabled();
+ };
+
+ /**
+ * Helper method to abstract the "disabled" state of this object.
+ *
+ * @return {true} if the disabled option is true.
+ * @return {false} if the disabled option is false.
+ */
+ Select2.prototype.isDisabled = function () {
+ return this.options.get('disabled');
};
Select2.prototype.isOpen = function () {
@@ -5737,7 +5954,7 @@ S2.define('select2/core',[
});
}
- this.$element.val(newVal).trigger('change');
+ this.$element.val(newVal).trigger('input').trigger('change');
};
Select2.prototype.destroy = function () {
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.min.js b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.min.js
new file mode 100644
index 0000000..e421426
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/contrib/select2/select2.min.js
@@ -0,0 +1,2 @@
+/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
+!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(u){var e=function(){if(u&&u.fn&&u.fn.select2&&u.fn.select2.amd)var e=u.fn.select2.amd;var t,n,r,h,o,s,f,g,m,v,y,_,i,a,b;function w(e,t){return i.call(e,t)}function l(e,t){var n,r,i,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"] [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-select2.js b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-select2.js
index 86b7c95..07d0dce 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-select2.js
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-select2.js
@@ -274,9 +274,77 @@ Tobago.Select2.register('suppressMessages', (function() {
var Utils = jQuery.fn.select2.amd.require('select2/utils');
var resultAdapter = jQuery.fn.select2.amd.require('select2/results');
- return Utils.Decorate(resultAdapter, suppressMessages);
+ var selectOnClose = jQuery.fn.select2.amd.require('select2/dropdown/selectOnClose');
+ var adapter = Utils.Decorate(resultAdapter, selectOnClose);
+ return Utils.Decorate(adapter, suppressMessages);
})());
+
+Tobago.Select2.register('testDataAdapter', (function() {
+
+ var testDataAdapter = (function () {
+
+ function TestDataAdapter (decorated, $element, options) {
+ decorated.call(this, $element, options);
+ }
+
+ TestDataAdapter.prototype.query = function(decorated, params, callback) {
+ var select2Instance = this;
+
+ if (!select2Instance.$element.data("tttxt")) {
+ select2Instance.container.on("open", function (params) {
+ console.warn("TestDataAdapter.container.open");
+ if (!select2Instance.$search.val()) {
+ select2Instance.container.$results.empty();
+ }
+ });
+ select2Instance.$element.data("tttxt", true);
+ }
+
+ console.warn("TestDataAdapter.prototype.query");
+ callback({results: []});
+ function clearDuplicatesCallback(results) {
+ callback(results);
+
+ var values = [];
+ select2Instance.$element.find("option[data-select2-tag='true']").each(function () {
+ var option = jQuery(this);
+ if (values.includes(option.val())) {
+ option.detach();
+ } else {
+ values.push(option.val());
+ }
+ });
+ }
+ decorated.call(this, params, clearDuplicatesCallback);
+ };
+
+ return TestDataAdapter;
+ })();
+
+ var Utils = jQuery.fn.select2.amd.require('select2/utils');
+
+
+ var adapter = jQuery.fn.select2.amd.require('select2/data/ajax');
+
+
+ /*
+ {"tags":true,"tokenSeparators":[","],"language":"de","minimumInputLength":2,"placeholder":"Select countries"}'
+ */
+
+ adapter = Utils.Decorate(adapter, testDataAdapter);
+
+
+ adapter = Utils.Decorate(adapter, jQuery.fn.select2.amd.require('select2/data/minimumInputLength'));
+ adapter = Utils.Decorate(adapter, jQuery.fn.select2.amd.require('select2/data/tags'));
+ return Utils.Decorate(adapter, jQuery.fn.select2.amd.require('select2/data/tokenizer'));
+
+})());
+
+
+
+
+
Tobago.registerListener(Tobago.Select2.init, Tobago.Phase.DOCUMENT_READY);
Tobago.registerListener(Tobago.Select2.init, Tobago.Phase.AFTER_UPDATE);
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2-4.0.8.min.css b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2-4.0.8.min.css
deleted file mode 100644
index dc2315a..0000000
--- a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2-4.0.8.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single . [...]
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2-4.0.8.css b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2.css
similarity index 99%
rename from tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2-4.0.8.css
rename to tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2.css
index cd45ce8..750b320 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2-4.0.8.css
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2.css
@@ -193,7 +193,8 @@
float: right;
font-weight: bold;
margin-top: 5px;
- margin-right: 10px; }
+ margin-right: 10px;
+ padding: 1px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2.min.css b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2.min.css
new file mode 100644
index 0000000..7c18ad5
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/style/contrib/select2/select2.min.css
@@ -0,0 +1 @@
+.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single . [...]