summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser.cc3
-rw-r--r--chrome/browser/extensions/extension_browser_actions_api.cc60
-rwxr-xr-xchrome/browser/extensions/extension_browser_actions_api.h4
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.cc10
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.h2
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc2
-rw-r--r--chrome/browser/extensions/image_loading_tracker.cc10
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.cc8
-rw-r--r--chrome/browser/views/browser_actions_container.cc5
-rwxr-xr-xchrome/common/extensions/api/extension_api.json90
-rwxr-xr-xchrome/common/extensions/docs/browserAction.html301
-rw-r--r--chrome/common/extensions/extension_resource_unittest.cc10
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc4
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js26
-rw-r--r--chrome/test/data/extensions/samples/gmail_browser_action/background.html50
-rwxr-xr-xchrome/test/data/extensions/samples/make_page_red/background.html6
-rw-r--r--chrome/test/data/extensions/samples/print_browser_action/background.html8
-rw-r--r--chrome/test/data/extensions/samples/test_browser_action/background.html8
-rw-r--r--chrome/test/data/extensions/samples/test_browser_action/manifest.json2
19 files changed, 464 insertions, 145 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 2bfd17a..60a78ce 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -1479,9 +1479,8 @@ void Browser::ExecuteCommand(int id) {
service->GetBrowserActions(false); // false means no popup actions.
for (size_t i = 0; i < browser_actions.size(); ++i) {
if (browser_actions[i]->command_id() == id) {
- int window_id = ExtensionTabUtil::GetWindowId(this);
ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
- profile_, browser_actions[i]->extension_id(), window_id);
+ profile_, browser_actions[i]->extension_id(), this);
return;
}
}
diff --git a/chrome/browser/extensions/extension_browser_actions_api.cc b/chrome/browser/extensions/extension_browser_actions_api.cc
index e671d15..d2cb604 100644
--- a/chrome/browser/extensions/extension_browser_actions_api.cc
+++ b/chrome/browser/extensions/extension_browser_actions_api.cc
@@ -17,30 +17,11 @@ const char kIconIndexOutOfBounds[] =
"Browser action icon index out of bounds.";
}
-bool BrowserActionSetNameFunction::RunImpl() {
- std::string title;
- EXTENSION_FUNCTION_VALIDATE(args_->GetAsString(&title));
-
- Extension* extension = dispatcher()->GetExtension();
- if (!extension->browser_action()) {
- error_ = kNoBrowserActionError;
- return false;
- }
-
- extension->browser_action_state()->set_title(title);
-
- NotificationService::current()->Notify(
- NotificationType::EXTENSION_BROWSER_ACTION_UPDATED,
- Source<ExtensionAction>(extension->browser_action()),
- Details<ExtensionActionState>(extension->browser_action_state()));
- return true;
-}
-
bool BrowserActionSetIconFunction::RunImpl() {
// setIcon can take a variant argument: either a canvas ImageData, or an
// icon index.
EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_BINARY) ||
- args_->IsType(Value::TYPE_INTEGER));
+ args_->IsType(Value::TYPE_DICTIONARY));
Extension* extension = dispatcher()->GetExtension();
if (!extension->browser_action()) {
@@ -58,8 +39,9 @@ bool BrowserActionSetIconFunction::RunImpl() {
extension->browser_action_state()->set_icon(bitmap.release());
} else {
int icon_index = -1;
- EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&icon_index));
-
+ EXTENSION_FUNCTION_VALIDATE(
+ static_cast<DictionaryValue*>(args_)->GetInteger(
+ L"iconIndex", &icon_index));
if (icon_index < 0 ||
static_cast<size_t>(icon_index) >=
extension->browser_action()->icon_paths().size()) {
@@ -77,9 +59,34 @@ bool BrowserActionSetIconFunction::RunImpl() {
return true;
}
+bool BrowserActionSetTitleFunction::RunImpl() {
+ EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_DICTIONARY));
+ DictionaryValue* details = static_cast<DictionaryValue*>(args_);
+
+ std::string title;
+ EXTENSION_FUNCTION_VALIDATE(details->GetString(L"title", &title));
+
+ Extension* extension = dispatcher()->GetExtension();
+ if (!extension->browser_action()) {
+ error_ = kNoBrowserActionError;
+ return false;
+ }
+
+ extension->browser_action_state()->set_title(title);
+
+ NotificationService::current()->Notify(
+ NotificationType::EXTENSION_BROWSER_ACTION_UPDATED,
+ Source<ExtensionAction>(extension->browser_action()),
+ Details<ExtensionActionState>(extension->browser_action_state()));
+ return true;
+}
+
bool BrowserActionSetBadgeTextFunction::RunImpl() {
+ EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_DICTIONARY));
+ DictionaryValue* details = static_cast<DictionaryValue*>(args_);
+
std::string badge_text;
- EXTENSION_FUNCTION_VALIDATE(args_->GetAsString(&badge_text));
+ EXTENSION_FUNCTION_VALIDATE(details->GetString(L"text", &badge_text));
Extension* extension = dispatcher()->GetExtension();
if (!extension->browser_action()) {
@@ -97,8 +104,11 @@ bool BrowserActionSetBadgeTextFunction::RunImpl() {
}
bool BrowserActionSetBadgeBackgroundColorFunction::RunImpl() {
- EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST));
- ListValue* list = static_cast<ListValue*>(args_);
+ EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_DICTIONARY));
+ DictionaryValue* details = static_cast<DictionaryValue*>(args_);
+
+ ListValue* list = NULL;
+ EXTENSION_FUNCTION_VALIDATE(details->GetList(L"color", &list));
EXTENSION_FUNCTION_VALIDATE(list->GetSize() == 4);
int color_array[4] = {0};
diff --git a/chrome/browser/extensions/extension_browser_actions_api.h b/chrome/browser/extensions/extension_browser_actions_api.h
index c5193d6..1becc70 100755
--- a/chrome/browser/extensions/extension_browser_actions_api.h
+++ b/chrome/browser/extensions/extension_browser_actions_api.h
@@ -7,12 +7,12 @@
#include "chrome/browser/extensions/extension_function.h"
-class BrowserActionSetNameFunction : public SyncExtensionFunction {
+class BrowserActionSetIconFunction : public SyncExtensionFunction {
virtual bool RunImpl();
DECLARE_EXTENSION_FUNCTION_NAME("browserAction.setName")
};
-class BrowserActionSetIconFunction : public SyncExtensionFunction {
+class BrowserActionSetTitleFunction : public SyncExtensionFunction {
virtual bool RunImpl();
DECLARE_EXTENSION_FUNCTION_NAME("browserAction.setIcon")
};
diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc
index 3604942..9a0f14a 100644
--- a/chrome/browser/extensions/extension_browser_event_router.cc
+++ b/chrome/browser/extensions/extension_browser_event_router.cc
@@ -375,10 +375,14 @@ void ExtensionBrowserEventRouter::PageActionExecuted(
}
void ExtensionBrowserEventRouter::BrowserActionExecuted(
- Profile* profile, const std::string& extension_id, int window_id) {
- ListValue args;
- args.Append(Value::CreateIntegerValue(window_id));
+ Profile* profile, const std::string& extension_id, Browser* browser) {
+ TabContents* tab_contents = NULL;
+ int tab_id = 0;
+ if (!ExtensionTabUtil::GetDefaultTab(browser, &tab_contents, &tab_id))
+ return;
+ ListValue args;
+ args.Append(ExtensionTabUtil::CreateTabValue(tab_contents));
std::string json_args;
JSONWriter::Write(&args, false, &json_args);
diff --git a/chrome/browser/extensions/extension_browser_event_router.h b/chrome/browser/extensions/extension_browser_event_router.h
index 681b448..dd56d29 100644
--- a/chrome/browser/extensions/extension_browser_event_router.h
+++ b/chrome/browser/extensions/extension_browser_event_router.h
@@ -62,7 +62,7 @@ class ExtensionBrowserEventRouter : public TabStripModelObserver,
// Browser Actions execute event.
void BrowserActionExecuted(Profile* profile,
const std::string& extension_id,
- int window_id);
+ Browser* browser);
// NotificationObserver.
void Observe(NotificationType type,
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 4b07658..1870701 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -103,8 +103,8 @@ void FactoryRegistry::ResetFunctions() {
RegisterFunction<DisablePageActionFunction>();
// Browser Actions.
- RegisterFunction<BrowserActionSetNameFunction>();
RegisterFunction<BrowserActionSetIconFunction>();
+ RegisterFunction<BrowserActionSetTitleFunction>();
RegisterFunction<BrowserActionSetBadgeTextFunction>();
RegisterFunction<BrowserActionSetBadgeBackgroundColorFunction>();
diff --git a/chrome/browser/extensions/image_loading_tracker.cc b/chrome/browser/extensions/image_loading_tracker.cc
index e141391..a2e4281 100644
--- a/chrome/browser/extensions/image_loading_tracker.cc
+++ b/chrome/browser/extensions/image_loading_tracker.cc
@@ -38,7 +38,6 @@ class ImageLoadingTracker::LoadImageTask : public Task {
index_(index) {}
void ReportBack(SkBitmap* image) {
- DCHECK(image);
callback_loop_->PostTask(FROM_HERE, NewRunnableMethod(tracker_,
&ImageLoadingTracker::OnImageLoaded,
image,
@@ -103,13 +102,12 @@ void ImageLoadingTracker::PostLoadImageTask(const ExtensionResource& resource) {
}
void ImageLoadingTracker::OnImageLoaded(SkBitmap* image, size_t index) {
- if (image == NULL) {
- NOTREACHED() << "Image failed to decode.";
- image = new SkBitmap();
- }
if (observer_)
observer_->OnImageLoaded(image, index);
- delete image;
+
+ if (image)
+ delete image;
+
if (--image_count_ == 0)
Release(); // We are no longer needed.
}
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
index cf90faa..7347876 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
@@ -93,7 +93,13 @@ class BrowserActionButton : public NotificationObserver,
// ImageLoadingTracker::Observer implementation.
void OnImageLoaded(SkBitmap* image, size_t index) {
- browser_action_icons_[index] = gfx::GdkPixbufFromSkBitmap(image);
+ if (image) {
+ browser_action_icons_[index] = gfx::GdkPixbufFromSkBitmap(image);
+ } else {
+ SkBitmap empty;
+ browser_action_icons_[index] = gfx::GdkPixbufFromSkBitmap(&empty);
+ }
+
OnStateUpdated();
}
diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc
index d7b610d..1c0733f 100644
--- a/chrome/browser/views/browser_actions_container.cc
+++ b/chrome/browser/views/browser_actions_container.cc
@@ -165,7 +165,7 @@ void BrowserActionButton::ButtonPressed(
void BrowserActionButton::OnImageLoaded(SkBitmap* image, size_t index) {
DCHECK(index < browser_action_icons_.size());
- browser_action_icons_[index] = *image;
+ browser_action_icons_[index] = image ? *image : SkBitmap();
if (index == browser_action_icons_.size() - 1) {
OnStateUpdated();
tracker_ = NULL; // The tracker object will delete itself when we return.
@@ -482,9 +482,8 @@ void BrowserActionsContainer::OnBrowserActionExecuted(
}
// Otherwise, we send the action to the extension.
- int window_id = ExtensionTabUtil::GetWindowId(toolbar_->browser());
ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
- profile_, browser_action.extension_id(), window_id);
+ profile_, browser_action.extension_id(), toolbar_->browser());
}
gfx::Size BrowserActionsContainer::GetPreferredSize() {
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index 5fe4d22..da80321 100755
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -824,32 +824,43 @@
"types": [],
"functions": [
{
- "name": "setName",
+ "name": "setTitle",
"type": "function",
- "description": "Sets the text for the browser action. Shows up in the tooltip if the browser action is visible, and in the menu item.",
+ "description": "Sets the title of the browser action. Shows up in the tooltip if the browser action is visible, and in the menu item.",
"parameters": [
- {"type": "string", "name": "name", "description": "The string the browser action should display when moused over.", "optional": false}
+ {
+ "name": "details",
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "description": "The string the browser action should display when moused over."
+ }
+ }
+ }
]
},
{
"name": "setIcon",
"type": "function",
- "description": "Sets the icon for the browser action. Can be up to about 22px square.",
+ "description": "Sets the icon for the browser action. The icon can be specified either as the index of one of the icons that was pre-specified in the manifest, or as the pixel data from a Canvas element. Either the iconIndex or the imageData property must be specified.",
"parameters": [
{
- "name": "iconId",
- "description": "An ImageData object from a canvas element, or a zero-based index into the |icons| vector specified in the manifest. This is useful to represent different browser action states. Example: A GMail checker could have a 'new email' icon and a 'no unread email' icon.",
- "choices": [
- {"type": "integer", "minimum": 0},
- {
- "type": "object",
- "properties": {
- "width": {"type": "integer", "description": "The image's width."},
- "height": {"type": "integer", "description": "The image's height."},
- "data": {"type": "any", "description": "The pixel data. Must be a CanvasPixelArray, with 32 bits per pixel and size equal to 4*width*height."}
- }
+ "name": "details",
+ "type": "object",
+ "properties": {
+ "imageData": {
+ "type": "any",
+ "description": "Pixel data for an image. Must be an ImageData object (eg from a <code>canvas</code> element).",
+ "optional": true
+ },
+ "iconIndex": {
+ "type": "integer",
+ "minimum": 0,
+ "description": "The zero-based index into the |icons| vector specified in the manifest.",
+ "optional": true
}
- ]
+ }
}
]
},
@@ -858,7 +869,16 @@
"type": "function",
"description": "Sets the badge text for the browser action. This is printed on top of the icon.",
"parameters": [
- {"type": "string", "name": "text", "description": "Any number of characters can be passed, but only about four can fit in the space."}
+ {
+ "name": "details",
+ "type": "object",
+ "properties": {
+ "text": {
+ "type": "string",
+ "description": "Any number of characters can be passed, but only about four can fit in the space."
+ }
+ }
+ }
]
},
{
@@ -867,21 +887,37 @@
"description": "Sets the background color for the badge.",
"parameters": [
{
- "type": "array",
- "name": "color",
- "description": "An array of four integers in the range [0,255] that make up the ARGB color for the bakground of the badge.",
- "items": {
- "type": "integer",
- "minimum": 0,
- "maximum": 255
- },
- "minItems": 4,
- "maxItems": 4
+ "name": "details",
+ "type": "object",
+ "properties": {
+ "color": {
+ "type": "array",
+ "description": "An array of four integers in the range [0,255] that make up the ARGB color for the bakground of the badge.",
+ "items": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 255
+ },
+ "minItems": 4,
+ "maxItems": 4
+ }
+ }
}
]
}
],
"events": [
+ {
+ "name": "onClicked",
+ "type": "function",
+ "description": "Fired when a page action button is clicked.",
+ "parameters": [
+ {
+ "name": "tab",
+ "$ref": "Tab"
+ }
+ ]
+ }
]
},
{
diff --git a/chrome/common/extensions/docs/browserAction.html b/chrome/common/extensions/docs/browserAction.html
index dc9b99a..c9ca19e 100755
--- a/chrome/common/extensions/docs/browserAction.html
+++ b/chrome/common/extensions/docs/browserAction.html
@@ -171,15 +171,15 @@
</li><li jsinstance="2">
<a href="#method-setIcon">setIcon</a>
</li><li jsinstance="*3">
- <a href="#method-setName">setName</a>
+ <a href="#method-setTitle">setTitle</a>
</li>
</ol>
</li>
- <li style="display: none; ">
+ <li>
<a href="#events">Events</a>
<ol>
- <li>
- <a href="#event-anchor">eventName</a>
+ <li jsinstance="*0">
+ <a href="#event-onClicked">onClicked</a>
</li>
</ol>
</li>
@@ -236,8 +236,8 @@
<div class="summary"><span style="display: none; ">void</span>
<!-- Note: intentionally longer 80 columns -->
- <span>chrome.browserAction.setBadgeBackgroundColor</span>(<span jsinstance="*0" class="null"><span style="display: none; ">, </span><span>array of integer</span>
- <var><span>color</span></var></span>)</div>
+ <span>chrome.browserAction.setBadgeBackgroundColor</span>(<span jsinstance="*0" class="null"><span style="display: none; ">, </span><span>object</span>
+ <var><span>details</span></var></span>)</div>
<div class="description">
<p class="todo" style="display: none; ">Undocumented.</p>
@@ -249,6 +249,42 @@
<div jsinstance="*0">
<div>
<dt>
+ <var>details</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional" style="display: none; ">optional</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>object</span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd>
+ <dl>
+ <div jsinstance="*0">
+ <div>
+ <dt>
<var>color</var>
<em>
@@ -297,6 +333,10 @@
</dl>
</dd>
</div>
+ </div>
+ </dl>
+ </dd>
+ </div>
</div>
</dl>
@@ -337,8 +377,8 @@
<div class="summary"><span style="display: none; ">void</span>
<!-- Note: intentionally longer 80 columns -->
- <span>chrome.browserAction.setBadgeText</span>(<span jsinstance="*0" class="null"><span style="display: none; ">, </span><span>string</span>
- <var><span>text</span></var></span>)</div>
+ <span>chrome.browserAction.setBadgeText</span>(<span jsinstance="*0" class="null"><span style="display: none; ">, </span><span>object</span>
+ <var><span>details</span></var></span>)</div>
<div class="description">
<p class="todo" style="display: none; ">Undocumented.</p>
@@ -350,6 +390,42 @@
<div jsinstance="*0">
<div>
<dt>
+ <var>details</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional" style="display: none; ">optional</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>object</span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd>
+ <dl>
+ <div jsinstance="*0">
+ <div>
+ <dt>
<var>text</var>
<em>
@@ -388,6 +464,10 @@
</dl>
</dd>
</div>
+ </div>
+ </dl>
+ </dd>
+ </div>
</div>
</dl>
@@ -428,12 +508,12 @@
<div class="summary"><span style="display: none; ">void</span>
<!-- Note: intentionally longer 80 columns -->
- <span>chrome.browserAction.setIcon</span>(<span jsinstance="*0" class="null"><span style="display: none; ">, </span><span>integer or object</span>
- <var><span>iconId</span></var></span>)</div>
+ <span>chrome.browserAction.setIcon</span>(<span jsinstance="*0" class="null"><span style="display: none; ">, </span><span>object</span>
+ <var><span>details</span></var></span>)</div>
<div class="description">
<p class="todo" style="display: none; ">Undocumented.</p>
- <p>Sets the icon for the browser action. Can be up to about 22px square.</p>
+ <p>Sets the icon for the browser action. The icon can be specified either as the index of one of the icons that was pre-specified in the manifest, or as the pixel data from a Canvas element. Either the iconIndex or the imageData property must be specified.</p>
<!-- PARAMETERS -->
<h4>Parameters</h4>
@@ -441,7 +521,7 @@
<div jsinstance="*0">
<div>
<dt>
- <var>iconId</var>
+ <var>details</var>
<em>
<!-- TYPE -->
@@ -456,7 +536,43 @@
<span style="display: none; ">
array of <span><span></span></span>
</span>
- <span>integer or object</span>
+ <span>object</span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd>
+ <dl>
+ <div jsinstance="0">
+ <div>
+ <dt>
+ <var>imageData</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>any</span>
</span>
</span>
)
@@ -467,7 +583,7 @@
<dd class="todo" style="display: none; ">
Undocumented.
</dd>
- <dd>An ImageData object from a canvas element, or a zero-based index into the |icons| vector specified in the manifest. This is useful to represent different browser action states. Example: A GMail checker could have a 'new email' icon and a 'no unread email' icon.</dd>
+ <dd>Pixel data for an image. Must be an ImageData object (eg from a <code>canvas</code> element).</dd>
<!-- OBJECT PROPERTIES -->
<dd style="display: none; ">
@@ -479,6 +595,51 @@
</dl>
</dd>
</div>
+ </div><div jsinstance="*1">
+ <div>
+ <dt>
+ <var>iconIndex</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>integer</span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>The zero-based index into the |icons| vector specified in the manifest.</dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd style="display: none; ">
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </dd>
+ </div>
+ </div>
+ </dl>
+ </dd>
+ </div>
</div>
</dl>
@@ -514,17 +675,17 @@
</div> <!-- /description -->
</div><div class="apiItem" jsinstance="*3">
- <a name="method-setName"></a> <!-- method-anchor -->
- <h4>setName</h4>
+ <a name="method-setTitle"></a> <!-- method-anchor -->
+ <h4>setTitle</h4>
<div class="summary"><span style="display: none; ">void</span>
<!-- Note: intentionally longer 80 columns -->
- <span>chrome.browserAction.setName</span>(<span jsinstance="*0" class=""><span style="display: none; ">, </span><span>string</span>
- <var><span>name</span></var></span>)</div>
+ <span>chrome.browserAction.setTitle</span>(<span jsinstance="*0" class="null"><span style="display: none; ">, </span><span>object</span>
+ <var><span>details</span></var></span>)</div>
<div class="description">
<p class="todo" style="display: none; ">Undocumented.</p>
- <p>Sets the text for the browser action. Shows up in the tooltip if the browser action is visible, and in the menu item.</p>
+ <p>Sets the title of the browser action. Shows up in the tooltip if the browser action is visible, and in the menu item.</p>
<!-- PARAMETERS -->
<h4>Parameters</h4>
@@ -532,7 +693,43 @@
<div jsinstance="*0">
<div>
<dt>
- <var>name</var>
+ <var>details</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional" style="display: none; ">optional</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>object</span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd>
+ <dl>
+ <div jsinstance="*0">
+ <div>
+ <dt>
+ <var>title</var>
<em>
<!-- TYPE -->
@@ -570,6 +767,10 @@
</dl>
</dd>
</div>
+ </div>
+ </dl>
+ </dd>
+ </div>
</div>
</dl>
@@ -609,32 +810,70 @@
</div> <!-- /apiGroup -->
<!-- EVENTS -->
- <div class="apiGroup" style="display: none; ">
+ <div class="apiGroup">
<a name="events"></a>
<h3 id="events">Events</h3>
<!-- iterates over all events -->
- <div class="apiItem">
- <a></a>
- <h4>event name</h4>
+ <div class="apiItem" jsinstance="*0">
+ <a name="event-onClicked"></a>
+ <h4>onClicked</h4>
<div class="summary">
<!-- Note: intentionally longer 80 columns -->
- <span class="subdued">chrome.bookmarks</span><span>onEvent</span><span class="subdued">.addListener</span>(function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>);
+ <span class="subdued">chrome.browserAction.</span><span>onClicked</span><span class="subdued">.addListener</span>(function(<span>Tab tab</span>) <span class="subdued">{...}</span>);
</div>
<div class="description">
- <p class="todo">Undocumented.</p>
- <p>
- A description from the json schema def of the event goes here.
- </p>
+ <p class="todo" style="display: none; ">Undocumented.</p>
+ <p>Fired when a page action button is clicked.</p>
<!-- PARAMETERS -->
<h4>Parameters</h4>
<dl>
- <div>
+ <div jsinstance="*0">
<div>
- </div>
+ <dt>
+ <var>tab</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional" style="display: none; ">optional</span>
+ <span id="typeTemplate">
+ <span>
+ <a href="tabs.html#type-Tab">Tab</a>
+ </span>
+ <span style="display: none; ">
+ <span>
+ array of <span><span></span></span>
+ </span>
+ <span>paramType</span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd style="display: none; ">
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </dd>
+ </div>
</div>
</dl>
diff --git a/chrome/common/extensions/extension_resource_unittest.cc b/chrome/common/extensions/extension_resource_unittest.cc
index c8ba976..7cc6ccf 100644
--- a/chrome/common/extensions/extension_resource_unittest.cc
+++ b/chrome/common/extensions/extension_resource_unittest.cc
@@ -67,8 +67,10 @@ TEST(ExtensionResourceTest, CreateWithBothResourcesOnDisk) {
ExtensionResource resource(temp.path(), FilePath().AppendASCII(filename));
FilePath resolved_path = resource.GetFilePath();
- EXPECT_EQ(l10n_path.AppendASCII(filename).value(), resolved_path.value());
- EXPECT_EQ(temp.path().value(), resource.extension_root().value());
- EXPECT_EQ(FilePath().AppendASCII(filename).value(),
- resource.relative_path().value());
+ EXPECT_EQ(ToLower(l10n_path.AppendASCII(filename).value()),
+ ToLower(resolved_path.value()));
+ EXPECT_EQ(ToLower(temp.path().value()),
+ ToLower(resource.extension_root().value()));
+ EXPECT_EQ(ToLower(FilePath().AppendASCII(filename).value()),
+ ToLower(resource.relative_path().value()));
}
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index 197bb42..801fb9d 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -411,7 +411,9 @@ class ExtensionImpl : public ExtensionBase {
// accepts a canvas ImageData object, so it needs to do extra processing
// before sending the request to the browser.
static v8::Handle<v8::Value> SetBrowserActionIcon(const v8::Arguments& args) {
- v8::Local<v8::Object> image_data = args[1]->ToObject();
+ v8::Local<v8::Object> details = args[1]->ToObject();
+ v8::Local<v8::Object> image_data =
+ details->Get(v8::String::New("imageData"))->ToObject();
v8::Local<v8::Object> data =
image_data->Get(v8::String::New("data"))->ToObject();
int width = image_data->Get(v8::String::New("width"))->Int32Value();
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
index 3ca88c4..c0e94a1 100644
--- a/chrome/renderer/resources/extension_process_bindings.js
+++ b/chrome/renderer/resources/extension_process_bindings.js
@@ -333,18 +333,32 @@ var chrome = chrome || {};
return GetL10nMessage(message_name, placeholders);
}
- apiFunctions["browserAction.setIcon"].handleRequest =
- function(idOrImageData) {
- if (typeof(idOrImageData) == "number") {
+ apiFunctions["browserAction.setIcon"].handleRequest = function(details) {
+ if ("iconIndex" in details) {
sendRequest(this.name, arguments, this.definition.parameters);
- } else if (typeof(idOrImageData) == "object") {
+ } else if ("imageData" in details) {
+ // Verify that this at least looks like an ImageData element.
+ // Unfortunately, we cannot use instanceof because the ImageData
+ // constructor is not public.
+ //
+ // We do this manually instead of using JSONSchema to avoid having these
+ // properties show up in the doc.
+ if (!("width" in details.imageData) ||
+ !("height" in details.imageData) ||
+ !("data" in details.imageData)) {
+ throw new Error(
+ "The imageData property must contain an ImageData object.");
+ }
sendCustomRequest(SetBrowserActionIcon, "browserAction.setIcon",
- idOrImageData, this.definition.parameters);
+ details, this.definition.parameters);
+ } else {
+ throw new Error(
+ "Either the iconIndex or imageData property must be specified.");
}
}
- setupPageActionEvents(extensionId);
setupBrowserActionEvent(extensionId);
+ setupPageActionEvents(extensionId);
setupToolstripEvents(GetRenderViewId());
});
})();
diff --git a/chrome/test/data/extensions/samples/gmail_browser_action/background.html b/chrome/test/data/extensions/samples/gmail_browser_action/background.html
index 7a5dd93..0c8b504 100644
--- a/chrome/test/data/extensions/samples/gmail_browser_action/background.html
+++ b/chrome/test/data/extensions/samples/gmail_browser_action/background.html
@@ -8,8 +8,8 @@ var browserActionHeight = 23;
var canvasContext;
var gmail = "http://mail.google.com/";
var gmailAtomRef = "http://mail.google.com/mail/feed/atom";
-var gmailIconName = 'gmail_logged_in.png';
-var gmailImage;
+var loggedInImage;
+var loggedOutImage;
var pollInterval = 1000 * 10; // 10 seconds
var requestTimeout = 1000 * 2; // 5 seconds
var rotation = 0;
@@ -26,16 +26,11 @@ chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) {
});
function init() {
- chrome.browserAction.setBadgeBackgroundColor([230, 190, 190, 190]);
- chrome.browserAction.setBadgeText("?");
-
- var canvas = document.getElementById('canvas');
+ var canvas = document.getElementById('canvas');
+ loggedInImage = document.getElementById('logged_in');
+ loggedOutImage = document.getElementById('logged_out');
canvasContext = canvas.getContext('2d');
- gmailImage = new Image();
- gmailImage.onload = function() {
- window.setTimeout(startRequest, 0);
- }
- gmailImage.src = gmailIconName;
+ startRequest();
}
function scheduleRequest() {
@@ -50,6 +45,7 @@ function startRequest() {
scheduleRequest();
},
function() {
+ showLoggedOut();
scheduleRequest();
}
);
@@ -142,23 +138,37 @@ function animateFlip() {
} else {
rotation = 0;
drawIconAtRotation();
- chrome.browserAction.setBadgeText(unreadCount);
- chrome.browserAction.setBadgeBackgroundColor([255, 208, 0, 24]);
- chrome.browserAction.setName(unreadCount + " unread emails");
+ chrome.browserAction.setBadgeText({text:unreadCount});
+ chrome.browserAction.setBadgeBackgroundColor({color:[255, 208, 0, 24]});
+ chrome.browserAction.setTitle({title:unreadCount + " unread emails"});
}
}
+function showLoggedOut() {
+ canvasContext.save();
+ canvasContext.clearRect(0, 0, browserActionWidth, browserActionHeight);
+ canvasContext.translate(browserActionWidth/2, browserActionHeight/2);
+ canvasContext.drawImage(loggedOutImage,
+ -loggedOutImage.width/2 - 1, -loggedOutImage.height/2);
+ canvasContext.restore();
+
+ chrome.browserAction.setIcon({imageData:canvasContext.getImageData(0, 0,
+ browserActionWidth,browserActionHeight)});
+ chrome.browserAction.setBadgeBackgroundColor({color:[230, 190, 190, 190]});
+ chrome.browserAction.setBadgeText({text:"?"});
+}
+
function drawIconAtRotation() {
canvasContext.save();
canvasContext.clearRect(0, 0, browserActionWidth, browserActionHeight);
canvasContext.translate(browserActionWidth/2, browserActionHeight/2);
canvasContext.rotate(2*Math.PI*ease(rotation));
- canvasContext.drawImage(gmailImage, -gmailImage.width/2,
- -gmailImage.height/2);
+ canvasContext.drawImage(loggedInImage,
+ -loggedInImage.width/2 - 1, -loggedInImage.height/2);
canvasContext.restore();
- chrome.browserAction.setIcon(canvasContext.getImageData(0, 0,
- browserActionWidth,browserActionHeight));
+ chrome.browserAction.setIcon({imageData:canvasContext.getImageData(0, 0,
+ browserActionWidth,browserActionHeight)});
}
function goToInbox() {
@@ -166,13 +176,15 @@ function goToInbox() {
}
// Called when the user clicks on the browser action.
-chrome.browserAction.onClicked.addListener(function(windowId) {
+chrome.browserAction.onClicked.addListener(function(tab) {
goToInbox();
});
</script>
</head>
<body onload="init()">
+<img id="logged_in" src="gmail_logged_in.png">
+<img id="logged_out" src="gmail_not_logged_in.png">
<canvas id="canvas" width="27" height="23">
</body>
</html>
diff --git a/chrome/test/data/extensions/samples/make_page_red/background.html b/chrome/test/data/extensions/samples/make_page_red/background.html
index 30631d2..5e348e7 100755
--- a/chrome/test/data/extensions/samples/make_page_red/background.html
+++ b/chrome/test/data/extensions/samples/make_page_red/background.html
@@ -2,15 +2,15 @@
<head>
<script>
// Called when the user clicks on the browser action.
- chrome.browserAction.onClicked.addListener(function(windowId) {
+ chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {code:"document.body.bgColor='red'"});
});
- chrome.browserAction.setBadgeBackgroundColor([100, 0, 200, 0]);
+ chrome.browserAction.setBadgeBackgroundColor({color:[100, 0, 200, 0]});
var i = 0;
window.setInterval(function() {
- chrome.browserAction.setBadgeText(String(i));
+ chrome.browserAction.setBadgeText({text:String(i)});
i++;
}, 10);
</script>
diff --git a/chrome/test/data/extensions/samples/print_browser_action/background.html b/chrome/test/data/extensions/samples/print_browser_action/background.html
index 75501ea..5b3f930 100644
--- a/chrome/test/data/extensions/samples/print_browser_action/background.html
+++ b/chrome/test/data/extensions/samples/print_browser_action/background.html
@@ -2,11 +2,9 @@
<head>
<script>
// Called when the user clicks on the browser action.
- chrome.browserAction.onClicked.addListener(function(windowId) {
- chrome.tabs.getSelected(windowId, function(tab) {
- var action_url = "javascript:window.print();";
- chrome.tabs.update(tab.id, {url: action_url});
- });
+ chrome.browserAction.onClicked.addListener(function(tab) {
+ var action_url = "javascript:window.print();";
+ chrome.tabs.update(tab.id, {url: action_url});
});
</script>
</head>
diff --git a/chrome/test/data/extensions/samples/test_browser_action/background.html b/chrome/test/data/extensions/samples/test_browser_action/background.html
index d15d283..8170e86 100644
--- a/chrome/test/data/extensions/samples/test_browser_action/background.html
+++ b/chrome/test/data/extensions/samples/test_browser_action/background.html
@@ -4,11 +4,11 @@
// Called when the user clicks on the browser action.
var clicks = 0;
chrome.browserAction.onClicked.addListener(function() {
- chrome.browserAction.setIcon(clicks);
+ chrome.browserAction.setIcon({iconIndex:clicks});
clicks++;
- // We only have 2 icons, but cycle through 3 icons to test the
+ // We only have 1 icon, but cycle through 3 icons to test the
// out-of-bounds index bug.
- if (clicks > 3)
+ if (clicks > 2)
clicks = 0;
});
var i = 0;
@@ -17,7 +17,7 @@
// Don't animate while in "click" mode.
if (clicks > 0) return;
i++;
- chrome.browserAction.setIcon(draw(i*2, i*4));
+ chrome.browserAction.setIcon({imageData:draw(i*2, i*4)});
}, 50);
function draw(starty, startx) {
diff --git a/chrome/test/data/extensions/samples/test_browser_action/manifest.json b/chrome/test/data/extensions/samples/test_browser_action/manifest.json
index 146668799..1134f3c 100644
--- a/chrome/test/data/extensions/samples/test_browser_action/manifest.json
+++ b/chrome/test/data/extensions/samples/test_browser_action/manifest.json
@@ -5,6 +5,6 @@
"background_page": "background.html",
"browser_action": {
"name": "First icon",
- "icons": ["badicon.png", "print_16x16.png"]
+ "icons": ["print_16x16.png"]
}
}