diff options
author | fsamuel@chromium.org <fsamuel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-25 20:42:55 +0000 |
---|---|---|
committer | fsamuel@chromium.org <fsamuel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-25 20:42:55 +0000 |
commit | 1869937705df919aff92cb54888527ccbaf62702 (patch) | |
tree | f56f5b67c9ad9b9330697b019a60337980303a65 | |
parent | ed2fa729af0311cc4d5f30be5f0368fad248d64a (diff) | |
download | chromium_src-1869937705df919aff92cb54888527ccbaf62702.zip chromium_src-1869937705df919aff92cb54888527ccbaf62702.tar.gz chromium_src-1869937705df919aff92cb54888527ccbaf62702.tar.bz2 |
<webview>: Partially migrate loadcommit event from content to chrome
All the pieces are now in place for upstreaming the big content->chrome
<webview> refactor. This first patch puts in the first set of pieces in
place for migrating loadcommit to chrome.
BUG=166165
Test=WebViewTest.*
Review URL: https://chromiumcodereview.appspot.com/17165004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@208542 0039d316-1c4b-4281-b951-d872f2087c98
24 files changed, 374 insertions, 193 deletions
diff --git a/chrome/browser/adview/adview_constants.cc b/chrome/browser/adview/adview_constants.cc new file mode 100644 index 0000000..2e0809e4 --- /dev/null +++ b/chrome/browser/adview/adview_constants.cc @@ -0,0 +1,19 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/adview/adview_constants.h" + +namespace adview { + +// Events. +const char kEventLoadCommit[] = "adview.onLoadCommit"; + +// Parameters/properties on events. +const char kIsTopLevel[] = "isTopLevel"; +const char kUrl[] = "url"; + +// Attributes. +const char kAttributeApi[] = "api"; + +} // namespace adview diff --git a/chrome/browser/adview/adview_constants.h b/chrome/browser/adview/adview_constants.h new file mode 100644 index 0000000..efbbcb1 --- /dev/null +++ b/chrome/browser/adview/adview_constants.h @@ -0,0 +1,25 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Constants used for the adview API. + +#ifndef CHROME_BROWSER_ADVIEW_ADVIEW_CONSTANTS_H_ +#define CHROME_BROWSER_ADVIEW_ADVIEW_CONSTANTS_H_ + +namespace adview { + +// Events. +extern const char kEventLoadCommit[]; + +// Parameters/properties on events. +extern const char kIsTopLevel[]; +extern const char kUrl[]; + +// Attributes. +extern const char kAttributeApi[]; + +} // namespace adview + +#endif // CHROME_BROWSER_ADVIEW_ADVIEW_CONSTANTS_H_ + diff --git a/chrome/browser/adview/adview_guest.cc b/chrome/browser/adview/adview_guest.cc new file mode 100644 index 0000000..2a2fedf --- /dev/null +++ b/chrome/browser/adview/adview_guest.cc @@ -0,0 +1,89 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/adview/adview_guest.h" + +#include "base/lazy_instance.h" +#include "chrome/browser/adview/adview_constants.h" +#include "chrome/browser/extensions/event_router.h" +#include "chrome/browser/extensions/extension_system.h" +#include "chrome/browser/profiles/profile.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/site_instance.h" +#include "content/public/browser/web_contents.h" + +using content::WebContents; + +namespace { + +typedef std::map<std::pair<int, int>, AdViewGuest*> AdViewGuestMap; +base::LazyInstance<AdViewGuestMap> adview_guest_map = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + +AdViewGuest::AdViewGuest(WebContents* guest_web_contents, + WebContents* embedder_web_contents, + const std::string& extension_id, + int view_instance_id, + const base::DictionaryValue& args) + : WebContentsObserver(guest_web_contents), + embedder_web_contents_(embedder_web_contents), + extension_id_(extension_id), + embedder_render_process_id_( + embedder_web_contents->GetRenderProcessHost()->GetID()), + profile_(guest_web_contents->GetBrowserContext()), + guest_instance_id_(guest_web_contents->GetEmbeddedInstanceID()), + view_instance_id_(view_instance_id) { + std::pair<int, int> key(embedder_render_process_id_, guest_instance_id_); + adview_guest_map.Get().insert(std::make_pair(key, this)); +} + +// static +AdViewGuest* AdViewGuest::From(int embedder_process_id, + int guest_instance_id) { + AdViewGuestMap* guest_map = adview_guest_map.Pointer(); + AdViewGuestMap::iterator it = guest_map->find( + std::make_pair(embedder_process_id, guest_instance_id)); + return it == guest_map->end() ? NULL : it->second; +} + +AdViewGuest::~AdViewGuest() { + std::pair<int, int> key(embedder_render_process_id_, guest_instance_id_); + adview_guest_map.Get().erase(key); +} + +void AdViewGuest::DispatchEvent(const std::string& event_name, + scoped_ptr<DictionaryValue> event) { + Profile* profile = Profile::FromBrowserContext( + web_contents()->GetBrowserContext()); + + extensions::EventFilteringInfo info; + info.SetURL(GURL()); + info.SetInstanceID(guest_instance_id_); + scoped_ptr<ListValue> args(new ListValue()); + args->Append(event.release()); + + extensions::EventRouter::DispatchEvent( + embedder_web_contents_, profile, extension_id_, + event_name, args.Pass(), + extensions::EventRouter::USER_GESTURE_UNKNOWN, info); +} + +void AdViewGuest::DidCommitProvisionalLoadForFrame( + int64 frame_id, + bool is_main_frame, + const GURL& url, + content::PageTransition transition_type, + content::RenderViewHost* render_view_host) { + scoped_ptr<DictionaryValue> event(new DictionaryValue()); + event->SetString(adview::kUrl, url.spec()); + event->SetBoolean(adview::kIsTopLevel, is_main_frame); + DispatchEvent(adview::kEventLoadCommit, event.Pass()); +} + +void AdViewGuest::WebContentsDestroyed(WebContents* web_contents) { + delete this; +} diff --git a/chrome/browser/adview/adview_guest.h b/chrome/browser/adview/adview_guest.h new file mode 100644 index 0000000..7ebbcb1 --- /dev/null +++ b/chrome/browser/adview/adview_guest.h @@ -0,0 +1,71 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ADVIEW_ADVIEW_GUEST_H_ +#define CHROME_BROWSER_ADVIEW_ADVIEW_GUEST_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" +#include "base/values.h" +#include "content/public/browser/web_contents_observer.h" + +// An AdViewGuest is a WebContentsObserver on the guest WebContents of a +// <adview> tag. It provides the browser-side implementation of the <adview> +// API and manages the lifetime of <adview> extension events. AdViewGuest is +// created on attachment. When a guest WebContents is associated with +// a particular embedder WebContents, we call this "attachment". +// TODO(fsamuel): There might be an opportunity here to refactor and reuse code +// between AdViewGuest and WebViewGuest. +class AdViewGuest : public content::WebContentsObserver { + public: + AdViewGuest(content::WebContents* guest_web_contents, + content::WebContents* embedder_web_contents, + const std::string& extension_id, + int adview_instance_id, + const base::DictionaryValue& args); + + static AdViewGuest* From(int embedder_process_id, int instance_id); + + content::WebContents* embedder_web_contents() const { + return embedder_web_contents_; + } + + content::WebContents* web_contents() const { + return WebContentsObserver::web_contents(); + } + + int view_instance_id() const { return view_instance_id_; } + + private: + virtual ~AdViewGuest(); + + void DispatchEvent(const std::string& event_name, + scoped_ptr<DictionaryValue> event); + + virtual void DidCommitProvisionalLoadForFrame( + int64 frame_id, + bool is_main_frame, + const GURL& url, + content::PageTransition transition_type, + content::RenderViewHost* render_view_host) OVERRIDE; + virtual void WebContentsDestroyed( + content::WebContents* web_contents) OVERRIDE; + + content::WebContents* embedder_web_contents_; + const std::string extension_id_; + const int embedder_render_process_id_; + // Profile and instance ID are cached here because |web_contents()| is + // null on destruction. + void* profile_; + // |guest_instance_id_| is a profile-wide unique identifier for a guest + // WebContents. + const int guest_instance_id_; + // |view_instance_id_| is an identifier that's unique within a particular + // embedder RenderView for a particular <adview> instance. + const int view_instance_id_; + + DISALLOW_COPY_AND_ASSIGN(AdViewGuest); +}; + +#endif // CHROME_BROWSER_ADVIEW_ADVIEW_GUEST_H_ diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 61cda79..6e16a0b 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -17,6 +17,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/sequenced_worker_pool.h" #include "chrome/app/breakpad_mac.h" +#include "chrome/browser/adview/adview_guest.h" #include "chrome/browser/app_mode/app_mode_utils.h" #include "chrome/browser/browser_about_handler.h" #include "chrome/browser/browser_process.h" @@ -84,6 +85,7 @@ #include "chrome/browser/user_style_sheet_watcher.h" #include "chrome/browser/user_style_sheet_watcher_factory.h" #include "chrome/browser/validation_message_message_filter.h" +#include "chrome/browser/webview/webview_constants.h" #include "chrome/browser/webview/webview_guest.h" #include "chrome/common/child_process_logging.h" #include "chrome/common/chrome_constants.h" @@ -710,11 +712,28 @@ void ChromeContentBrowserClient::GuestWebContentsAttached( GetExtensionOrAppByURL(ExtensionURLInfo(url)); if (!extension) return; - new WebViewGuest(guest_web_contents, - embedder_web_contents, - extension->id(), - browser_plugin_instance_id, - extra_params); + + std::string api_type; + extra_params.GetString(webview::kAttributeApi, &api_type); + + // WebViewGuest and AdViewGuest's lifetimes iare tied to their associated + // guest WebContents' lifetime. When the guest WebContents is destroyed, so is + // the attached WebViewGuest or AdViewGuest. + if (api_type == "adview") { + new AdViewGuest(guest_web_contents, + embedder_web_contents, + extension->id(), + browser_plugin_instance_id, + extra_params); + } else if (api_type == "webview") { + new WebViewGuest(guest_web_contents, + embedder_web_contents, + extension->id(), + browser_plugin_instance_id, + extra_params); + } else { + NOTREACHED(); + } } void ChromeContentBrowserClient::RenderProcessHostCreated( diff --git a/chrome/browser/extensions/api/webview/webview_api.cc b/chrome/browser/extensions/api/webview/webview_api.cc index dc89e45..db6675f 100644 --- a/chrome/browser/extensions/api/webview/webview_api.cc +++ b/chrome/browser/extensions/api/webview/webview_api.cc @@ -52,7 +52,7 @@ bool WebviewExecuteCodeFunction::CanExecuteScriptOnPage() { } extensions::ScriptExecutor* WebviewExecuteCodeFunction::GetScriptExecutor() { - chrome::WebViewGuest* guest = chrome::WebViewGuest::From( + WebViewGuest* guest = WebViewGuest::From( render_view_host()->GetProcess()->GetID(), guest_instance_id_); if (!guest) return NULL; diff --git a/chrome/browser/extensions/extension_renderer_state.h b/chrome/browser/extensions/extension_renderer_state.h index 8118585..1ce2dde 100644 --- a/chrome/browser/extensions/extension_renderer_state.h +++ b/chrome/browser/extensions/extension_renderer_state.h @@ -12,9 +12,7 @@ #include "base/basictypes.h" #include "base/memory/singleton.h" -namespace chrome { class WebViewGuest; -} // namespace chrome // This class keeps track of renderer state for use on the IO thread. All // methods should be called on the IO thread except for Init and Shutdown. @@ -48,7 +46,7 @@ class ExtensionRendererState { class RenderViewHostObserver; class TabObserver; friend class TabObserver; - friend class chrome::WebViewGuest; + friend class WebViewGuest; friend struct DefaultSingletonTraits<ExtensionRendererState>; typedef std::pair<int, int> RenderId; diff --git a/chrome/browser/webview/webview_constants.cc b/chrome/browser/webview/webview_constants.cc index 5a5e13b..0766a21 100644 --- a/chrome/browser/webview/webview_constants.cc +++ b/chrome/browser/webview/webview_constants.cc @@ -4,9 +4,16 @@ #include "chrome/browser/webview/webview_constants.h" -namespace webview_constants { +namespace webview { + +// Events. +const char kEventLoadCommit[] = "webview.onLoadCommit"; + +// Parameters/properties on events. +const char kIsTopLevel[] = "isTopLevel"; +const char kUrl[] = "url"; // Attributes. const char kAttributeApi[] = "api"; -} // namespace webview_constants +} // namespace webview diff --git a/chrome/browser/webview/webview_constants.h b/chrome/browser/webview/webview_constants.h index ee8cef4..c48ad9b 100644 --- a/chrome/browser/webview/webview_constants.h +++ b/chrome/browser/webview/webview_constants.h @@ -7,12 +7,19 @@ #ifndef CHROME_BROWSER_WEBVIEW_WEBVIEW_CONSTANTS_H_ #define CHROME_BROWSER_WEBVIEW_WEBVIEW_CONSTANTS_H_ -namespace webview_constants { +namespace webview { + +// Events. +extern const char kEventLoadCommit[]; + +// Parameters/properties on events. +extern const char kIsTopLevel[]; +extern const char kUrl[]; // Attributes. extern const char kAttributeApi[]; -} // namespace webview_constants +} // namespace webview #endif // CHROME_BROWSER_WEBVIEW_WEBVIEW_CONSTANTS_H_ diff --git a/chrome/browser/webview/webview_guest.cc b/chrome/browser/webview/webview_guest.cc index 5d97f2a..c4f8f1f 100644 --- a/chrome/browser/webview/webview_guest.cc +++ b/chrome/browser/webview/webview_guest.cc @@ -6,7 +6,9 @@ #include "base/lazy_instance.h" #include "chrome/browser/extensions/api/web_request/web_request_api.h" +#include "chrome/browser/extensions/event_router.h" #include "chrome/browser/extensions/extension_renderer_state.h" +#include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/extensions/script_executor.h" #include "chrome/browser/webview/webview_constants.h" #include "content/public/browser/browser_thread.h" @@ -16,14 +18,10 @@ using content::WebContents; -namespace keys = webview_constants; - -namespace chrome { - namespace { typedef std::map<std::pair<int, int>, WebViewGuest*> WebViewGuestMap; -static base::LazyInstance<WebViewGuestMap> webview_guest_map = +base::LazyInstance<WebViewGuestMap> webview_guest_map = LAZY_INSTANCE_INITIALIZER; void RemoveWebViewEventListenersOnIOThread( @@ -53,9 +51,6 @@ WebViewGuest::WebViewGuest(WebContents* guest_web_contents, webview_instance_id_(webview_instance_id), script_executor_(new extensions::ScriptExecutor(guest_web_contents, &script_observers_)) { - std::string api_name; - DCHECK(args.GetString(keys::kAttributeApi, &api_name)); - DCHECK_EQ("webview", api_name); std::pair<int, int> key(embedder_render_process_id_, guest_instance_id_); webview_guest_map.Get().insert(std::make_pair(key, this)); @@ -76,6 +71,35 @@ WebViewGuest::~WebViewGuest() { webview_guest_map.Get().erase(key); } +void WebViewGuest::DispatchEvent(const std::string& event_name, + scoped_ptr<DictionaryValue> event) { + Profile* profile = Profile::FromBrowserContext( + web_contents()->GetBrowserContext()); + + extensions::EventFilteringInfo info; + info.SetURL(GURL()); + info.SetInstanceID(guest_instance_id_); + scoped_ptr<ListValue> args(new ListValue()); + args->Append(event.release()); + + extensions::EventRouter::DispatchEvent( + embedder_web_contents_, profile, extension_id_, + event_name, args.Pass(), + extensions::EventRouter::USER_GESTURE_UNKNOWN, info); +} + +void WebViewGuest::DidCommitProvisionalLoadForFrame( + int64 frame_id, + bool is_main_frame, + const GURL& url, + content::PageTransition transition_type, + content::RenderViewHost* render_view_host) { + scoped_ptr<DictionaryValue> event(new DictionaryValue()); + event->SetString(webview::kUrl, url.spec()); + event->SetBoolean(webview::kIsTopLevel, is_main_frame); + DispatchEvent(webview::kEventLoadCommit, event.Pass()); +} + void WebViewGuest::WebContentsDestroyed(WebContents* web_contents) { RemoveWebViewFromExtensionRendererState(web_contents); content::BrowserThread::PostTask( @@ -118,5 +142,3 @@ void WebViewGuest::RemoveWebViewFromExtensionRendererState( web_contents->GetRenderProcessHost()->GetID(), web_contents->GetRoutingID())); } - -} // namespace chrome diff --git a/chrome/browser/webview/webview_guest.h b/chrome/browser/webview/webview_guest.h index cefc7b3..da406a0 100644 --- a/chrome/browser/webview/webview_guest.h +++ b/chrome/browser/webview/webview_guest.h @@ -13,8 +13,6 @@ namespace extensions { class ScriptExecutor; } // namespace extensions -namespace chrome { - // A WebViewGuest is a WebContentsObserver on the guest WebContents of a // <webview> tag. It provides the browser-side implementation of the <webview> // API and manages the lifetime of <webview> extension events. WebViewGuest is @@ -48,6 +46,16 @@ class WebViewGuest : public content::WebContentsObserver { private: virtual ~WebViewGuest(); + + void DispatchEvent(const std::string& event_name, + scoped_ptr<DictionaryValue> event); + + virtual void DidCommitProvisionalLoadForFrame( + int64 frame_id, + bool is_main_frame, + const GURL& url, + content::PageTransition transition_type, + content::RenderViewHost* render_view_host) OVERRIDE; virtual void WebContentsDestroyed( content::WebContents* web_contents) OVERRIDE; @@ -75,6 +83,4 @@ class WebViewGuest : public content::WebContentsObserver { DISALLOW_COPY_AND_ASSIGN(WebViewGuest); }; -} // namespace chrome - #endif // CHROME_BROWSER_WEBVIEW_WEBVIEW_GUEST_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 8f633c2..ec21bcd 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -84,6 +84,10 @@ 'browser/accessibility/accessibility_events.h', 'browser/accessibility/invert_bubble_prefs.cc', 'browser/accessibility/invert_bubble_prefs.h', + 'browser/adview/adview_constants.cc', + 'browser/adview/adview_constants.h', + 'browser/adview/adview_guest.cc', + 'browser/adview/adview_guest.h', 'browser/android/chrome_jni_registrar.cc', 'browser/android/chrome_jni_registrar.h', 'browser/android/chrome_startup_flags.cc', diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 5199402..38a6fa6 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -10,6 +10,10 @@ "dependencies": ["permission:activityLogPrivate"], "contexts": ["blessed_extension"] }, + "adview": { + "dependencies": ["permission:adview"], + "contexts": ["blessed_extension"] + }, "alarms": { "dependencies": ["permission:alarms"], "contexts": ["blessed_extension"] diff --git a/chrome/common/extensions/api/adview.json b/chrome/common/extensions/api/adview.json new file mode 100644 index 0000000..68d8802 --- /dev/null +++ b/chrome/common/extensions/api/adview.json @@ -0,0 +1,12 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + { + "namespace": "adview", + "description": "none", + "nodoc": true + } +] + diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp index 3ab46cc..d09c800 100644 --- a/chrome/common/extensions/api/api.gyp +++ b/chrome/common/extensions/api/api.gyp @@ -21,6 +21,7 @@ 'schema_files': [ 'alarms.idl', 'activity_log_private.json', + 'adview.json', 'app_current_window_internal.idl', 'app_runtime.idl', 'app_window.idl', diff --git a/chrome/renderer/resources/extensions/ad_view.js b/chrome/renderer/resources/extensions/ad_view.js index fa1c0cf..1efda0e 100644 --- a/chrome/renderer/resources/extensions/ad_view.js +++ b/chrome/renderer/resources/extensions/ad_view.js @@ -10,6 +10,7 @@ // TODO(rpaquay): This file is currently very similar to "web_view.js". Do we // want to refactor to extract common pieces? +var eventBindings = require('event_bindings'); var process = requireNative('process'); var watchForTag = require('tagWatcher').watchForTag; @@ -73,6 +74,13 @@ var AD_VIEW_EVENTS = { 'sizechanged': ['oldHeight', 'oldWidth', 'newHeight', 'newWidth'], }; +var createEvent = function(name) { + var eventOpts = {supportsListeners: true, supportsFilters: true}; + return new eventBindings.Event(name, undefined, eventOpts); +}; + +var AdviewLoadCommitEvent = createEvent('adview.onLoadCommit'); + /** * List of supported ad-networks. * @@ -124,8 +132,7 @@ function AdView(adviewNode) { AdView.prototype.createBrowserPluginNode_ = function() { var browserPluginNode = document.createElement('object'); browserPluginNode.type = 'application/browser-plugin'; - // TODO(fsamuel): Change this to 'adview' once AdViewGuest is ready. - browserPluginNode.setAttribute('api', 'webview'); + browserPluginNode.setAttribute('api', 'adview'); // The <object> node fills in the <adview> container. browserPluginNode.style.width = '100%'; browserPluginNode.style.height = '100%'; @@ -432,6 +439,21 @@ AdView.prototype.handleSrcMutation = function(mutation) { * @private */ AdView.prototype.setupAdviewNodeEvents_ = function() { + var adviewNode = this.adviewNode_; + // TODO(fsamuel): Generalize this further as we add more events. + var onAttached = function(e) { + var detail = e.detail ? JSON.parse(e.detail) : {}; + AdviewLoadCommitEvent.addListener(function(event) { + var adviewEvent = new Event('loadcommit', {bubbles: true}); + var attribs = AD_VIEW_EVENTS['loadcommit']; + $Array.forEach(attribs, function(attribName) { + adviewEvent[attribName] = event[attribName]; + }); + adviewNode.dispatchEvent(adviewEvent); + }, {instanceId: detail.windowId}); + }; + this.browserPluginNode_.addEventListener('-internal-attached', onAttached); + for (var eventName in AD_VIEW_EVENTS) { this.setupEvent_(eventName, AD_VIEW_EVENTS[eventName]); } diff --git a/chrome/renderer/resources/extensions/web_view.js b/chrome/renderer/resources/extensions/web_view.js index bfb3498..f4cc6ef 100644 --- a/chrome/renderer/resources/extensions/web_view.js +++ b/chrome/renderer/resources/extensions/web_view.js @@ -8,6 +8,7 @@ // are hidden via Shadow DOM. var watchForTag = require('tagWatcher').watchForTag; +var eventBindings = require('event_bindings'); /** @type {Array.<string>} */ var WEB_VIEW_ATTRIBUTES = ['name', 'src', 'partition', 'autosize', 'minheight', @@ -43,6 +44,13 @@ var WEB_VIEW_EVENTS = { 'unresponsive' : ['processId'] }; +var createEvent = function(name) { + var eventOpts = {supportsListeners: true, supportsFilters: true}; + return new eventBindings.Event(name, undefined, eventOpts); +}; + +var loadCommitEvent = createEvent('webview.onLoadCommit'); + // The <webview> tags we wish to watch for (watchForTag) does not belong to the // current scope's "document" reference. We need to wait until the document // begins loading, since only then will the "document" reference @@ -266,6 +274,21 @@ WebView.prototype.handleBrowserPluginAttributeMutation_ = function(mutation) { * @private */ WebView.prototype.setupWebviewNodeEvents_ = function() { + var webviewNode = this.webviewNode_; + // TODO(fsamuel): Generalize this further as we add more events. + var onAttached = function(e) { + var detail = e.detail ? JSON.parse(e.detail) : {}; + loadCommitEvent.addListener(function(event) { + var webviewEvent = new Event('loadcommit', {bubbles: true}); + var attribs = WEB_VIEW_EVENTS['loadcommit']; + $Array.forEach(attribs, function(attribName) { + webviewEvent[attribName] = event[attribName]; + }); + webviewNode.dispatchEvent(webviewEvent); + }, {instanceId: detail.windowId}); + }; + this.browserPluginNode_.addEventListener('-internal-attached', onAttached); + for (var eventName in WEB_VIEW_EVENTS) { this.setupEvent_(eventName, WEB_VIEW_EVENTS[eventName]); } diff --git a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc index adcb948..134705e 100644 --- a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc +++ b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -1128,29 +1128,6 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadStop) { EXPECT_EQ(expected_title, actual_title); } -IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadCommit) { - const char* kEmbedderURL = "/browser_plugin_embedder.html"; - StartBrowserPluginTest(kEmbedderURL, "about:blank", true, std::string()); - - const string16 expected_title = ASCIIToUTF16( - base::StringPrintf("loadCommit:%s", kHTMLForGuest)); - content::TitleWatcher title_watcher( - test_embedder()->web_contents(), expected_title); - // Renavigate the guest to |kHTMLForGuest|. - RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( - test_embedder()->web_contents()->GetRenderViewHost()); - ExecuteSyncJSFunction(rvh, - base::StringPrintf("SetSrc('%s');", kHTMLForGuest)); - - string16 actual_title = title_watcher.WaitAndGetTitle(); - EXPECT_EQ(expected_title, actual_title); - scoped_ptr<base::Value> is_top_level = - content::ExecuteScriptAndGetValue(rvh, "commitIsTopLevel"); - bool top_level_bool = false; - EXPECT_TRUE(is_top_level->GetAsBoolean(&top_level_bool)); - EXPECT_EQ(true, top_level_bool); -} - // This test verifies that if a browser plugin is hidden before navigation, // the guest starts off hidden. IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, HiddenBeforeNavigation) { diff --git a/content/common/browser_plugin/browser_plugin_constants.cc b/content/common/browser_plugin/browser_plugin_constants.cc index f3bbdd1..80146f0 100644 --- a/content/common/browser_plugin/browser_plugin_constants.cc +++ b/content/common/browser_plugin/browser_plugin_constants.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -25,6 +25,9 @@ const char kMethodInternalAttachWindowTo[] = "-internal-attachWindowTo"; const char kMethodInternalPersistObject[] = "-internal-persistObject"; const char kMethodInternalSetPermission[] = "-internal-setPermission"; +// Internal events. +const char kEventInternalAttached[] = "attached"; + // Attributes. const char kAttributeApi[] = "api"; const char kAttributeAutoSize[] = "autosize"; @@ -43,7 +46,6 @@ const char kEventConsoleMessage[] = "consolemessage"; const char kEventContentLoad[] = "contentload"; const char kEventExit[] = "exit"; const char kEventLoadAbort[] = "loadabort"; -const char kEventLoadCommit[] = "loadcommit"; const char kEventLoadRedirect[] = "loadredirect"; const char kEventLoadStart[] = "loadstart"; const char kEventLoadStop[] = "loadstop"; diff --git a/content/common/browser_plugin/browser_plugin_constants.h b/content/common/browser_plugin/browser_plugin_constants.h index dafa165..991ad3d 100644 --- a/content/common/browser_plugin/browser_plugin_constants.h +++ b/content/common/browser_plugin/browser_plugin_constants.h @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -26,6 +26,9 @@ extern const char kMethodInternalAttachWindowTo[]; extern const char kMethodInternalPersistObject[]; extern const char kMethodInternalSetPermission[]; +// Internal events +extern const char kEventInternalAttached[]; + // Attributes. extern const char kAttributeApi[]; extern const char kAttributeAutoSize[]; @@ -44,7 +47,6 @@ extern const char kEventConsoleMessage[]; extern const char kEventContentLoad[]; extern const char kEventExit[]; extern const char kEventLoadAbort[]; -extern const char kEventLoadCommit[]; extern const char kEventLoadRedirect[]; extern const char kEventLoadStart[]; extern const char kEventLoadStop[]; diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 011b2ec..25cdaa0 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -420,6 +420,11 @@ void BrowserPlugin::Attach(int guest_instance_id) { guest_instance_id_ = guest_instance_id; browser_plugin_manager()->AddBrowserPlugin(guest_instance_id, this); + std::map<std::string, base::Value*> props; + props[browser_plugin::kWindowID] = + new base::FundamentalValue(guest_instance_id); + TriggerEvent(browser_plugin::kEventInternalAttached, &props); + BrowserPluginHostMsg_Attach_Params attach_params; attach_params.browser_plugin_instance_id = instance_id_; attach_params.focused = ShouldGuestBeFocused(); @@ -583,12 +588,6 @@ void BrowserPlugin::OnLoadCommit( current_nav_entry_index_ = params.current_entry_index; nav_entry_count_ = params.entry_count; - - std::map<std::string, base::Value*> props; - props[browser_plugin::kURL] = new base::StringValue(params.url.spec()); - props[browser_plugin::kIsTopLevel] = - new base::FundamentalValue(params.is_top_level); - TriggerEvent(browser_plugin::kEventLoadCommit, &props); } void BrowserPlugin::OnLoadHandlerCalled(int guest_instance_id) { diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index d6791cf..b95380b 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/content/renderer/browser_plugin/browser_plugin_browsertest.cc b/content/renderer/browser_plugin/browser_plugin_browsertest.cc index dd12f18..0bdcf6f 100644 --- a/content/renderer/browser_plugin/browser_plugin_browsertest.cc +++ b/content/renderer/browser_plugin/browser_plugin_browsertest.cc @@ -453,53 +453,6 @@ TEST_F(BrowserPluginTest, RemovePluginBeforeNavigation) { BrowserPluginHostMsg_PluginDestroyed::ID)); } -TEST_F(BrowserPluginTest, CustomEvents) { - const char* kAddEventListener = - "var url;" - "function nav(e) {" - " url = JSON.parse(e.detail).url;" - "}" - "document.getElementById('browserplugin')." - " addEventListener('-internal-loadcommit', nav);"; - const char* kRemoveEventListener = - "document.getElementById('browserplugin')." - " removeEventListener('-internal-loadcommit', nav);"; - const char* kGetSrc = - "document.getElementById('browserplugin').src"; - const char* kGoogleURL = "http://www.google.com/"; - const char* kGoogleNewsURL = "http://news.google.com/"; - - LoadHTML(GetHTMLForBrowserPluginObject().c_str()); - ExecuteJavaScript(kAddEventListener); - - MockBrowserPlugin* browser_plugin = GetCurrentPlugin(); - ASSERT_TRUE(browser_plugin); - int instance_id = browser_plugin->instance_id(); - - { - BrowserPluginMsg_LoadCommit_Params navigate_params; - navigate_params.is_top_level = true; - navigate_params.url = GURL(kGoogleURL); - BrowserPluginMsg_LoadCommit msg(instance_id, navigate_params); - browser_plugin->OnMessageReceived(msg); - EXPECT_EQ(kGoogleURL, ExecuteScriptAndReturnString("url")); - EXPECT_EQ(kGoogleURL, ExecuteScriptAndReturnString(kGetSrc)); - } - ExecuteJavaScript(kRemoveEventListener); - { - BrowserPluginMsg_LoadCommit_Params navigate_params; - navigate_params.is_top_level = false; - navigate_params.url = GURL(kGoogleNewsURL); - BrowserPluginMsg_LoadCommit msg(instance_id, navigate_params); - browser_plugin->OnMessageReceived(msg); - // The URL variable should not change because we've removed the event - // listener. - EXPECT_EQ(kGoogleURL, ExecuteScriptAndReturnString("url")); - // The src attribute should not change if this is a top-level navigation. - EXPECT_EQ(kGoogleURL, ExecuteScriptAndReturnString(kGetSrc)); - } -} - TEST_F(BrowserPluginTest, StopMethod) { const char* kCallStop = "document.getElementById('browserplugin').stop();"; @@ -657,79 +610,6 @@ TEST_F(BrowserPluginTest, ImmutableAttributesAfterNavigation) { EXPECT_STREQ("storage", partition_value.c_str()); } -// This test verifies that we can mutate the event listener vector -// within an event listener. -TEST_F(BrowserPluginTest, RemoveEventListenerInEventListener) { - const char* kAddEventListener = - "var url;" - "function nav(e) {" - " url = JSON.parse(e.detail).url;" - " document.getElementById('browserplugin')." - " removeEventListener('-internal-loadcommit', nav);" - "}" - "document.getElementById('browserplugin')." - " addEventListener('-internal-loadcommit', nav);"; - const char* kGoogleURL = "http://www.google.com/"; - const char* kGoogleNewsURL = "http://news.google.com/"; - - LoadHTML(GetHTMLForBrowserPluginObject().c_str()); - ExecuteJavaScript(kAddEventListener); - - MockBrowserPlugin* browser_plugin = GetCurrentPlugin(); - ASSERT_TRUE(browser_plugin); - int instance_id = browser_plugin->instance_id(); - - { - BrowserPluginMsg_LoadCommit_Params navigate_params; - navigate_params.url = GURL(kGoogleURL); - BrowserPluginMsg_LoadCommit msg(instance_id, navigate_params); - browser_plugin->OnMessageReceived(msg); - EXPECT_EQ(kGoogleURL, ExecuteScriptAndReturnString("url")); - } - { - BrowserPluginMsg_LoadCommit_Params navigate_params; - navigate_params.url = GURL(kGoogleNewsURL); - BrowserPluginMsg_LoadCommit msg(instance_id, navigate_params); - browser_plugin->OnMessageReceived(msg); - // The URL variable should not change because we've removed the event - // listener. - EXPECT_EQ(kGoogleURL, ExecuteScriptAndReturnString("url")); - } -} - -// This test verifies that multiple event listeners fire that are registered -// on a single event type. -TEST_F(BrowserPluginTest, MultipleEventListeners) { - const char* kAddEventListener = - "var count = 0;" - "function nava(u) {" - " count++;" - "}" - "function navb(u) {" - " count++;" - "}" - "document.getElementById('browserplugin')." - " addEventListener('-internal-loadcommit', nava);" - "document.getElementById('browserplugin')." - " addEventListener('-internal-loadcommit', navb);"; - const char* kGoogleURL = "http://www.google.com/"; - - LoadHTML(GetHTMLForBrowserPluginObject().c_str()); - ExecuteJavaScript(kAddEventListener); - - MockBrowserPlugin* browser_plugin = GetCurrentPlugin(); - ASSERT_TRUE(browser_plugin); - int instance_id = browser_plugin->instance_id(); - - { - BrowserPluginMsg_LoadCommit_Params navigate_params; - navigate_params.url = GURL(kGoogleURL); - BrowserPluginMsg_LoadCommit msg(instance_id, navigate_params); - browser_plugin->OnMessageReceived(msg); - EXPECT_EQ(2, ExecuteScriptAndReturnInt("count")); - } -} - TEST_F(BrowserPluginTest, RemoveBrowserPluginOnExit) { LoadHTML(GetHTMLForBrowserPluginObject().c_str()); diff --git a/content/test/data/browser_plugin_embedder.html b/content/test/data/browser_plugin_embedder.html index 9501d19..914c12a 100644 --- a/content/test/data/browser_plugin_embedder.html +++ b/content/test/data/browser_plugin_embedder.html @@ -14,13 +14,6 @@ function loadStop(evt) { document.title = "loadStop"; } -var commitIsTopLevel; -function loadCommit(evt) { - var detail = JSON.parse(evt.detail); - document.title = "loadCommit:" + detail.url; - commitIsTopLevel = detail.isTopLevel; -} - var redirectOldUrl; var redirectNewUrl; function loadRedirect(event) { @@ -107,6 +100,5 @@ function receiveMessage(event) { plugin.addEventListener('-internal-loadredirect', loadRedirect); window.addEventListener('message', receiveMessage, false); plugin.addEventListener('-internal-loadstop', loadStop); - plugin.addEventListener('-internal-loadcommit', loadCommit); plugin.addEventListener('-internal-sizechanged', sizeChanged); </script> |