diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-05 08:07:17 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-05 08:07:17 +0000 |
commit | fdd94a02f3eeeaff9c13c4fb83b13734cca69859 (patch) | |
tree | 8270a7e5e5b895bbc9824b06b1d821a57dafc850 /chrome | |
parent | 60b06601b62b9830b39b562db06087fa5cd84060 (diff) | |
download | chromium_src-fdd94a02f3eeeaff9c13c4fb83b13734cca69859.zip chromium_src-fdd94a02f3eeeaff9c13c4fb83b13734cca69859.tar.gz chromium_src-fdd94a02f3eeeaff9c13c4fb83b13734cca69859.tar.bz2 |
Implement onCompleted event for the webNavigation API
BUG=50943
TEST=browser_tests:*.WebNavigationEvents*
Review URL: http://codereview.chromium.org/4448003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65182 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
14 files changed, 159 insertions, 1 deletions
diff --git a/chrome/browser/chromeos/login/web_page_view.cc b/chrome/browser/chromeos/login/web_page_view.cc index 5a7c30a..2d5e4de 100644 --- a/chrome/browser/chromeos/login/web_page_view.cc +++ b/chrome/browser/chromeos/login/web_page_view.cc @@ -83,6 +83,10 @@ void WizardWebPageViewTabContents::DocumentLoadedInFrame( page_delegate_->OnPageLoaded(); } +void WizardWebPageViewTabContents::DidFinishLoad( + long long /*frame_id*/) { +} + void WizardWebPageViewTabContents::OnContentBlocked(ContentSettingsType type) { LOG(ERROR) << "Page load failed: content blocked. Type: " << type; page_delegate_->OnPageLoadFailed(""); diff --git a/chrome/browser/chromeos/login/web_page_view.h b/chrome/browser/chromeos/login/web_page_view.h index 0e2bfcc..e219722 100644 --- a/chrome/browser/chromeos/login/web_page_view.h +++ b/chrome/browser/chromeos/login/web_page_view.h @@ -53,6 +53,7 @@ class WizardWebPageViewTabContents : public TabContents { virtual void DidDisplayInsecureContent(); virtual void DidRunInsecureContent(const std::string& security_origin); virtual void DocumentLoadedInFrame(long long frame_id); + virtual void DidFinishLoad(long long frame_id); virtual void OnContentBlocked(ContentSettingsType type); private: diff --git a/chrome/browser/extensions/extension_webnavigation_api.cc b/chrome/browser/extensions/extension_webnavigation_api.cc index 3b5f0e3..9a3e4ab 100644 --- a/chrome/browser/extensions/extension_webnavigation_api.cc +++ b/chrome/browser/extensions/extension_webnavigation_api.cc @@ -120,6 +120,9 @@ void ExtensionWebNavigationEventRouter::Init() { NotificationType::FRAME_DOM_CONTENT_LOADED, NotificationService::AllSources()); registrar_.Add(this, + NotificationType::FRAME_DID_FINISH_LOAD, + NotificationService::AllSources()); + registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR, NotificationService::AllSources()); registrar_.Add(this, @@ -148,6 +151,11 @@ void ExtensionWebNavigationEventRouter::Observe( Source<NavigationController>(source).ptr(), *Details<long long>(details).ptr()); break; + case NotificationType::FRAME_DID_FINISH_LOAD: + FrameDidFinishLoad( + Source<NavigationController>(source).ptr(), + *Details<long long>(details).ptr()); + break; case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR: FailProvisionalLoadWithError( Source<NavigationController>(source).ptr(), @@ -233,6 +241,25 @@ void ExtensionWebNavigationEventRouter::FrameDomContentLoaded( DispatchEvent(controller->profile(), keys::kOnDOMContentLoaded, json_args); } +void ExtensionWebNavigationEventRouter::FrameDidFinishLoad( + NavigationController* controller, long long frame_id) { + if (!navigation_state_.CanSendEvents(frame_id)) + return; + ListValue args; + DictionaryValue* dict = new DictionaryValue(); + dict->SetInteger(keys::kTabIdKey, + ExtensionTabUtil::GetTabId(controller->tab_contents())); + dict->SetString(keys::kUrlKey, navigation_state_.GetUrl(frame_id).spec()); + dict->SetInteger(keys::kFrameIdKey, navigation_state_.IsMainFrame(frame_id) ? + 0 : static_cast<int>(frame_id)); + dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); + args.Append(dict); + + std::string json_args; + base::JSONWriter::Write(&args, false, &json_args); + DispatchEvent(controller->profile(), keys::kOnCompleted, json_args); +} + void ExtensionWebNavigationEventRouter::FailProvisionalLoadWithError( NavigationController* controller, ProvisionalLoadDetails* details) { diff --git a/chrome/browser/extensions/extension_webnavigation_api.h b/chrome/browser/extensions/extension_webnavigation_api.h index 81d06cf..b595aca 100644 --- a/chrome/browser/extensions/extension_webnavigation_api.h +++ b/chrome/browser/extensions/extension_webnavigation_api.h @@ -106,6 +106,10 @@ class ExtensionWebNavigationEventRouter : public NotificationObserver { void FrameDomContentLoaded(NavigationController* controller, long long frame_id); + // Handler for the FRAME_DID_FINISH_LOAD event. The method takes the frame + // ID and constructs a suitable JSON formatted extension event from it. + void FrameDidFinishLoad(NavigationController* controller, long long frame_id); + // Handler for the FAIL_PROVISIONAL_LOAD_WITH_ERROR event. The method takes // the details of such an event and constructs a suitable JSON formatted // extension event from it. diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index f5b42ef..23d233c 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -803,6 +803,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { OnMsgForwardMessageToExternalHost) IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentLoadedInFrame, OnMsgDocumentLoadedInFrame) + IPC_MESSAGE_HANDLER(ViewHostMsg_DidFinishLoad, + OnMsgDidFinishLoad) IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, OnMsgGoToEntryAtOffset) IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnMsgSetTooltipText) @@ -1373,6 +1375,13 @@ void RenderViewHost::OnMsgDocumentLoadedInFrame(long long frame_id) { resource_delegate->DocumentLoadedInFrame(frame_id); } +void RenderViewHost::OnMsgDidFinishLoad(long long frame_id) { + RenderViewHostDelegate::Resource* resource_delegate = + delegate_->GetResourceDelegate(); + if (resource_delegate) + resource_delegate->DidFinishLoad(frame_id); +} + void RenderViewHost::DisassociateFromPopupCount() { Send(new ViewMsg_DisassociateFromPopupCount(routing_id())); } diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 47599ea..b821e7a 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -605,6 +605,7 @@ class RenderViewHost : public RenderWidgetHost { const std::string& origin, const std::string& target); void OnMsgDocumentLoadedInFrame(long long frame_id); + void OnMsgDidFinishLoad(long long frame_id); void OnMsgGoToEntryAtOffset(int offset); void OnMsgSetTooltipText(const std::wstring& tooltip_text, WebKit::WebTextDirection text_direction_hint); diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index 55b92a5..0602f2b 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -367,6 +367,9 @@ class RenderViewHostDelegate { // Notification that a document has been loaded in a frame. virtual void DocumentLoadedInFrame(long long frame_id) = 0; + // Notification that a frame finished loading. + virtual void DidFinishLoad(long long frame_id) = 0; + protected: virtual ~Resource() {} }; diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index c50f84e..91995c7 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -2256,6 +2256,13 @@ void TabContents::DocumentLoadedInFrame(long long frame_id) { Details<long long>(&frame_id)); } +void TabContents::DidFinishLoad(long long frame_id) { + NotificationService::current()->Notify( + NotificationType::FRAME_DID_FINISH_LOAD, + Source<NavigationController>(&controller_), + Details<long long>(&frame_id)); +} + void TabContents::OnContentSettingsAccessed(bool content_was_blocked) { if (delegate_) delegate_->OnContentSettingsChange(this); diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index f9542f3..0a79a83 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -916,6 +916,7 @@ class TabContents : public PageNavigator, const GURL& url, bool showing_repost_interstitial); virtual void DocumentLoadedInFrame(long long frame_id); + virtual void DidFinishLoad(long long frame_id); // RenderViewHostDelegate implementation. virtual RenderViewHostDelegate::View* GetViewDelegate(); diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index b8ffb76..e9127a7b 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -120,6 +120,11 @@ class NotificationType { // occurred. Details are the long long frame ID. FRAME_DOM_CONTENT_LOADED, + // The frame finished loading. The source is a Source<NavigationController> + // corresponding to the tab in which the load occurred. Details are the + // long long frame ID. + FRAME_DID_FINISH_LOAD, + // Content was loaded from an in-memory cache. The source will be a // Source<NavigationController> corresponding to the tab in which the load // occurred. Details in the form of a LoadFromMemoryCacheDetails object diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 14ee339d..a7fbf65 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -1230,6 +1230,10 @@ IPC_BEGIN_MESSAGES(ViewHost) IPC_MESSAGE_ROUTED1(ViewHostMsg_DocumentLoadedInFrame, long long /* frame_id */) + // Notifies the browser that a frame finished loading. + IPC_MESSAGE_ROUTED1(ViewHostMsg_DidFinishLoad, + long long /* frame_id */) + // Changes the title for the page in the UI when the page is navigated or the // title changes. // TODO(darin): use a UTF-8 string to reduce data size diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 74213b5..b4f42cb 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -3361,6 +3361,8 @@ void RenderView::didFinishLoad(WebFrame* frame) { // Let the password manager know which password forms are actually visible. password_autocomplete_manager_->SendPasswordForms(frame, true); + + Send(new ViewHostMsg_DidFinishLoad(routing_id_, frame->identifier())); } void RenderView::didNavigateWithinPage( diff --git a/chrome/test/data/extensions/api_test/webnavigation/navigation1/test.html b/chrome/test/data/extensions/api_test/webnavigation/navigation1/test.html index f8a0e3f..cbbfd99 100644 --- a/chrome/test/data/extensions/api_test/webnavigation/navigation1/test.html +++ b/chrome/test/data/extensions/api_test/webnavigation/navigation1/test.html @@ -47,6 +47,11 @@ chrome.experimental.webNavigation.onDOMContentLoaded.addListener( captureEvent("onDOMContentLoaded", details); }); +chrome.experimental.webNavigation.onCompleted.addListener( + function(details) { + captureEvent("onCompleted", details); +}); + chrome.experimental.webNavigation.onErrorOccurred.addListener( function(details) { captureEvent("onErrorOccurred", details); @@ -77,6 +82,11 @@ chrome.tabs.getSelected(null, function(tab) { { frameId: 0, tabId: tabId, timeStamp: 0, + url: getURL('simpleLoad/a.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, url: getURL('simpleLoad/a.html') }]]); chrome.tabs.update(tabId, { url: getURL('simpleLoad/a.html') }); }, @@ -104,6 +114,11 @@ chrome.tabs.getSelected(null, function(tab) { tabId: tabId, timeStamp: 0, url: getURL('clientRedirect/a.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, + url: getURL('clientRedirect/a.html') }], [ "onBeforeNavigate", { frameId: 0, requestId: 0, @@ -121,6 +136,11 @@ chrome.tabs.getSelected(null, function(tab) { { frameId: 0, tabId: tabId, timeStamp: 0, + url: getURL('clientRedirect/b.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, url: getURL('clientRedirect/b.html') }]]); chrome.tabs.update(tabId, { url: getURL('clientRedirect/a.html') }); }, @@ -147,6 +167,11 @@ chrome.tabs.getSelected(null, function(tab) { tabId: tabId, timeStamp: 0, url: getURL('forwardBack/a.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, + url: getURL('forwardBack/a.html') }], [ "onBeforeNavigate", { frameId: 0, requestId: 0, @@ -165,6 +190,11 @@ chrome.tabs.getSelected(null, function(tab) { tabId: tabId, timeStamp: 0, url: getURL('forwardBack/b.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, + url: getURL('forwardBack/b.html') }], [ "onBeforeNavigate", { frameId: 0, requestId: 0, @@ -182,6 +212,11 @@ chrome.tabs.getSelected(null, function(tab) { { frameId: 0, tabId: tabId, timeStamp: 0, + url: getURL('forwardBack/a.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, url: getURL('forwardBack/a.html') }]]); chrome.tabs.update(tabId, { url: getURL('forwardBack/a.html') }); }, @@ -226,6 +261,16 @@ chrome.tabs.getSelected(null, function(tab) { tabId: tabId, timeStamp: 0, url: getURL('iframe/b.html') }], + [ "onCompleted", + { frameId: 1, + tabId: tabId, + timeStamp: 0, + url: getURL('iframe/b.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, + url: getURL('iframe/a.html') }], [ "onBeforeNavigate", { frameId: 1, requestId: 0, @@ -243,6 +288,11 @@ chrome.tabs.getSelected(null, function(tab) { { frameId: 1, tabId: tabId, timeStamp: 0, + url: getURL('iframe/c.html') }], + [ "onCompleted", + { frameId: 1, + tabId: tabId, + timeStamp: 0, url: getURL('iframe/c.html') }]]); chrome.tabs.update(tabId, { url: getURL('iframe/a.html') }); }, @@ -294,6 +344,11 @@ chrome.tabs.getSelected(null, function(tab) { tabId: tabId, timeStamp: 0, url: getURL('iframe/f.html') }], + [ "onCompleted", + { frameId: 1, + tabId: tabId, + timeStamp: 0, + url: getURL('iframe/e.html') }], [ "onCommitted", { frameId: 2, tabId: tabId, @@ -306,6 +361,16 @@ chrome.tabs.getSelected(null, function(tab) { tabId: tabId, timeStamp: 0, url: getURL('iframe/f.html') }], + [ "onCompleted", + { frameId: 2, + tabId: tabId, + timeStamp: 0, + url: getURL('iframe/f.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, + url: getURL('iframe/d.html') }], [ "onBeforeNavigate", { frameId: 2, requestId: 0, @@ -323,6 +388,11 @@ chrome.tabs.getSelected(null, function(tab) { { frameId: 2, tabId: tabId, timeStamp: 0, + url: getURL('iframe/g.html') }], + [ "onCompleted", + { frameId: 2, + tabId: tabId, + timeStamp: 0, url: getURL('iframe/g.html') }]]); chrome.tabs.update(tabId, { url: getURL('iframe/d.html') }); }, diff --git a/chrome/test/data/extensions/api_test/webnavigation/navigation2/test.html b/chrome/test/data/extensions/api_test/webnavigation/navigation2/test.html index e97a67a..f55b927 100644 --- a/chrome/test/data/extensions/api_test/webnavigation/navigation2/test.html +++ b/chrome/test/data/extensions/api_test/webnavigation/navigation2/test.html @@ -47,6 +47,11 @@ chrome.experimental.webNavigation.onDOMContentLoaded.addListener( captureEvent("onDOMContentLoaded", details); }); +chrome.experimental.webNavigation.onCompleted.addListener( + function(details) { + captureEvent("onCompleted", details); +}); + chrome.experimental.webNavigation.onErrorOccurred.addListener( function(details) { captureEvent("onErrorOccurred", details); @@ -107,7 +112,12 @@ chrome.tabs.getSelected(null, function(tab) { frameId: 1, tabId: tabId, timeStamp: 0, - url: getURL('iframeFail/c.html') }]]); + url: getURL('iframeFail/c.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, + url: getURL('iframeFail/d.html') }]]); chrome.tabs.update(tabId, { url: getURL('iframeFail/d.html') }); }, @@ -150,6 +160,16 @@ chrome.tabs.getSelected(null, function(tab) { tabId: tabId, timeStamp: 0, url: getURL('iframeFail/b.html') }], + [ "onCompleted", + { frameId: 1, + tabId: tabId, + timeStamp: 0, + url: getURL('iframeFail/b.html') }], + [ "onCompleted", + { frameId: 0, + tabId: tabId, + timeStamp: 0, + url: getURL('iframeFail/a.html') }], [ "onBeforeNavigate", { frameId: 1, requestId: 0, |