Chromium Code Reviews| Index: chrome/browser/extensions/api/web_navigation/web_navigation_api.cc |
| diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc |
| index 6d45ec5856295bb365085ebcbf3cdc14a43bc81d..946868aedc97667b27cb110d1fdec0eec400ee52 100644 |
| --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc |
| +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc |
| @@ -271,11 +271,34 @@ void WebNavigationTabObserver::DidStartNavigation( |
| return; |
| } |
| - helpers::DispatchOnBeforeNavigate(navigation_handle); |
| + pending_on_before_navigate_event_ = |
| + helpers::CreateOnBeforeNavigateEvent(navigation_handle); |
| + |
| + // Only dispatch the onBeforeNavigate event if the associated WebContents |
| + // is already added to the tab strip. Otherwise the event should be delayed |
| + // and sent after the addition, to preserve the ordering of events. |
| + // |
| + // TODO(nasko|devlin): This check is necessary because chrome::Navigate() |
| + // begins the navigation before the sending the TAB_ADDED notification, and it |
| + // is used an indication of that. It would be best if instead it was known |
| + // when the tab was created and immediately sent the created event instead of |
| + // waiting for the later TAB_ADDED notification, but this appears to work for |
| + // now. |
| + if (ExtensionTabUtil::GetTabById(ExtensionTabUtil::GetTabId(web_contents()), |
| + web_contents()->GetBrowserContext(), false, |
| + nullptr, nullptr, nullptr, nullptr)) { |
| + DispatchCachedOnBeforeNavigate(); |
| + } |
| } |
| void WebNavigationTabObserver::DidFinishNavigation( |
| content::NavigationHandle* navigation_handle) { |
| + // If there has been a DidStartNavigation call before the tab was ready to |
| + // dispatch events, ensure that it is sent before processing the |
| + // DidFinishNavigation. |
| + // Note: This is exercised by WebNavigationApiTest.TargetBlankIncognito. |
| + DispatchCachedOnBeforeNavigate(); |
| + |
| if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) { |
| HandleCommit(navigation_handle); |
| return; |
| @@ -391,6 +414,14 @@ void WebNavigationTabObserver::WebContentsDestroyed() { |
| registrar_.RemoveAll(); |
| } |
| +void WebNavigationTabObserver::DispatchCachedOnBeforeNavigate() { |
| + if (!pending_on_before_navigate_event_.get()) |
|
alexmos
2016/12/03 00:03:46
nit: .get() is not needed
nasko
2016/12/03 00:19:03
Done.
|
| + return; |
| + |
| + EventRouter::Get(web_contents()->GetBrowserContext()) |
| + ->BroadcastEvent(std::move(pending_on_before_navigate_event_)); |
| +} |
| + |
| void WebNavigationTabObserver::HandleCommit( |
| content::NavigationHandle* navigation_handle) { |
| bool is_reference_fragment_navigation = IsReferenceFragmentNavigation( |