diff options
author | ericdingle@google.com <ericdingle@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 18:35:29 +0000 |
---|---|---|
committer | ericdingle@google.com <ericdingle@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 18:35:29 +0000 |
commit | 5cce3cd134a69809feab9086c0ff52cbd87bae0e (patch) | |
tree | e76f43828db3db5ec583fc5f43429c712e068c73 | |
parent | 656475d275524893e4e9b1f02469fe470721a14e (diff) | |
download | chromium_src-5cce3cd134a69809feab9086c0ff52cbd87bae0e.zip chromium_src-5cce3cd134a69809feab9086c0ff52cbd87bae0e.tar.gz chromium_src-5cce3cd134a69809feab9086c0ff52cbd87bae0e.tar.bz2 |
Disallow display of multiple experimental.extension.popup(...) windows.
Patch 1 contains twiz@'s code reviewed implementation from http://codereview.chromium.org/1512007.
This CL is to address the failure of release tests.
BUG=None
TEST=ExtensionApiTest.Popup
Review URL: http://codereview.chromium.org/1921003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46592 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/extension_host.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host.h | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_popup_api.cc | 86 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 6 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.h | 1 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host_delegate.h | 4 | ||||
-rw-r--r-- | chrome/common/extensions/api/extension_api.json | 4 | ||||
-rw-r--r-- | chrome/common/extensions/docs/extension.html | 2 | ||||
-rw-r--r-- | chrome/common/extensions/docs/history.html | 122 | ||||
-rw-r--r-- | chrome/common/notification_type.h | 5 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 4 | ||||
-rw-r--r-- | chrome/renderer/extensions/extension_process_bindings.cc | 2 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 3 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/popup/toolband.html | 66 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/popup/toolband_popup_a.html | 12 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/popup/toolband_popup_b.html | 12 |
16 files changed, 242 insertions, 91 deletions
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 3921aa6..3a6ccc3 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -439,7 +439,9 @@ void ExtensionHost::DocumentAvailableInMainFrame(RenderViewHost* rvh) { break; // No style sheet for other types, at the moment. } } +} +void ExtensionHost::DocumentOnLoadCompletedInMainFrame(RenderViewHost* rvh) { if (ViewType::EXTENSION_POPUP == GetRenderViewType()) { NotificationService::current()->Notify( NotificationType::EXTENSION_POPUP_VIEW_READY, diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h index 39d2f8b..013cb99 100644 --- a/chrome/browser/extensions/extension_host.h +++ b/chrome/browser/extensions/extension_host.h @@ -125,6 +125,8 @@ class ExtensionHost : public RenderViewHostDelegate, const ViewHostMsg_FrameNavigate_Params& params); virtual void DidStopLoading(); virtual void DocumentAvailableInMainFrame(RenderViewHost* render_view_host); + virtual void DocumentOnLoadCompletedInMainFrame( + RenderViewHost* render_view_host); virtual WebPreferences GetWebkitPrefs(); virtual void ProcessDOMUIMessage(const std::string& message, diff --git a/chrome/browser/extensions/extension_popup_api.cc b/chrome/browser/extensions/extension_popup_api.cc index a6f85f2..836b5b2 100644 --- a/chrome/browser/extensions/extension_popup_api.cc +++ b/chrome/browser/extensions/extension_popup_api.cc @@ -12,6 +12,9 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host_delegate.h" +#include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/notification_details.h" @@ -22,9 +25,6 @@ #include "gfx/point.h" #if defined(TOOLKIT_VIEWS) -#include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/render_view_host_delegate.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/views/extensions/extension_popup.h" #include "views/view.h" #include "views/focus/focus_manager.h" @@ -42,6 +42,8 @@ namespace { const char kBadAnchorArgument[] = "Invalid anchor argument."; const char kInvalidURLError[] = "Invalid URL."; const char kNotAnExtension[] = "Not an extension view."; +const char kPopupsDisallowed[] = + "Popups are only supported from toolstrip or tab-contents views."; // Keys. const wchar_t kUrlKey[] = L"url"; @@ -70,7 +72,8 @@ const char kRectangleChrome[] = "rectangle"; // containing view or any of *its* children. class ExtensionPopupHost : public ExtensionPopup::Observer, public views::WidgetFocusChangeListener, - public base::RefCounted<ExtensionPopupHost> { + public base::RefCounted<ExtensionPopupHost>, + public NotificationObserver { public: explicit ExtensionPopupHost(ExtensionFunctionDispatcher* dispatcher) : dispatcher_(dispatcher), popup_(NULL) { @@ -85,9 +88,18 @@ class ExtensionPopupHost : public ExtensionPopup::Observer, void set_popup(ExtensionPopup* popup) { popup_ = popup; + + // Now that a popup has been assigned, listen for subsequent popups being + // created in the same extension - we want to disallow more than one + // concurrently displayed popup windows. + registrar_.Add( + this, + NotificationType::EXTENSION_HOST_CREATED, + Source<ExtensionProcessManager>( + dispatcher_->profile()->GetExtensionProcessManager())); } - // Overriden from ExtensionPopup::Observer + // Overridden from ExtensionPopup::Observer virtual void ExtensionPopupClosed(ExtensionPopup* popup) { // Unregister the automation resource routing registered upon host // creation. @@ -119,7 +131,7 @@ class ExtensionPopupHost : public ExtensionPopup::Observer, Release(); // Balanced in ctor. } - // Overriden from views::WidgetFocusChangeListener + // Overridden from views::WidgetFocusChangeListener virtual void NativeFocusWillChange(gfx::NativeView focused_before, gfx::NativeView focused_now) { // If no view is to be focused, then Chrome was deactivated, so hide the @@ -129,11 +141,16 @@ class ExtensionPopupHost : public ExtensionPopup::Observer, dispatcher_->delegate()->GetNativeViewOfHost(); // If the widget hosting the popup contains the newly focused view, then - // don't dismiss the pop-up. - views::Widget* popup_root_widget = popup_->host()->view()->GetWidget(); - if (popup_root_widget && - popup_root_widget->ContainsNativeView(focused_now)) - return; + // don't dismiss the pop-up. Note that an ExtensionPopup must have an + // ExtensionHost, but an ExtensionHost may or may not have an + // ExtensionView view. We check to make sure. + ExtensionView* view = popup_->host()->view(); + if (view) { + views::Widget* popup_root_widget = view->GetWidget(); + if (popup_root_widget && + popup_root_widget->ContainsNativeView(focused_now)) + return; + } // If the widget or RenderWidgetHostView hosting the extension that // launched the pop-up is receiving focus, then don't dismiss the popup. @@ -156,6 +173,23 @@ class ExtensionPopupHost : public ExtensionPopup::Observer, &ExtensionPopup::Close)); } + // Overridden from NotificationObserver + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(NotificationType::EXTENSION_HOST_CREATED == type); + if (NotificationType::EXTENSION_HOST_CREATED == type) { + Details<ExtensionHost> details_host(details); + // Disallow multiple pop-ups from the same extension, by closing + // the presently opened popup during construction of any new popups. + if (ViewType::EXTENSION_POPUP == details_host->GetRenderViewType() && + popup_->host()->extension() == details_host->extension() && + Details<ExtensionHost>(popup_->host()) != details) { + popup_->Close(); + } + } + } + private: // Returns the AutomationResourceRoutingDelegate interface for |dispatcher|. static AutomationResourceRoutingDelegate* @@ -177,6 +211,8 @@ class ExtensionPopupHost : public ExtensionPopup::Observer, // A pointer to the popup. ExtensionPopup* popup_; + NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(ExtensionPopupHost); }; #endif // TOOLKIT_VIEWS @@ -211,6 +247,16 @@ void PopupShowFunction::Run() { } bool PopupShowFunction::RunImpl() { + // Popups may only be displayed from TAB_CONTENTS and EXTENSION_TOOLSTRIP + // views. + ViewType::Type view_type = + dispatcher()->render_view_host()->delegate()->GetRenderViewType(); + if (ViewType::EXTENSION_TOOLSTRIP != view_type && + ViewType::TAB_CONTENTS != view_type) { + error_ = kPopupsDisallowed; + return false; + } + EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST)); const ListValue* args = args_as_list(); @@ -272,7 +318,6 @@ bool PopupShowFunction::RunImpl() { return false; } -#if defined(TOOLKIT_VIEWS) gfx::Point origin(dom_left, dom_top); if (!dispatcher()->render_view_host()->view()) { error_ = kNotAnExtension; @@ -284,14 +329,6 @@ bool PopupShowFunction::RunImpl() { origin.Offset(content_bounds.x(), content_bounds.y()); gfx::Rect rect(origin.x(), origin.y(), dom_width, dom_height); - // Pop-up from extension views (ExtensionShelf, etc.), and drop-down when - // in a TabContents view. - ViewType::Type view_type = - dispatcher()->render_view_host()->delegate()->GetRenderViewType(); - BubbleBorder::ArrowLocation arrow_location = - view_type == ViewType::TAB_CONTENTS ? - BubbleBorder::TOP_LEFT : BubbleBorder::BOTTOM_LEFT; - // Get the correct native window to pass to ExtensionPopup. // ExtensionFunctionDispatcher::Delegate may provide a custom implementation // of this. @@ -300,6 +337,13 @@ bool PopupShowFunction::RunImpl() { if (!window) window = GetCurrentBrowser()->window()->GetNativeHandle(); +#if defined(TOOLKIT_VIEWS) + // Pop-up from extension views (ExtensionShelf, etc.), and drop-down when + // in a TabContents view. + BubbleBorder::ArrowLocation arrow_location = + view_type == ViewType::TAB_CONTENTS ? + BubbleBorder::TOP_LEFT : BubbleBorder::BOTTOM_LEFT; + // ExtensionPopupHost manages it's own lifetime. ExtensionPopupHost* popup_host = new ExtensionPopupHost(dispatcher()); popup_ = ExtensionPopup::Show(url, @@ -329,6 +373,8 @@ void PopupShowFunction::Observe(NotificationType type, type == NotificationType::EXTENSION_HOST_DESTROYED); DCHECK(popup_ != NULL); + // Wait for notification that the popup view is ready (and onload has been + // called), before completing the API call. if (popup_ && type == NotificationType::EXTENSION_POPUP_VIEW_READY && Details<ExtensionHost>(popup_->host()) == details) { SendResponse(true); diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 285e24e..ea0d855 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -727,6 +727,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnMsgDidStopLoading) IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentAvailableInMainFrame, OnMsgDocumentAvailableInMainFrame) + IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentOnLoadCompletedInMainFrame, + OnMsgDocumentOnLoadCompletedInMainFrame) IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache, OnMsgDidLoadResourceFromMemoryCache) IPC_MESSAGE_HANDLER(ViewHostMsg_DidDisplayInsecureContent, @@ -1056,6 +1058,10 @@ void RenderViewHost::OnMsgDocumentAvailableInMainFrame() { delegate_->DocumentAvailableInMainFrame(this); } +void RenderViewHost::OnMsgDocumentOnLoadCompletedInMainFrame() { + delegate_->DocumentOnLoadCompletedInMainFrame(this); +} + void RenderViewHost::OnMsgDidLoadResourceFromMemoryCache( const GURL& url, const std::string& frame_origin, diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index c5bec3c..8ca6c98 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -505,6 +505,7 @@ class RenderViewHost : public RenderWidgetHost { void OnMsgDidStartLoading(); void OnMsgDidStopLoading(); void OnMsgDocumentAvailableInMainFrame(); + void OnMsgDocumentOnLoadCompletedInMainFrame(); void OnMsgDidLoadResourceFromMemoryCache(const GURL& url, const std::string& frame_origin, const std::string& main_frame_origin, diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index 233099c..b8ca5f0 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -537,6 +537,10 @@ class RenderViewHostDelegate { // the document has finished parsing. virtual void DocumentAvailableInMainFrame(RenderViewHost* render_view_host) {} + // The onload handler in the RenderView's main frame has completed. + virtual void DocumentOnLoadCompletedInMainFrame( + RenderViewHost* render_view_host) {} + // The page wants to open a URL with the specified disposition. virtual void RequestOpenURL(const GURL& url, const GURL& referrer, diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index 5db6983..99e07f9 100644 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -134,9 +134,9 @@ "properties": { "type": { "type": "string", - "enum": ["tab", "infobar", "notification"], + "enum": ["tab", "infobar", "notification", "popup"], "optional": true, - "description": "The type of view to get. If omitted, returns all views (including background pages and tabs). Valid values: 'tab', 'infobar', 'notification'." + "description": "The type of view to get. If omitted, returns all views (including background pages and tabs). Valid values: 'tab', 'infobar', 'notification', 'popup'." }, "windowId": { "type": "integer", diff --git a/chrome/common/extensions/docs/extension.html b/chrome/common/extensions/docs/extension.html index 113b81a..3c7f0cb 100644 --- a/chrome/common/extensions/docs/extension.html +++ b/chrome/common/extensions/docs/extension.html @@ -1158,7 +1158,7 @@ For details, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The type of view to get. If omitted, returns all views (including background pages and tabs). Valid values: 'tab', 'infobar', 'notification'.</dd> + <dd>The type of view to get. If omitted, returns all views (including background pages and tabs). Valid values: 'tab', 'infobar', 'notification', 'popup'.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> diff --git a/chrome/common/extensions/docs/history.html b/chrome/common/extensions/docs/history.html index 7079c0c..a6bf9b1 100644 --- a/chrome/common/extensions/docs/history.html +++ b/chrome/common/extensions/docs/history.html @@ -266,9 +266,9 @@ <a href="#types">Types</a> <ol> <li> - <a href="#type-VisitItem">VisitItem</a> - </li><li> <a href="#type-HistoryItem">HistoryItem</a> + </li><li> + <a href="#type-VisitItem">VisitItem</a> </li> </ol> </li> @@ -1874,8 +1874,8 @@ For other examples and for help in viewing the source code, see <!-- iterates over all types --> <div class="apiItem"> - <a name="type-VisitItem"></a> - <h4>VisitItem</h4> + <a name="type-HistoryItem"></a> + <h4>HistoryItem</h4> <div> <dt> @@ -1905,7 +1905,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>An object encapsulating one visit to a URL.</dd> + <dd>An object encapsulating one result of a history query.</dd> <!-- OBJECT PROPERTIES --> <dd> @@ -1954,13 +1954,13 @@ For other examples and for help in viewing the source code, see </div><div> <div> <dt> - <var>visitId</var> + <var>url</var> <em> <!-- TYPE --> <div style="display:inline"> ( - <span class="optional" style="display: none; ">optional</span> + <span class="optional">optional</span> <span id="typeTemplate"> <span style="display: none; "> <a> Type</a> @@ -1980,7 +1980,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The unique identifier for this visit.</dd> + <dd>The URL navigated to by a user.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> @@ -1995,7 +1995,7 @@ For other examples and for help in viewing the source code, see </div><div> <div> <dt> - <var>visitTime</var> + <var>title</var> <em> <!-- TYPE --> @@ -2010,7 +2010,7 @@ For other examples and for help in viewing the source code, see <span style="display: none; "> array of <span><span></span></span> </span> - <span>number</span> + <span>string</span> </span> </span> ) @@ -2021,7 +2021,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>When this visit occurred, represented in milliseconds since the epoch.</dd> + <dd>The title of the history page.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> @@ -2036,13 +2036,13 @@ For other examples and for help in viewing the source code, see </div><div> <div> <dt> - <var>referringVisitId</var> + <var>lastVisitTime</var> <em> <!-- TYPE --> <div style="display:inline"> ( - <span class="optional" style="display: none; ">optional</span> + <span class="optional">optional</span> <span id="typeTemplate"> <span style="display: none; "> <a> Type</a> @@ -2051,7 +2051,7 @@ For other examples and for help in viewing the source code, see <span style="display: none; "> array of <span><span></span></span> </span> - <span>string</span> + <span>number</span> </span> </span> ) @@ -2062,7 +2062,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The visit_id of the referrer.</dd> + <dd>When this page was last loaded, represented in milliseconds since the epoch.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> @@ -2077,13 +2077,13 @@ For other examples and for help in viewing the source code, see </div><div> <div> <dt> - <var>transition</var> + <var>visitCount</var> <em> <!-- TYPE --> <div style="display:inline"> ( - <span class="optional" style="display: none; ">optional</span> + <span class="optional">optional</span> <span id="typeTemplate"> <span style="display: none; "> <a> Type</a> @@ -2092,7 +2092,7 @@ For other examples and for help in viewing the source code, see <span style="display: none; "> array of <span><span></span></span> </span> - <span>string</span> + <span>integer</span> </span> </span> ) @@ -2103,7 +2103,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The <a href="#transition_types">transition type</a> for this visit from its referrer.</dd> + <dd>The number of times the user has navigated to this page.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> @@ -2115,24 +2115,16 @@ For other examples and for help in viewing the source code, see </dl> </dd> </div> - </div> - </dl> - </dd> - </div> - - </div><div class="apiItem"> - <a name="type-HistoryItem"></a> - <h4>HistoryItem</h4> - - <div> + </div><div> + <div> <dt> - <var style="display: none; ">paramName</var> + <var>typedCount</var> <em> <!-- TYPE --> <div style="display:inline"> ( - <span class="optional" style="display: none; ">optional</span> + <span class="optional">optional</span> <span id="typeTemplate"> <span style="display: none; "> <a> Type</a> @@ -2141,7 +2133,7 @@ For other examples and for help in viewing the source code, see <span style="display: none; "> array of <span><span></span></span> </span> - <span>object</span> + <span>integer</span> </span> </span> ) @@ -2152,15 +2144,30 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>An object encapsulating one result of a history query.</dd> + <dd>The number of times the user has navigated to this page by typing in the address.</dd> <!-- OBJECT PROPERTIES --> - <dd> + <dd style="display: none; "> <dl> <div> <div> + </div> + </div> + </dl> + </dd> + </div> + </div> + </dl> + </dd> + </div> + + </div><div class="apiItem"> + <a name="type-VisitItem"></a> + <h4>VisitItem</h4> + + <div> <dt> - <var>id</var> + <var style="display: none; ">paramName</var> <em> <!-- TYPE --> @@ -2175,7 +2182,7 @@ For other examples and for help in viewing the source code, see <span style="display: none; "> array of <span><span></span></span> </span> - <span>string</span> + <span>object</span> </span> </span> ) @@ -2186,28 +2193,21 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The unique identifier for the item.</dd> + <dd>An object encapsulating one visit to a URL.</dd> <!-- OBJECT PROPERTIES --> - <dd style="display: none; "> + <dd> <dl> <div> <div> - </div> - </div> - </dl> - </dd> - </div> - </div><div> - <div> <dt> - <var>url</var> + <var>id</var> <em> <!-- TYPE --> <div style="display:inline"> ( - <span class="optional">optional</span> + <span class="optional" style="display: none; ">optional</span> <span id="typeTemplate"> <span style="display: none; "> <a> Type</a> @@ -2227,7 +2227,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The URL navigated to by a user.</dd> + <dd>The unique identifier for the item.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> @@ -2242,13 +2242,13 @@ For other examples and for help in viewing the source code, see </div><div> <div> <dt> - <var>title</var> + <var>visitId</var> <em> <!-- TYPE --> <div style="display:inline"> ( - <span class="optional">optional</span> + <span class="optional" style="display: none; ">optional</span> <span id="typeTemplate"> <span style="display: none; "> <a> Type</a> @@ -2268,7 +2268,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The title of the history page.</dd> + <dd>The unique identifier for this visit.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> @@ -2283,7 +2283,7 @@ For other examples and for help in viewing the source code, see </div><div> <div> <dt> - <var>lastVisitTime</var> + <var>visitTime</var> <em> <!-- TYPE --> @@ -2309,7 +2309,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>When this page was last loaded, represented in milliseconds since the epoch.</dd> + <dd>When this visit occurred, represented in milliseconds since the epoch.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> @@ -2324,13 +2324,13 @@ For other examples and for help in viewing the source code, see </div><div> <div> <dt> - <var>visitCount</var> + <var>referringVisitId</var> <em> <!-- TYPE --> <div style="display:inline"> ( - <span class="optional">optional</span> + <span class="optional" style="display: none; ">optional</span> <span id="typeTemplate"> <span style="display: none; "> <a> Type</a> @@ -2339,7 +2339,7 @@ For other examples and for help in viewing the source code, see <span style="display: none; "> array of <span><span></span></span> </span> - <span>integer</span> + <span>string</span> </span> </span> ) @@ -2350,7 +2350,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The number of times the user has navigated to this page.</dd> + <dd>The visit_id of the referrer.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> @@ -2365,13 +2365,13 @@ For other examples and for help in viewing the source code, see </div><div> <div> <dt> - <var>typedCount</var> + <var>transition</var> <em> <!-- TYPE --> <div style="display:inline"> ( - <span class="optional">optional</span> + <span class="optional" style="display: none; ">optional</span> <span id="typeTemplate"> <span style="display: none; "> <a> Type</a> @@ -2380,7 +2380,7 @@ For other examples and for help in viewing the source code, see <span style="display: none; "> array of <span><span></span></span> </span> - <span>integer</span> + <span>string</span> </span> </span> ) @@ -2391,7 +2391,7 @@ For other examples and for help in viewing the source code, see <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The number of times the user has navigated to this page by typing in the address.</dd> + <dd>The <a href="#transition_types">transition type</a> for this visit from its referrer.</dd> <!-- OBJECT PROPERTIES --> <dd style="display: none; "> diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index d8b46b4..00a6995 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -806,7 +806,10 @@ class NotificationType { EXTENSION_BACKGROUND_PAGE_READY, // Sent when a pop-up extension view is ready, so that notification may - // be sent to pending callbacks. + // be sent to pending callbacks. Note that this notification is sent + // after all onload callbacks have been invoked in the main frame. + // The details is the ExtensionHost* hosted within the popup, and the source + // is a Profile*. EXTENSION_POPUP_VIEW_READY, // Sent when a browser action's state has changed. The source is the diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 2877400..a34991c 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -1053,6 +1053,10 @@ IPC_BEGIN_MESSAGES(ViewHost) // finished. IPC_MESSAGE_ROUTED0(ViewHostMsg_DocumentAvailableInMainFrame) + // Sent when after the onload handler has been invoked for the document + // in the toplevel frame. + IPC_MESSAGE_ROUTED0(ViewHostMsg_DocumentOnLoadCompletedInMainFrame) + // Sent when the renderer loads a resource from its memory cache. // The security info is non empty if the resource was originally loaded over // a secure connection. diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc index 0e28a91..b9f4e29 100644 --- a/chrome/renderer/extensions/extension_process_bindings.cc +++ b/chrome/renderer/extensions/extension_process_bindings.cc @@ -299,7 +299,7 @@ class ExtensionImpl : public ExtensionBase { if (0 == popup_matcher.views()->Length()) return v8::Undefined(); - DCHECK(popup_matcher.views()->Has(0)); + DCHECK(1 == popup_matcher.views()->Length()); // Return the first view found. return popup_matcher.views()->Get(v8::Integer::New(0)); diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 45cef24..4823e2e 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -2727,7 +2727,8 @@ void RenderView::OnUserScriptIdleTriggered(WebFrame* frame) { } void RenderView::didHandleOnloadEvents(WebFrame* frame) { - // Ignore + if (webview()->mainFrame() == frame) + Send(new ViewHostMsg_DocumentOnLoadCompletedInMainFrame(routing_id_)); } void RenderView::didFailLoad(WebFrame* frame, const WebURLError& error) { diff --git a/chrome/test/data/extensions/api_test/popup/toolband.html b/chrome/test/data/extensions/api_test/popup/toolband.html index 5d04350..eb3fd43 100644 --- a/chrome/test/data/extensions/api_test/popup/toolband.html +++ b/chrome/test/data/extensions/api_test/popup/toolband.html @@ -111,8 +111,7 @@ window.onload = function() { }, function popupBlackBorder() { // Ensure that the test waits until the popup is dismissed. - chrome.test.listenOnce(chrome.experimental.popup.onClosed, - function() {}); + chrome.test.listenOnce(chrome.experimental.popup.onClosed); // Validate that displaying a pop-up with a black border still invokes // the callback successfully. Note that this test does not validate @@ -127,6 +126,62 @@ window.onload = function() { chrome.experimental.extension.getPopupView().close(); })); }, + function disallowMultiplePopups() { + // This test ensures that for a given extension with a popup displayed, + // displaying a subsequent popup will dismiss the first. + var showDetails1 = { + "relativeTo": document.getElementById("anchorHere"), + }; + + var showDetails2 = { + "relativeTo": document.getElementById("anchorHere2"), + "borderStyle": "rectangle" + }; + + // Track the number of popups opened and closed, so that we can signal + // the test as completed when appropriate. + var numberClosed = 0; + var doneListening = chrome.test.listenForever( + chrome.experimental.popup.onClosed, + function() { + // This test expects to open and close two popups, so signify that + // the test has succeeded, after closing the second popup. + if (++numberClosed == 2) { + doneListening(); + } + }); + + chrome.experimental.popup.show("toolband_popup_a.html", + showDetails1, + function() { + // Validate that the popup view returned is the one we expect. + chrome.test.assertEq( + 'a', + chrome.experimental.extension.getPopupView().getIdentity()); + + // Ensure that only one popup is open. + chrome.test.assertEq( + 1, + chrome.extension.getViews({type: "popup"}).length); + + chrome.experimental.popup.show("toolband_popup_b.html", + showDetails2, + function() { + // Validate that the first popup view is fully closed, and that + // getPopupView returns the most recently opened popup. + chrome.test.assertEq( + 'b', + chrome.experimental.extension.getPopupView().getIdentity()); + + // Ensure that only one popup is open. + chrome.test.assertEq( + 1, + chrome.extension.getViews({type: 'popup'}).length); + + chrome.experimental.extension.getPopupView().close(); + }); + }); + }, function popupChromeSizing() { // Ensure that the test waits until the popup is dismissed. chrome.test.listenOnce(chrome.experimental.popup.onClosed); @@ -159,8 +214,11 @@ window.onload = function() { </script> </head> <body> -<div> -<span id="anchorHere">TEST</span> +<div id="anchorHere"> +<span>TEST</span> +</div> +<div id="anchorHere2"> +<span>TESTING 2</span> </div> <form> <input id="entryForm" onfocus="onFormFocused();" onblur="onFormBlurred();"/> diff --git a/chrome/test/data/extensions/api_test/popup/toolband_popup_a.html b/chrome/test/data/extensions/api_test/popup/toolband_popup_a.html new file mode 100644 index 0000000..112d7f0 --- /dev/null +++ b/chrome/test/data/extensions/api_test/popup/toolband_popup_a.html @@ -0,0 +1,12 @@ +<html>
+<head>
+<script>
+function getIdentity() {
+ return 'a';
+}
+</script>
+</head>
+<body>
+Popup-A-Contents
+</body>
+</html>
\ No newline at end of file diff --git a/chrome/test/data/extensions/api_test/popup/toolband_popup_b.html b/chrome/test/data/extensions/api_test/popup/toolband_popup_b.html new file mode 100644 index 0000000..e8c7433 --- /dev/null +++ b/chrome/test/data/extensions/api_test/popup/toolband_popup_b.html @@ -0,0 +1,12 @@ +<html>
+<head>
+<script>
+function getIdentity() {
+ return 'b';
+}
+</script>
+</head>
+<body>
+Popup-B-Contents
+</body>
+</html>
\ No newline at end of file |