1
0
mirror of synced 2024-11-29 08:06:03 +03:00

Switch back to late binding the positioning handlers

This is how it used to work pre-4.0.9, where the bound handlers for
resizing and positioning the dropdown were bound at the first time
that the dropdown was opened. This was changed for the 4.0.9 release
as a part of 3f75227a693 where it was not clear why this late binding
was happening, so it was removed to simplify the code.

The late binding is necessary because the handlers within results for
generating the results, and thus the content within the dropdown,
are bound after the handlers for the dropdown are bound. This results
in situations where the handlers for positioning the dropdown are
bound before the dropdown is updated with content, resulting in the
positioning being calculated for the old content and thus being
incorrectly placed. By binding the positioning handlers after the
dropdow is opened for the first time, we can ensure that the
positioning handlers are bound after the result handlers, so we
won't have to worry about this issue.

The handlers are only bound once because they only need to perform
all the calculations a single time. There is no need to keep checking
all of the calculated styles more than we need to, so this is guarded
by a flag which ensures it is only bound a single time per dropdown.

Fixes #5619
Fixes #5620
This commit is contained in:
Kevin Brown 2019-08-27 22:13:41 -04:00
parent d54560f21e
commit d8d2aa5b03

View File

@ -16,6 +16,9 @@ define([
container.on('open', function () { container.on('open', function () {
self._showDropdown(); self._showDropdown();
self._attachPositioningHandler(container); self._attachPositioningHandler(container);
// Must bind after the results handlers to ensure correct sizing
self._bindContainerResultHandlers(container);
}); });
container.on('close', function () { container.on('close', function () {
@ -23,31 +26,6 @@ define([
self._detachPositioningHandler(container); self._detachPositioningHandler(container);
}); });
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.$dropdownContainer.on('mousedown', function (evt) { this.$dropdownContainer.on('mousedown', function (evt) {
evt.stopPropagation(); evt.stopPropagation();
}); });
@ -89,6 +67,44 @@ define([
this.$dropdownContainer.detach(); 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 = AttachBody.prototype._attachPositioningHandler =
function (decorated, container) { function (decorated, container) {
var self = this; var self = this;