There was a plan to universally use an array as the return from
query methods, but now that we've realized pagination and extra
things are impossible without it, we're going back to the return
object. Anyone looking to migrate their data should be returning
an object with the key `results` containing what they previously
returned.
This should fix https://github.com/select2/select2/issues/2898
Now that the data objects have the `element` property, we can test
to make sure it's a DOM element and then use it for selecting the
option. This allows us to select multiple options with the same id,
as well as handle cases where that is already happening.
You cannot use `$e.val()` to select two options with the same id,
as jQuery will reject it, but you can set the second option to
`.selected = true`, which is supported.
This improves the speeds of creating the `<option>` tags for array
data. By creating the HTML ahead of time and putting it into an
`<option>` element before passing it to jQuery, it cuts down on the
time it takes for jQuery to process the HTML string and convert it
into DOM elements. This proved to be incredibly slow.
This also changes the `item` function to return early when the
data exists. The `$e.data` call has also been switched to a
`$.data` call, which doesn't need to check the DOM to see if the
data attributes already exist. This cuts down on a bit of wasted
time, as the `data` key should never be present in the DOM, and it
should be ignored if it is.
We should only be checking the option values that matter, such as
`id` and `text`, instead of checking all of the option values. This
will prevent unexpected breaking when new properties are added to
the options.
Existing properties should be covered by tests to avoid regressions.
We have to enforce ids being strings as the values of options within
a select will always be an id. This fixes an issue that we had with
array selections not being highlighted in the results.