From 4d391c70132227bda7ad1175634587689eb8ad6e Mon Sep 17 00:00:00 2001 From: Kevin Brown Date: Sun, 4 Aug 2019 00:42:06 -0400 Subject: [PATCH] Inherted `lang` attribute should be below the default in the chain It was pointed out in #5468 that the `lang` attribute, when inherited from a parent element, was above the option set in the global default within the inheritance chain. While this makes sense because of how we inherit other properties, it does not make sense for the `lang` attribute. The inheritance chain for the `language` option has been adjusted to be the following: 1. The `lang` attribute on the original `` element (because of how `data-*` attribute resolution affects options) 3. The `language` option specified when initiailizing Select2 4. The `language` Select2 default 5. The `lang` attribute on a parent of the `` element that it is applying the options for. Closes #5468 --- src/js/select2/defaults.js | 20 ++++++++++++++++++-- src/js/select2/options.js | 12 ++++-------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/js/select2/defaults.js b/src/js/select2/defaults.js index b0de0d1733..7f3bc3c6f1 100644 --- a/src/js/select2/defaults.js +++ b/src/js/select2/defaults.js @@ -232,8 +232,6 @@ define([ ); } - options.language = this._resolveLanguage(options.language); - // Always fall back to English since it will always be complete options.language.push('en'); @@ -341,6 +339,24 @@ define([ }; }; + 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 []; diff --git a/src/js/select2/options.js b/src/js/select2/options.js index 8e0dc07efe..b3d67cee1c 100644 --- a/src/js/select2/options.js +++ b/src/js/select2/options.js @@ -11,6 +11,10 @@ define([ this.fromElement($element); } + if ($element != null) { + this.options = Defaults.applyFromElement(this.options, $element); + } + this.options = Defaults.apply(this.options); if ($element && $element.is('input')) { @@ -34,14 +38,6 @@ define([ 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');