Add |auto_cancel| parameter to WebContents::DispatchBeforeUnload.

This exposes a parameter on WebContents::DispatchBeforeUnload which causes
the beforeunload dialog to automatically cancel itself if the beforeunload
handler returns a non-empty string.

This also adds plumbing to expose the value of |proceed| to the existing
WebContentsObserver::BeforeUnloadFired.

A follow-up CL will use these changes in order to create a "beforeunload"
helper to determine whether or not a page contains unsaved user data, and
is therefore unsafe for proactive discarding.

BUG=877550

Change-Id: I3d7b09709985656dc48bbbf408f8b2bdf87b186c
Reviewed-on: https://chromium-review.googlesource.com/1220307
Commit-Queue: Chris Hamilton <[email protected]>
Reviewed-by: Dmitry Gozman <[email protected]>
Reviewed-by: Scott Violet <[email protected]>
Reviewed-by: Egor Pasko <[email protected]>
Reviewed-by: Alex Moshchuk <[email protected]>
Cr-Commit-Position: refs/heads/master@{#592378}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 386454d..0365df2a 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1733,9 +1733,11 @@
       true /* check_subframes_only */);
 }
 
-void WebContentsImpl::DispatchBeforeUnload() {
-  GetMainFrame()->DispatchBeforeUnload(
-      RenderFrameHostImpl::BeforeUnloadType::TAB_CLOSE, false);
+void WebContentsImpl::DispatchBeforeUnload(bool auto_cancel) {
+  auto before_unload_type =
+      auto_cancel ? RenderFrameHostImpl::BeforeUnloadType::DISCARD
+                  : RenderFrameHostImpl::BeforeUnloadType::TAB_CLOSE;
+  GetMainFrame()->DispatchBeforeUnload(before_unload_type, false);
 }
 
 void WebContentsImpl::AttachToOuterWebContentsFrame(
@@ -5965,7 +5967,7 @@
     bool proceed, const base::TimeTicks& proceed_time,
     bool* proceed_to_fire_unload) {
   for (auto& observer : observers_)
-    observer.BeforeUnloadFired(proceed_time);
+    observer.BeforeUnloadFired(proceed, proceed_time);
   if (delegate_)
     delegate_->BeforeUnloadFired(this, proceed, proceed_to_fire_unload);
   // Note: |this| might be deleted at this point.