Allows the PDF engine return the page index it is scrolling to

Chromium/PDFium behave differently from IE/Acrobat, when it
comes to the way some Javascript that scroll to a given
page index is handled.

For instance, lets assume a PDF file is showing its page
'0' and the following JS runs:

  this.pageNum = 1;
  app.alert(this.pageNum);

The output of the alert in IE/Acrobat is '1', whereas it is
'0' in Chromium/PDFium.
This happens because of the asynchronous way Chromium's PDF
plugin handles the "scroll to page X" request.

Also, a similar behavior difference is seen on other
Acrobat JS APIs, including Document::gotoNamedDest, where
the same code path is taken to scroll to a given page index.

CL adds an "optional" class member variable that
caches the page index the PDF is going to be scrolled
to, and allows the PDF plugin to return the target page
index even before the it has finished handling the scroll
request.

BUG=pdfium:492

Review-Url: https://codereview.chromium.org/2271263002
Cr-Commit-Position: refs/heads/master@{#414921}
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc
index 118a5ee5..fffb198 100644
--- a/pdf/pdfium/pdfium_engine.cc
+++ b/pdf/pdfium/pdfium_engine.cc
@@ -2283,6 +2283,9 @@
 }
 
 int PDFiumEngine::GetMostVisiblePage() {
+  if (in_flight_visible_page_)
+    return *in_flight_visible_page_;
+
   CalculateVisiblePages();
   return most_visible_page_;
 }
@@ -2677,6 +2680,11 @@
   return base::ContainsValue(visible_pages_, index);
 }
 
+void PDFiumEngine::ScrollToPage(int page) {
+  in_flight_visible_page_ = page;
+  client_->ScrollToPage(page);
+}
+
 bool PDFiumEngine::CheckPageAvailable(int index, std::vector<int>* pending) {
   if (!doc_ || !form_)
     return false;
@@ -3183,6 +3191,8 @@
 }
 
 void PDFiumEngine::SetCurrentPage(int index) {
+  in_flight_visible_page_.reset();
+
   if (index == most_visible_page_ || !form_)
     return;
 
@@ -3526,13 +3536,13 @@
   // Reader supports more, like FitWidth, but since they're not part of the spec
   // and we haven't got bugs about them, no need to now.
   if (action == "NextPage") {
-    engine->client_->ScrollToPage(index + 1);
+    engine->ScrollToPage(index + 1);
   } else if (action == "PrevPage") {
-    engine->client_->ScrollToPage(index - 1);
+    engine->ScrollToPage(index - 1);
   } else if (action == "FirstPage") {
-    engine->client_->ScrollToPage(0);
+    engine->ScrollToPage(0);
   } else if (action == "LastPage") {
-    engine->client_->ScrollToPage(engine->pages_.size() - 1);
+    engine->ScrollToPage(engine->pages_.size() - 1);
   }
 }
 
@@ -3556,7 +3566,7 @@
                                      float* position_array,
                                      int size_of_array) {
   PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
-  engine->client_->ScrollToPage(page_index);
+  engine->ScrollToPage(page_index);
 }
 
 int PDFiumEngine::Form_Alert(IPDF_JSPLATFORM* param,
@@ -3685,7 +3695,7 @@
 void PDFiumEngine::Form_GotoPage(IPDF_JSPLATFORM* param,
                                  int page_number) {
   PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
-  engine->client_->ScrollToPage(page_number);
+  engine->ScrollToPage(page_number);
 }
 
 int PDFiumEngine::Form_Browse(IPDF_JSPLATFORM* param,
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h
index 7f7d113..c7bf28e2 100644
--- a/pdf/pdfium/pdfium_engine.h
+++ b/pdf/pdfium/pdfium_engine.h
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "base/optional.h"
 #include "base/time/time.h"
 #include "pdf/document_loader.h"
 #include "pdf/pdf_engine.h"
@@ -249,6 +250,11 @@
   // must have been called first.
   bool IsPageVisible(int index) const;
 
+  // Internal interface that caches the page index requested by PDFium to get
+  // scrolled to. The cache is to be be used during the interval the PDF
+  // plugin has not finished handling the scroll request.
+  void ScrollToPage(int page);
+
   // Checks if a page is now available, and if so marks it as such and returns
   // true.  Otherwise, it will return false and will add the index to the given
   // array if it's not already there.
@@ -678,6 +684,10 @@
   // calling CalculateVisiblePages()
   int most_visible_page_;
 
+  // Holds the page index requested by PDFium while the scroll operation
+  // is being handled (asynchronously).
+  base::Optional<int> in_flight_visible_page_;
+
   // Set to true after FORM_DoDocumentJSAction/FORM_DoDocumentOpenAction have
   // been called. Only after that can we call FORM_DoPageAAction.
   bool called_do_document_action_;