Skip to content

Commit

Permalink
Inherted lang attribute should be below the default in the chain
Browse files Browse the repository at this point in the history
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 `<select>` element
2. The `data-language` attribute on the original `<select>` 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 `<select>` element

While this is a breaking change, we believe that this change will
have minimal to no impact on real-world usage of Select2, because
of how the `lang` attribute is generally used within documents.
We believe this will now make setting the default language through
JavaScript easier and more reliable, bringing it in line with how
we recommend it is done within the documentation.

This was implemented through a new method `Defaults.applyFromElement`
instead of within the old `Options.fromElement` method because it
relies on the global defaults object. While we could have reached
in to the internals in order to apply it appropriately, it made
more sense to handle the proper resolution through a single
consistent place.

This was not implemented in the `Defaults.apply` method because that
method is not typically passed in a reference to the original
`<select>` element that it is applying the options for.

Closes #5468
  • Loading branch information
kevin-brown committed Aug 4, 2019
1 parent 782c60a commit 4d391c7
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 10 deletions.
20 changes: 18 additions & 2 deletions src/js/select2/defaults.js
Expand Up @@ -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');

Expand Down Expand Up @@ -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 [];
Expand Down
12 changes: 4 additions & 8 deletions src/js/select2/options.js
Expand Up @@ -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')) {
Expand All @@ -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');
Expand Down

0 comments on commit 4d391c7

Please sign in to comment.