Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit ca59748

Browse files
author
Narciso Jaramillo
committed
Update scroll pos/selection synchronously after ModalBar.close() starts rather than on a timeout
1 parent 362c2d7 commit ca59748

2 files changed

Lines changed: 30 additions & 19 deletions

File tree

src/search/QuickOpen.js

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -385,20 +385,8 @@ define(function (require, exports, module) {
385385
var self = this;
386386
setTimeout(function () {
387387
if (e.keyCode === KeyEvent.DOM_VK_ESCAPE) {
388-
self.close();
389-
390-
// This is tricky. We want to restore the original selection, and we don't actually want to wait
391-
// until the modal bar has fully animated closed. However, we do need to wait until the next
392-
// event loop after ModalBar.close() has (synchronously) finished, because ModalBar.close() itself
393-
// tries to rescroll the editor (in order to restore the *apparent* scroll position that gets
394-
// changed when the ModalBar pushes the editor down). So we do this on yet another timeout.
395-
setTimeout(function () {
396-
// Restore original selection / scroll pos
397-
if (self._origSelection) {
398-
EditorManager.getCurrentFullEditor().setSelection(self._origSelection.start, self._origSelection.end);
399-
EditorManager.getCurrentFullEditor().setScrollPos(self._origScrollPos.x, self._origScrollPos.y);
400-
}
401-
}, 0);
388+
// Restore original selection / scroll pos
389+
self.close(self._origScrollPos, self._origSelection);
402390
} else if (e.keyCode === KeyEvent.DOM_VK_RETURN) {
403391
self._handleItemSelect(null, $(".smart_autocomplete_highlight").get(0)); // calls close() too
404392
}
@@ -452,9 +440,13 @@ define(function (require, exports, module) {
452440
/**
453441
* Closes the search dialog and notifies all quick open plugins that
454442
* searching is done.
443+
* @param {{x: number, y: number}=} scrollPos If specified, scroll to the given
444+
* position when closing the ModalBar.
445+
* @param {{start: {line: number, ch: number}, end: {line: number, ch: number}} selection If specified,
446+
* restore the given selection when closing the ModalBar.
455447
* @return {$.Promise} Resolved when the search bar is entirely closed.
456448
*/
457-
QuickNavigateDialog.prototype.close = function () {
449+
QuickNavigateDialog.prototype.close = function (scrollPos, selection) {
458450
if (!this.isOpen) {
459451
return this._closeDeferred.promise();
460452
}
@@ -481,9 +473,20 @@ define(function (require, exports, module) {
481473
// So we wait until after this call chain is complete before actually closing the dialog.
482474
var self = this;
483475
setTimeout(function () {
484-
self.modalBar.close().done(function () {
476+
self.modalBar.close(!scrollPos).done(function () {
485477
self._closeDeferred.resolve();
486478
});
479+
480+
// Note that we deliberately reset the scroll position synchronously on return from
481+
// `ModalBar.close()` (before the animation completes).
482+
// See description of `restoreScrollPos` in `ModalBar.close()`.
483+
var editor = EditorManager.getCurrentFullEditor();
484+
if (selection) {
485+
editor.setSelection(selection.start, selection.end);
486+
}
487+
if (scrollPos) {
488+
editor.setScrollPos(scrollPos.x, scrollPos.y);
489+
}
487490
}, 0);
488491

489492
$(".smart_autocomplete_container").remove();

src/widgets/ModalBar.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,17 @@ define(function (require, exports, module) {
120120
/**
121121
* Closes the modal bar and returns focus to the active editor. Returns a promise that is
122122
* resolved when the bar is fully closed and the container is removed from the DOM.
123+
* @param {boolean=} restoreScrollPos If true (the default), adjust the scroll position
124+
* of the editor to account for the ModalBar disappearing. If not set, the caller
125+
* should do it immediately on return of this function (before the animation completes),
126+
* because the editor will already have been resized.
123127
* @return {$.Promise} promise resolved when close is finished
124128
*/
125-
ModalBar.prototype.close = function () {
129+
ModalBar.prototype.close = function (restoreScrollPos) {
130+
if (restoreScrollPos === undefined) {
131+
restoreScrollPos = true;
132+
}
133+
126134
// Store our height before closing, while we can still measure it
127135
var result = new $.Deferred(),
128136
barHeight = this.height();
@@ -141,11 +149,11 @@ define(function (require, exports, module) {
141149
// height of the modal bar so the code doesn't appear to shift if possible.
142150
var fullEditor = EditorManager.getCurrentFullEditor(),
143151
scrollPos;
144-
if (fullEditor) {
152+
if (restoreScrollPos && fullEditor) {
145153
scrollPos = fullEditor.getScrollPos();
146154
}
147155
EditorManager.resizeEditor();
148-
if (fullEditor) {
156+
if (restoreScrollPos && fullEditor) {
149157
fullEditor._codeMirror.scrollTo(scrollPos.x, scrollPos.y - barHeight);
150158
}
151159
EditorManager.focusEditor();

0 commit comments

Comments
 (0)