summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorericdingle@google.com <ericdingle@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 18:35:29 +0000
committerericdingle@google.com <ericdingle@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 18:35:29 +0000
commit5cce3cd134a69809feab9086c0ff52cbd87bae0e (patch)
treee76f43828db3db5ec583fc5f43429c712e068c73
parent656475d275524893e4e9b1f02469fe470721a14e (diff)
downloadchromium_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.cc2
-rw-r--r--chrome/browser/extensions/extension_host.h2
-rw-r--r--chrome/browser/extensions/extension_popup_api.cc86
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc6
-rw-r--r--chrome/browser/renderer_host/render_view_host.h1
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h4
-rw-r--r--chrome/common/extensions/api/extension_api.json4
-rw-r--r--chrome/common/extensions/docs/extension.html2
-rw-r--r--chrome/common/extensions/docs/history.html122
-rw-r--r--chrome/common/notification_type.h5
-rw-r--r--chrome/common/render_messages_internal.h4
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc2
-rw-r--r--chrome/renderer/render_view.cc3
-rw-r--r--chrome/test/data/extensions/api_test/popup/toolband.html66
-rw-r--r--chrome/test/data/extensions/api_test/popup/toolband_popup_a.html12
-rw-r--r--chrome/test/data/extensions/api_test/popup/toolband_popup_b.html12
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