mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 03:16:41 +08:00
FIX: Upgrade Select2 widget - fixes focus on mobile
This commit is contained in:
parent
6eb83a3d00
commit
05849d2afb
306
vendor/assets/javascripts/select2.js
vendored
306
vendor/assets/javascripts/select2.js
vendored
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright 2012 Igor Vaynberg
|
||||
|
||||
Version: 3.5.2 Timestamp: Sat Nov 1 14:43:36 EDT 2014
|
||||
Version: 3.5.4 Timestamp: Sun Aug 30 13:30:32 EDT 2015
|
||||
|
||||
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
|
||||
General Public License version 2 (the "GPL License"). You may choose either license to govern your
|
||||
|
@ -814,7 +814,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
// focusin can cause focus wars between modals and select2 since the dropdown is outside the modal.
|
||||
this.dropdown.on("click mouseup mousedown touchstart touchend focusin", function (e) { e.stopPropagation(); });
|
||||
|
||||
this.nextSearchTerm = undefined;
|
||||
this.lastSearchTerm = undefined;
|
||||
|
||||
if ($.isFunction(this.opts.initSelection)) {
|
||||
// initialize selection based on the current value of the source element
|
||||
|
@ -870,17 +870,21 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
select2.container.remove();
|
||||
select2.liveRegion.remove();
|
||||
select2.dropdown.remove();
|
||||
element
|
||||
.show()
|
||||
.removeData("select2")
|
||||
.off(".select2")
|
||||
.prop("autofocus", this.autofocus || false);
|
||||
if (this.elementTabIndex) {
|
||||
element.attr({tabindex: this.elementTabIndex});
|
||||
element.removeData("select2")
|
||||
.off(".select2");
|
||||
if (!element.is("input[type='hidden']")) {
|
||||
element
|
||||
.show()
|
||||
.prop("autofocus", this.autofocus || false);
|
||||
if (this.elementTabIndex) {
|
||||
element.attr({tabindex: this.elementTabIndex});
|
||||
} else {
|
||||
element.removeAttr("tabindex");
|
||||
}
|
||||
element.show();
|
||||
} else {
|
||||
element.removeAttr("tabindex");
|
||||
element.css("display", "");
|
||||
}
|
||||
element.show();
|
||||
}
|
||||
|
||||
cleanupJQueryElements.call(this,
|
||||
|
@ -932,6 +936,155 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
});
|
||||
}
|
||||
|
||||
opts.debug = opts.debug || $.fn.select2.defaults.debug;
|
||||
|
||||
// Warnings for options renamed/removed in Select2 4.0.0
|
||||
// Only when it's enabled through debug mode
|
||||
if (opts.debug && console && console.warn) {
|
||||
// id was removed
|
||||
if (opts.id != null) {
|
||||
console.warn(
|
||||
'Select2: The `id` option has been removed in Select2 4.0.0, ' +
|
||||
'consider renaming your `id` property or mapping the property before your data makes it to Select2. ' +
|
||||
'You can read more at https://select2.github.io/announcements-4.0.html#changed-id'
|
||||
);
|
||||
}
|
||||
|
||||
// text was removed
|
||||
if (opts.text != null) {
|
||||
console.warn(
|
||||
'Select2: The `text` option has been removed in Select2 4.0.0, ' +
|
||||
'consider renaming your `text` property or mapping the property before your data makes it to Select2. ' +
|
||||
'You can read more at https://select2.github.io/announcements-4.0.html#changed-id'
|
||||
);
|
||||
}
|
||||
|
||||
// sortResults was renamed to results
|
||||
if (opts.sortResults != null) {
|
||||
console.warn(
|
||||
'Select2: the `sortResults` option has been renamed to `sorter` in Select2 4.0.0. '
|
||||
);
|
||||
}
|
||||
|
||||
// selectOnBlur was renamed to selectOnClose
|
||||
if (opts.selectOnBlur != null) {
|
||||
console.warn(
|
||||
'Select2: The `selectOnBlur` option has been renamed to `selectOnClose` in Select2 4.0.0.'
|
||||
);
|
||||
}
|
||||
|
||||
// ajax.results was renamed to ajax.processResults
|
||||
if (opts.ajax != null && opts.ajax.results != null) {
|
||||
console.warn(
|
||||
'Select2: The `ajax.results` option has been renamed to `ajax.processResults` in Select2 4.0.0.'
|
||||
);
|
||||
}
|
||||
|
||||
// format* options were renamed to language.*
|
||||
if (opts.formatNoResults != null) {
|
||||
console.warn(
|
||||
'Select2: The `formatNoResults` option has been renamed to `language.noResults` in Select2 4.0.0.'
|
||||
);
|
||||
}
|
||||
if (opts.formatSearching != null) {
|
||||
console.warn(
|
||||
'Select2: The `formatSearching` option has been renamed to `language.searching` in Select2 4.0.0.'
|
||||
);
|
||||
}
|
||||
if (opts.formatInputTooShort != null) {
|
||||
console.warn(
|
||||
'Select2: The `formatInputTooShort` option has been renamed to `language.inputTooShort` in Select2 4.0.0.'
|
||||
);
|
||||
}
|
||||
if (opts.formatInputTooLong != null) {
|
||||
console.warn(
|
||||
'Select2: The `formatInputTooLong` option has been renamed to `language.inputTooLong` in Select2 4.0.0.'
|
||||
);
|
||||
}
|
||||
if (opts.formatLoading != null) {
|
||||
console.warn(
|
||||
'Select2: The `formatLoading` option has been renamed to `language.loadingMore` in Select2 4.0.0.'
|
||||
);
|
||||
}
|
||||
if (opts.formatSelectionTooBig != null) {
|
||||
console.warn(
|
||||
'Select2: The `formatSelectionTooBig` option has been renamed to `language.maximumSelected` in Select2 4.0.0.'
|
||||
);
|
||||
}
|
||||
|
||||
if (opts.element.data('select2Tags')) {
|
||||
console.warn(
|
||||
'Select2: The `data-select2-tags` attribute has been renamed to `data-tags` in Select2 4.0.0.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Aliasing options renamed in Select2 4.0.0
|
||||
|
||||
// data-select2-tags -> data-tags
|
||||
if (opts.element.data('tags') != null) {
|
||||
var elemTags = opts.element.data('tags');
|
||||
|
||||
// data-tags should actually be a boolean
|
||||
if (!$.isArray(elemTags)) {
|
||||
elemTags = [];
|
||||
}
|
||||
|
||||
opts.element.data('select2Tags', elemTags);
|
||||
}
|
||||
|
||||
// sortResults -> sorter
|
||||
if (opts.sorter != null) {
|
||||
opts.sortResults = opts.sorter;
|
||||
}
|
||||
|
||||
// selectOnBlur -> selectOnClose
|
||||
if (opts.selectOnClose != null) {
|
||||
opts.selectOnBlur = opts.selectOnClose;
|
||||
}
|
||||
|
||||
// ajax.results -> ajax.processResults
|
||||
if (opts.ajax != null) {
|
||||
if ($.isFunction(opts.ajax.processResults)) {
|
||||
opts.ajax.results = opts.ajax.processResults;
|
||||
}
|
||||
}
|
||||
|
||||
// Formatters/language options
|
||||
if (opts.language != null) {
|
||||
var lang = opts.language;
|
||||
|
||||
// formatNoMatches -> language.noMatches
|
||||
if ($.isFunction(lang.noMatches)) {
|
||||
opts.formatNoMatches = lang.noMatches;
|
||||
}
|
||||
|
||||
// formatSearching -> language.searching
|
||||
if ($.isFunction(lang.searching)) {
|
||||
opts.formatSearching = lang.searching;
|
||||
}
|
||||
|
||||
// formatInputTooShort -> language.inputTooShort
|
||||
if ($.isFunction(lang.inputTooShort)) {
|
||||
opts.formatInputTooShort = lang.inputTooShort;
|
||||
}
|
||||
|
||||
// formatInputTooLong -> language.inputTooLong
|
||||
if ($.isFunction(lang.inputTooLong)) {
|
||||
opts.formatInputTooLong = lang.inputTooLong;
|
||||
}
|
||||
|
||||
// formatLoading -> language.loadingMore
|
||||
if ($.isFunction(lang.loadingMore)) {
|
||||
opts.formatLoading = lang.loadingMore;
|
||||
}
|
||||
|
||||
// formatSelectionTooBig -> language.maximumSelected
|
||||
if ($.isFunction(lang.maximumSelected)) {
|
||||
opts.formatSelectionTooBig = lang.maximumSelected;
|
||||
}
|
||||
}
|
||||
|
||||
opts = $.extend({}, {
|
||||
populateResults: function(container, results, query) {
|
||||
var populate, id=this.opts.id, liveRegion=this.liveRegion;
|
||||
|
@ -975,7 +1128,6 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
|
||||
if (compound) {
|
||||
|
||||
innerContainer=$("<ul></ul>");
|
||||
innerContainer.addClass("select2-result-sub");
|
||||
populate(result.children, innerContainer, depth+1);
|
||||
|
@ -1046,7 +1198,6 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
opts.id=function(e) { return e.id; };
|
||||
} else {
|
||||
if (!("query" in opts)) {
|
||||
|
||||
if ("ajax" in opts) {
|
||||
ajaxUrl = opts.element.data("ajax-url");
|
||||
if (ajaxUrl && ajaxUrl.length > 0) {
|
||||
|
@ -1325,10 +1476,11 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
};
|
||||
|
||||
if (above) {
|
||||
css.top = offset.top - dropHeight;
|
||||
css.bottom = 'auto';
|
||||
this.container.addClass("select2-drop-above");
|
||||
$dropdown.addClass("select2-drop-above");
|
||||
dropHeight = $dropdown.outerHeight(false);
|
||||
css.top = offset.top - dropHeight;
|
||||
css.bottom = 'auto';
|
||||
}
|
||||
else {
|
||||
css.top = dropTop;
|
||||
|
@ -1481,6 +1633,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
this.clearSearch();
|
||||
this.search.removeClass("select2-active");
|
||||
|
||||
// Remove the aria active descendant for highlighted element
|
||||
this.search.removeAttr("aria-activedescendant");
|
||||
this.opts.element.trigger($.Event("select2-close"));
|
||||
},
|
||||
|
||||
|
@ -1499,6 +1654,27 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {Boolean} Whether or not search value was changed.
|
||||
* @private
|
||||
*/
|
||||
prefillNextSearchTerm: function () {
|
||||
// initializes search's value with nextSearchTerm (if defined by user)
|
||||
// ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
|
||||
if(this.search.val() !== "") {
|
||||
return false;
|
||||
}
|
||||
|
||||
var nextSearchTerm = this.opts.nextSearchTerm(this.data(), this.lastSearchTerm);
|
||||
if(nextSearchTerm !== undefined){
|
||||
this.search.val(nextSearchTerm);
|
||||
this.search.select();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
//abstract
|
||||
getMaximumSelectionSize: function() {
|
||||
return evaluate(this.opts.maximumSelectionSize, this.opts.element);
|
||||
|
@ -1812,6 +1988,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) {
|
||||
render("<li class='select2-no-results'>" + evaluate(opts.formatNoMatches, opts.element, search.val()) + "</li>");
|
||||
if(this.showSearch){
|
||||
this.showSearch(search.val());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1916,7 +2095,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
} else if (this.opts.width === "copy" || this.opts.width === "resolve") {
|
||||
// check if there is inline style on the element that contains width
|
||||
style = this.opts.element.attr('style');
|
||||
if (style !== undefined) {
|
||||
if (typeof(style) === "string") {
|
||||
attrs = style.split(';');
|
||||
for (i = 0, l = attrs.length; i < l; i = i + 1) {
|
||||
attr = attrs[i].replace(/\s/g, '');
|
||||
|
@ -2015,14 +2194,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
}
|
||||
}
|
||||
|
||||
// initializes search's value with nextSearchTerm (if defined by user)
|
||||
// ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
|
||||
if(this.search.val() === "") {
|
||||
if(this.nextSearchTerm != undefined){
|
||||
this.search.val(this.nextSearchTerm);
|
||||
this.search.select();
|
||||
}
|
||||
}
|
||||
this.prefillNextSearchTerm();
|
||||
|
||||
this.focusser.prop("disabled", true).val("");
|
||||
this.updateResults(true);
|
||||
|
@ -2109,7 +2281,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
this.focusser.attr("id", "s2id_autogen"+idSuffix);
|
||||
|
||||
elementLabel = $("label[for='" + this.opts.element.attr("id") + "']");
|
||||
this.opts.element.focus(this.bind(function () { this.focus(); }));
|
||||
this.opts.element.on('focus.select2', this.bind(function () { this.focus(); }));
|
||||
|
||||
this.focusser.prev()
|
||||
.text(elementLabel.text())
|
||||
|
@ -2165,7 +2337,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
// without this the search field loses focus which is annoying
|
||||
if (document.activeElement === this.body.get(0)) {
|
||||
window.setTimeout(this.bind(function() {
|
||||
if (this.opened()) {
|
||||
if (this.opened() && this.results && this.results.length > 1) {
|
||||
this.search.focus();
|
||||
}
|
||||
}), 0);
|
||||
|
@ -2317,7 +2489,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
self.updateSelection(selected);
|
||||
self.close();
|
||||
self.setPlaceholder();
|
||||
self.nextSearchTerm = self.opts.nextSearchTerm(selected, self.search.val());
|
||||
self.lastSearchTerm = self.search.val();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -2454,7 +2626,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
this.opts.element.trigger({ type: "select2-selected", val: this.id(data), choice: data });
|
||||
|
||||
this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
|
||||
this.lastSearchTerm = this.search.val();
|
||||
this.close();
|
||||
|
||||
if ((!options || !options.noFocus) && this.opts.shouldFocusInput(this)) {
|
||||
|
@ -2508,9 +2680,23 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
if (arguments.length > 1) {
|
||||
triggerChange = arguments[1];
|
||||
|
||||
if (this.opts.debug && console && console.warn) {
|
||||
console.warn(
|
||||
'Select2: The second option to `select2("val")` is not supported in Select2 4.0.0. ' +
|
||||
'The `change` event will always be triggered in 4.0.0.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.select) {
|
||||
if (this.opts.debug && console && console.warn) {
|
||||
console.warn(
|
||||
'Select2: Setting the value on a <select> using `select2("val")` is no longer supported in 4.0.0. ' +
|
||||
'You can use the `.val(newValue).trigger("change")` method provided by jQuery instead.'
|
||||
);
|
||||
}
|
||||
|
||||
this.select
|
||||
.val(val)
|
||||
.find("option").filter(function() { return this.selected }).each2(function (i, elm) {
|
||||
|
@ -2559,6 +2745,13 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
if (data == undefined) data = null;
|
||||
return data;
|
||||
} else {
|
||||
if (this.opts.debug && console && console.warn) {
|
||||
console.warn(
|
||||
'Select2: The `select2("data")` method can no longer set selected values in 4.0.0, ' +
|
||||
'consider using the `.val()` method instead.'
|
||||
);
|
||||
}
|
||||
|
||||
if (arguments.length > 1) {
|
||||
triggerChange = arguments[1];
|
||||
}
|
||||
|
@ -2704,7 +2897,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
this.search.prev()
|
||||
.text($("label[for='" + this.opts.element.attr("id") + "']").text())
|
||||
.attr('for', this.search.attr('id'));
|
||||
this.opts.element.focus(this.bind(function () { this.focus(); }));
|
||||
this.opts.element.on('focus.select2', this.bind(function () { this.focus(); }));
|
||||
|
||||
this.search.on("input paste", this.bind(function() {
|
||||
if (this.search.attr('placeholder') && this.search.val().length == 0) return;
|
||||
|
@ -2922,16 +3115,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
this.focusSearch();
|
||||
|
||||
// initializes search's value with nextSearchTerm (if defined by user)
|
||||
// ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
|
||||
if(this.search.val() === "") {
|
||||
if(this.nextSearchTerm != undefined){
|
||||
this.search.val(this.nextSearchTerm);
|
||||
this.search.select();
|
||||
}
|
||||
}
|
||||
|
||||
this.prefillNextSearchTerm();
|
||||
this.updateResults(true);
|
||||
|
||||
if (this.opts.shouldFocusInput(this)) {
|
||||
this.search.focus();
|
||||
}
|
||||
|
@ -2957,21 +3143,18 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
// multi
|
||||
updateSelection: function (data) {
|
||||
var ids = [], filtered = [], self = this;
|
||||
var ids = {}, filtered = [], self = this;
|
||||
|
||||
// filter out duplicates
|
||||
$(data).each(function () {
|
||||
if (indexOf(self.id(this), ids) < 0) {
|
||||
ids.push(self.id(this));
|
||||
if (!(self.id(this) in ids)) {
|
||||
ids[self.id(this)] = 0;
|
||||
filtered.push(this);
|
||||
}
|
||||
});
|
||||
data = filtered;
|
||||
|
||||
this.selection.find(".select2-search-choice").remove();
|
||||
$(data).each(function () {
|
||||
self.addSelectedChoice(this);
|
||||
});
|
||||
this.addSelectedChoice(filtered);
|
||||
self.postprocessResults();
|
||||
},
|
||||
|
||||
|
@ -2998,7 +3181,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
|
||||
|
||||
// keep track of the search's value before it gets cleared
|
||||
this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
|
||||
this.lastSearchTerm = this.search.val();
|
||||
|
||||
this.clearSearch();
|
||||
this.updateResults();
|
||||
|
@ -3018,10 +3201,8 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
this.updateResults(true);
|
||||
} else {
|
||||
// initializes search's value with nextSearchTerm and update search result
|
||||
if(this.nextSearchTerm != undefined){
|
||||
this.search.val(this.nextSearchTerm);
|
||||
if (this.prefillNextSearchTerm()) {
|
||||
this.updateResults();
|
||||
this.search.select();
|
||||
}
|
||||
}
|
||||
this.positionDropdown();
|
||||
|
@ -3047,6 +3228,14 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
},
|
||||
|
||||
addSelectedChoice: function (data) {
|
||||
var val = this.getVal(), self = this;
|
||||
$(data).each(function () {
|
||||
val.push(self.createChoice(this));
|
||||
});
|
||||
this.setVal(val);
|
||||
},
|
||||
|
||||
createChoice: function (data) {
|
||||
var enableChoice = !data.locked,
|
||||
enabledItem = $(
|
||||
"<li class='select2-search-choice'>" +
|
||||
|
@ -3059,7 +3248,6 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
"</li>");
|
||||
var choice = enableChoice ? enabledItem : disabledItem,
|
||||
id = this.id(data),
|
||||
val = this.getVal(),
|
||||
formatted,
|
||||
cssClass;
|
||||
|
||||
|
@ -3093,8 +3281,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
choice.data("select2-data", data);
|
||||
choice.insertBefore(this.searchContainer);
|
||||
|
||||
val.push(id);
|
||||
this.setVal(val);
|
||||
return id;
|
||||
},
|
||||
|
||||
// multi
|
||||
|
@ -3226,14 +3413,16 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
// multi
|
||||
setVal: function (val) {
|
||||
var unique;
|
||||
if (this.select) {
|
||||
this.select.val(val);
|
||||
} else {
|
||||
unique = [];
|
||||
var unique = [], valMap = {};
|
||||
// filter out duplicates
|
||||
$(val).each(function () {
|
||||
if (indexOf(this, unique) < 0) unique.push(this);
|
||||
if (!(this in valMap)) {
|
||||
unique.push(this);
|
||||
valMap[this] = 0;
|
||||
}
|
||||
});
|
||||
this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator));
|
||||
}
|
||||
|
@ -3249,11 +3438,9 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
for (var j = 0; j < old.length; j++) {
|
||||
if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) {
|
||||
current.splice(i, 1);
|
||||
if(i>0){
|
||||
i--;
|
||||
}
|
||||
i--;
|
||||
old.splice(j, 1);
|
||||
j--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3423,6 +3610,7 @@ the specific language governing permissions and limitations under the Apache Lic
|
|||
|
||||
// plugin defaults, accessible to users
|
||||
$.fn.select2.defaults = {
|
||||
debug: false,
|
||||
width: "copy",
|
||||
loadMorePadding: 0,
|
||||
closeOnSelect: true,
|
||||
|
|
Loading…
Reference in New Issue
Block a user