From 6be4921eaf5b1c5a51fa8f6aead8824ca9e632f9 Mon Sep 17 00:00:00 2001
From: Jonas Jenwald <jonas.jenwald@gmail.com>
Date: Mon, 1 Oct 2018 18:31:27 +0200
Subject: [PATCH] Make the clearing of find highlights, when closing the
 findbar, asynchronous

Since searching itself is an asynchronous operation, removal of highlights needs to be asynchronous too since otherwise there's a risk that the events happen in the wrong order and find highlights thus remain visible.

Also, this patch will now ensure that only 'findbarclose' events for the *current* document is handled since other ones doesn't really matter. Note in particular that when no document is loaded text-layers are, obviously, not present and subsequently it's unnecessary to attempt to hide non-existent find highlights.
---
 web/pdf_find_controller.js | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/web/pdf_find_controller.js b/web/pdf_find_controller.js
index c103da0ba..93b5d31d0 100644
--- a/web/pdf_find_controller.js
+++ b/web/pdf_find_controller.js
@@ -58,15 +58,7 @@ class PDFFindController {
     this._eventBus = eventBus;
 
     this._reset();
-
-    eventBus.on('findbarclose', () => {
-      this._highlightMatches = false;
-
-      eventBus.dispatch('updatetextlayermatches', {
-        source: this,
-        pageIndex: -1,
-      });
-    });
+    eventBus.on('findbarclose', this._onFindBarClose.bind(this));
 
     // Compile the regular expression for text normalization once.
     const replace = Object.keys(CHARACTERS_TO_NORMALIZE).join('');
@@ -556,6 +548,32 @@ class PDFFindController {
     }
   }
 
+  _onFindBarClose(evt) {
+    const pdfDocument = this._pdfDocument;
+    // Since searching is asynchronous, ensure that the removal of highlighted
+    // matches (from the UI) is async too such that the 'updatetextlayermatches'
+    // events will always be dispatched in the expected order.
+    this._firstPagePromise.then(() => {
+      if (!this._pdfDocument ||
+          (pdfDocument && this._pdfDocument !== pdfDocument)) {
+        // Only update the UI if the document is open, and is the current one.
+        return;
+      }
+      if (this._findTimeout) {
+        clearTimeout(this._findTimeout);
+        this._findTimeout = null;
+        // Avoid the UI being in a pending state if the findbar is re-opened.
+        this._updateUIState(FindState.FOUND);
+      }
+      this._highlightMatches = false;
+
+      this._eventBus.dispatch('updatetextlayermatches', {
+        source: this,
+        pageIndex: -1,
+      });
+    });
+  }
+
   _requestMatchesCount() {
     const { pageIdx, matchIdx, } = this._selected;
     let current = 0, total = this._matchesCountTotal;