summaryrefslogtreecommitdiffstats
path: root/chrome/common
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-11-25 19:40:10 +0000
committerBen Murdoch <benm@google.com>2010-12-03 13:52:53 +0000
commit4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7 (patch)
tree938665d93a11fe7a6d0124e3c1e020d1f9d3f947 /chrome/common
parent7c627d87728a355737862918d144f98f69406954 (diff)
downloadexternal_chromium-4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7.zip
external_chromium-4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7.tar.gz
external_chromium-4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7.tar.bz2
Merge Chromium at r66597: Initial merge by git.
Change-Id: I9639f8a997f90ec219573aa22a49f5dbde78cc7b
Diffstat (limited to 'chrome/common')
-rw-r--r--chrome/common/automation_constants.h36
-rw-r--r--chrome/common/automation_messages.cc9
-rw-r--r--chrome/common/automation_messages.h645
-rw-r--r--chrome/common/automation_messages_internal.h1460
-rw-r--r--chrome/common/child_process_info.cc3
-rw-r--r--chrome/common/child_process_info.h3
-rw-r--r--chrome/common/child_process_logging.h2
-rw-r--r--chrome/common/child_process_logging_mac.mm22
-rw-r--r--chrome/common/chrome_switches.cc60
-rw-r--r--chrome/common/chrome_switches.h17
-rw-r--r--chrome/common/common_param_traits.cc14
-rw-r--r--chrome/common/common_param_traits.h6
-rw-r--r--chrome/common/common_param_traits_unittest.cc24
-rw-r--r--chrome/common/common_resources.grd1
-rw-r--r--chrome/common/extensions/api/extension_api.json86
-rw-r--r--chrome/common/extensions/docs/a11y.html10
-rw-r--r--chrome/common/extensions/docs/api_index.html12
-rw-r--r--chrome/common/extensions/docs/api_other.html10
-rw-r--r--chrome/common/extensions/docs/autoupdate.html10
-rw-r--r--chrome/common/extensions/docs/background_pages.html10
-rw-r--r--chrome/common/extensions/docs/bookmarks.html10
-rw-r--r--chrome/common/extensions/docs/browserAction.html10
-rwxr-xr-xchrome/common/extensions/docs/build/build.py9
-rw-r--r--chrome/common/extensions/docs/build/directory.py169
-rw-r--r--chrome/common/extensions/docs/content_scripts.html10
-rw-r--r--chrome/common/extensions/docs/contextMenus.html10
-rw-r--r--chrome/common/extensions/docs/cookies.html10
-rw-r--r--chrome/common/extensions/docs/crx.html10
-rw-r--r--chrome/common/extensions/docs/css/ApiRefStyles.css7
-rw-r--r--chrome/common/extensions/docs/devguide.html10
-rw-r--r--chrome/common/extensions/docs/docs.html10
-rw-r--r--chrome/common/extensions/docs/events.html10
-rw-r--r--chrome/common/extensions/docs/examples/api/bookmarks/basic.zipbin5647 -> 5687 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/browserAction/make_page_red.zipbin3930 -> 3970 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/browserAction/print.zipbin1614 -> 1654 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/browserAction/set_icon_path.zipbin15530 -> 15570 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/browserAction/set_page_color.zipbin5245 -> 5285 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/contextMenus/basic.zipbin3512 -> 3552 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/cookies.zipbin9255 -> 9295 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/history/showHistory.zipbin9608 -> 9648 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/i18n/cld.zipbin1310 -> 1350 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/i18n/getMessage.zipbin6739 -> 6779 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/idle/idle_simple.zipbin11992 -> 12032 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/infobars/sandwichbar.zipbin16055 -> 16095 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/messaging/timer.zipbin3558 -> 3598 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/notifications.zipbin49949 -> 49989 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/omnibox/extension-docs.zipbin74406 -> 74348 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/omnibox/extension-docs/background.html12
-rw-r--r--chrome/common/extensions/docs/examples/api/omnibox/extension-docs/manifest.json3
-rw-r--r--chrome/common/extensions/docs/examples/api/omnibox/simple-example.zipbin1208 -> 1185 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/omnibox/simple-example/background.html4
-rw-r--r--chrome/common/extensions/docs/examples/api/omnibox/simple-example/manifest.json3
-rw-r--r--chrome/common/extensions/docs/examples/api/override/blank_ntp.zipbin699 -> 739 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/override/override_igoogle.zipbin496 -> 536 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content.zipbin14181 -> 14221 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url.zipbin15175 -> 15215 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/pageAction/set_icon.zipbin8421 -> 8461 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/processes/process_monitor.zipbin5226 -> 5266 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/processes/show_tabs.zipbin6112 -> 6152 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/tabs/inspector.zipbin46521 -> 46561 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/tabs/screenshot.zipbin6202 -> 6242 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/windows/merge_windows.zipbin12134 -> 12174 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/benchmark.zipbin316130 -> 258748 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/buildbot.zipbin28059 -> 28099 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar.zipbin0 -> 40571 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/_locales/en/messages.json38
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/images/calendar_logo.gifbin0 -> 3828 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/images/icon-128.gifbin0 -> 5232 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16.gifbin0 -> 413 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16_bw.gifbin0 -> 1019 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/javascript/background.js728
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/javascript/options.js73
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/javascript/util.js14
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/manifest.json18
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/views/background.html16
-rw-r--r--chrome/common/extensions/docs/examples/extensions/calendar/views/options.html87
-rw-r--r--chrome/common/extensions/docs/examples/extensions/chrome_search.zipbin3885 -> 3734 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/chrome_search/background.html10
-rw-r--r--chrome/common/extensions/docs/examples/extensions/chrome_search/manifest.json18
-rw-r--r--chrome/common/extensions/docs/examples/extensions/email_this_page.zipbin11437 -> 11477 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/fx.zipbin37859 -> 37899 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/gdocs.zipbin164256 -> 164296 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/gmail.zipbin57647 -> 57687 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/imageinfo.zipbin45525 -> 46603 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/mappy.zipbin21151 -> 21191 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news.zipbin22018 -> 65941 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/_locales/en/messages.json102
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/css/feed.css101
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/css/options.css121
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/feed.html310
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/images/buzz.pngbin0 -> 892 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/images/delete-icon.pngbin0 -> 1030 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/images/fb.pngbin0 -> 428 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/images/news.gifbin0 -> 3431 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/images/news_action.png (renamed from chrome/common/extensions/docs/examples/extensions/news/news_action.png)bin1109 -> 1109 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/images/news_icon.png (renamed from chrome/common/extensions/docs/examples/extensions/news/news_icon.png)bin10782 -> 10782 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/images/sprite_arrows.gif (renamed from chrome/common/extensions/docs/examples/extensions/news/sprite_arrows.gif)bin1328 -> 1328 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/images/twitter.pngbin0 -> 588 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/javascript/feed.js388
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/javascript/options.js395
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/javascript/util.js29
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/manifest.json19
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/views/background.html27
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/views/feed.html146
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news/views/options.html166
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news_a11y.zipbin25262 -> 25302 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/news_i18n.zipbin27689 -> 27729 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/oauth_contacts.zipbin71913 -> 71953 bytes
-rw-r--r--chrome/common/extensions/docs/examples/extensions/wave.zipbin98759 -> 98799 bytes
-rw-r--r--chrome/common/extensions/docs/examples/howto/contentscript_xhr.zipbin9769 -> 9809 bytes
-rw-r--r--chrome/common/extensions/docs/examples/tutorials/analytics.zipbin16263 -> 16303 bytes
-rw-r--r--chrome/common/extensions/docs/examples/tutorials/getstarted.zipbin10844 -> 10884 bytes
-rw-r--r--chrome/common/extensions/docs/experimental.clipboard.html10
-rw-r--r--chrome/common/extensions/docs/experimental.contextMenus.html10
-rw-r--r--chrome/common/extensions/docs/experimental.cookies.html10
-rw-r--r--chrome/common/extensions/docs/experimental.history.html10
-rw-r--r--chrome/common/extensions/docs/experimental.html11
-rw-r--r--chrome/common/extensions/docs/experimental.idle.html10
-rw-r--r--chrome/common/extensions/docs/experimental.infobars.html10
-rw-r--r--chrome/common/extensions/docs/experimental.omnibox.html1178
-rw-r--r--chrome/common/extensions/docs/experimental.processes.html10
-rw-r--r--chrome/common/extensions/docs/experimental.proxy.html10
-rw-r--r--chrome/common/extensions/docs/experimental.sidebar.html10
-rw-r--r--chrome/common/extensions/docs/experimental.webNavigation.html10
-rw-r--r--chrome/common/extensions/docs/experimental.webRequest.html10
-rw-r--r--chrome/common/extensions/docs/extension.html141
-rw-r--r--chrome/common/extensions/docs/external_extensions.html10
-rw-r--r--chrome/common/extensions/docs/faq.html10
-rw-r--r--chrome/common/extensions/docs/getstarted.html10
-rw-r--r--chrome/common/extensions/docs/history.html10
-rw-r--r--chrome/common/extensions/docs/hosting.html10
-rw-r--r--chrome/common/extensions/docs/i18n-messages.html10
-rw-r--r--chrome/common/extensions/docs/i18n.html10
-rw-r--r--chrome/common/extensions/docs/idle.html10
-rw-r--r--chrome/common/extensions/docs/index.html10
-rw-r--r--chrome/common/extensions/docs/management.html10
-rw-r--r--chrome/common/extensions/docs/manifest.html10
-rw-r--r--chrome/common/extensions/docs/match_patterns.html10
-rw-r--r--chrome/common/extensions/docs/messaging.html10
-rw-r--r--chrome/common/extensions/docs/notifications.html10
-rw-r--r--chrome/common/extensions/docs/npapi.html10
-rw-r--r--chrome/common/extensions/docs/options.html10
-rw-r--r--chrome/common/extensions/docs/override.html10
-rw-r--r--chrome/common/extensions/docs/overview.html10
-rw-r--r--chrome/common/extensions/docs/packaging.html10
-rw-r--r--chrome/common/extensions/docs/pageAction.html10
-rw-r--r--chrome/common/extensions/docs/permission_warnings.html14
-rw-r--r--chrome/common/extensions/docs/samples.html194
-rw-r--r--chrome/common/extensions/docs/samples.json1615
-rw-r--r--chrome/common/extensions/docs/server/chromeextensionsdocs.py2
-rw-r--r--chrome/common/extensions/docs/tabs.html10
-rw-r--r--chrome/common/extensions/docs/template/api_template.html10
-rw-r--r--chrome/common/extensions/docs/themes.html10
-rw-r--r--chrome/common/extensions/docs/tut_analytics.html10
-rw-r--r--chrome/common/extensions/docs/tut_debugging.html10
-rw-r--r--chrome/common/extensions/docs/tut_oauth.html10
-rw-r--r--chrome/common/extensions/docs/tutorials.html10
-rw-r--r--chrome/common/extensions/docs/whats_new.html10
-rw-r--r--chrome/common/extensions/docs/windows.html10
-rw-r--r--chrome/common/extensions/docs/xhr.html10
-rw-r--r--chrome/common/extensions/extension.cc43
-rw-r--r--chrome/common/extensions/extension.h4
-rw-r--r--chrome/common/extensions/extension_constants.cc9
-rw-r--r--chrome/common/extensions/extension_constants.h15
-rw-r--r--chrome/common/extensions/extension_l10n_util.cc4
-rw-r--r--chrome/common/extensions/extension_l10n_util_unittest.cc33
-rw-r--r--chrome/common/extensions/extension_resource.cc34
-rw-r--r--chrome/common/extensions/extension_resource.h28
-rw-r--r--chrome/common/extensions/url_pattern_unittest.cc30
-rw-r--r--chrome/common/extensions/user_script_unittest.cc18
-rw-r--r--chrome/common/gpu_info.cc14
-rw-r--r--chrome/common/gpu_info.h15
-rw-r--r--chrome/common/gpu_messages.cc90
-rw-r--r--chrome/common/gpu_messages_unittest.cc4
-rw-r--r--chrome/common/json_schema_validator.cc503
-rw-r--r--chrome/common/json_schema_validator.h211
-rw-r--r--chrome/common/json_schema_validator_unittest.cc51
-rw-r--r--chrome/common/json_schema_validator_unittest_base.cc628
-rw-r--r--chrome/common/json_schema_validator_unittest_base.h59
-rw-r--r--chrome/common/metrics_helpers.cc90
-rw-r--r--chrome/common/metrics_helpers.h71
-rw-r--r--chrome/common/multi_process_lock.h39
-rw-r--r--chrome/common/multi_process_lock_linux.cc108
-rw-r--r--chrome/common/multi_process_lock_mac.cc54
-rw-r--r--chrome/common/multi_process_lock_unittest.cc157
-rw-r--r--chrome/common/multi_process_lock_win.cc58
-rw-r--r--chrome/common/net/gaia/gaia_auth_consumer.h2
-rw-r--r--chrome/common/net/gaia/gaia_auth_fetcher.cc (renamed from chrome/common/net/gaia/gaia_authenticator2.cc)110
-rw-r--r--chrome/common/net/gaia/gaia_auth_fetcher.h (renamed from chrome/common/net/gaia/gaia_authenticator2.h)41
-rw-r--r--chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc (renamed from chrome/common/net/gaia/gaia_authenticator2_unittest.cc)102
-rw-r--r--chrome/common/net/gaia/gaia_auth_fetcher_unittest.h (renamed from chrome/common/net/gaia/gaia_authenticator2_unittest.h)10
-rw-r--r--chrome/common/net/test_url_fetcher_factory.cc77
-rw-r--r--chrome/common/net/test_url_fetcher_factory.h68
-rw-r--r--chrome/common/net/url_fetcher_unittest.cc6
-rw-r--r--chrome/common/notification_service.h4
-rw-r--r--chrome/common/page_type.h17
-rw-r--r--chrome/common/pepper_plugin_registry.cc29
-rw-r--r--chrome/common/pepper_plugin_registry.h17
-rw-r--r--chrome/common/policy_constants.cc12
-rw-r--r--chrome/common/policy_constants.h11
-rw-r--r--chrome/common/pref_names.cc45
-rw-r--r--chrome/common/pref_names.h22
-rw-r--r--chrome/common/render_messages.cc2
-rw-r--r--chrome/common/render_messages_internal.h26
-rw-r--r--chrome/common/render_messages_params.cc13
-rw-r--r--chrome/common/render_messages_params.h16
-rw-r--r--chrome/common/resource_dispatcher_unittest.cc8
-rw-r--r--chrome/common/sandbox_mac.mm27
-rw-r--r--chrome/common/sandbox_policy.cc84
-rw-r--r--chrome/common/security_style.h35
-rw-r--r--chrome/common/url_constants.cc21
-rw-r--r--chrome/common/url_constants.h9
-rw-r--r--chrome/common/web_app_schema.json58
-rw-r--r--chrome/common/web_apps.cc323
-rw-r--r--chrome/common/web_apps.h109
-rw-r--r--chrome/common/web_apps_unittest.cc190
216 files changed, 10074 insertions, 2898 deletions
diff --git a/chrome/common/automation_constants.h b/chrome/common/automation_constants.h
index 6959af7..13b120e 100644
--- a/chrome/common/automation_constants.h
+++ b/chrome/common/automation_constants.h
@@ -15,6 +15,42 @@ extern const char kJSONProxyNoProxy[];
extern const char kJSONProxyPacUrl[];
extern const char kJSONProxyBypassList[];
extern const char kJSONProxyServer[];
+
+// Amount of time to wait before querying the browser.
+static const int kSleepTime = 250;
}
+// Used by AutomationProxy, declared here so that other headers don't need
+// to include automation_proxy.h.
+enum AutomationLaunchResult {
+ AUTOMATION_LAUNCH_RESULT_INVALID = -1,
+ AUTOMATION_SUCCESS,
+ AUTOMATION_TIMEOUT,
+ AUTOMATION_VERSION_MISMATCH,
+ AUTOMATION_CREATE_TAB_FAILED,
+ AUTOMATION_SERVER_CRASHED,
+};
+
+enum AutomationMsg_NavigationResponseValues {
+ AUTOMATION_MSG_NAVIGATION_ERROR = 0,
+ AUTOMATION_MSG_NAVIGATION_SUCCESS,
+ AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
+};
+
+enum AutomationMsg_ExtensionResponseValues {
+ AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED = 0,
+ AUTOMATION_MSG_EXTENSION_INSTALL_FAILED
+};
+
+// Used in the AutomationMsg_GetExtensionProperty to identify which extension
+// property should be retrieved, instead of having separate messages for each
+// property.
+enum AutomationMsg_ExtensionProperty {
+ AUTOMATION_MSG_EXTENSION_ID = 0,
+ AUTOMATION_MSG_EXTENSION_NAME,
+ AUTOMATION_MSG_EXTENSION_VERSION,
+ AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX,
+};
+
+
#endif // CHROME_COMMON_AUTOMATION_CONSTANTS_H__
diff --git a/chrome/common/automation_messages.cc b/chrome/common/automation_messages.cc
new file mode 100644
index 0000000..df6d0e2
--- /dev/null
+++ b/chrome/common/automation_messages.cc
@@ -0,0 +1,9 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/automation_messages.h"
+
+#define MESSAGES_INTERNAL_IMPL_FILE \
+ "chrome/common/automation_messages_internal.h"
+#include "ipc/ipc_message_impl_macros.h"
diff --git a/chrome/common/automation_messages.h b/chrome/common/automation_messages.h
new file mode 100644
index 0000000..0f8ec7c
--- /dev/null
+++ b/chrome/common/automation_messages.h
@@ -0,0 +1,645 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_AUTOMATION_MESSAGES_H__
+#define CHROME_COMMON_AUTOMATION_MESSAGES_H__
+#pragma once
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "chrome/common/automation_constants.h"
+#include "chrome/common/common_param_traits.h"
+#include "chrome/common/page_type.h"
+#include "chrome/common/security_style.h"
+#include "chrome/common/common_param_traits.h"
+#include "gfx/rect.h"
+#include "net/base/upload_data.h"
+
+struct AutomationMsg_Find_Params {
+ // Unused value, which exists only for backwards compat.
+ int unused;
+
+ // The word(s) to find on the page.
+ string16 search_string;
+
+ // Whether to search forward or backward within the page.
+ bool forward;
+
+ // Whether search should be Case sensitive.
+ bool match_case;
+
+ // Whether this operation is first request (Find) or a follow-up (FindNext).
+ bool find_next;
+};
+
+namespace IPC {
+
+template <>
+struct ParamTraits<AutomationMsg_Find_Params> {
+ typedef AutomationMsg_Find_Params param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.unused);
+ WriteParam(m, p.search_string);
+ WriteParam(m, p.forward);
+ WriteParam(m, p.match_case);
+ WriteParam(m, p.find_next);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return
+ ReadParam(m, iter, &p->unused) &&
+ ReadParam(m, iter, &p->search_string) &&
+ ReadParam(m, iter, &p->forward) &&
+ ReadParam(m, iter, &p->match_case) &&
+ ReadParam(m, iter, &p->find_next);
+ }
+ static void Log(const param_type& p, std::string* l) {
+ l->append("<AutomationMsg_Find_Params>");
+ }
+};
+
+template <>
+struct ParamTraits<AutomationMsg_NavigationResponseValues> {
+ typedef AutomationMsg_NavigationResponseValues param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteInt(p);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ int type;
+ if (!m->ReadInt(iter, &type))
+ return false;
+ *p = static_cast<AutomationMsg_NavigationResponseValues>(type);
+ return true;
+ }
+ static void Log(const param_type& p, std::string* l) {
+ std::string control;
+ switch (p) {
+ case AUTOMATION_MSG_NAVIGATION_ERROR:
+ control = "AUTOMATION_MSG_NAVIGATION_ERROR";
+ break;
+ case AUTOMATION_MSG_NAVIGATION_SUCCESS:
+ control = "AUTOMATION_MSG_NAVIGATION_SUCCESS";
+ break;
+ case AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED:
+ control = "AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED";
+ break;
+ default:
+ control = "UNKNOWN";
+ break;
+ }
+
+ LogParam(control, l);
+ }
+};
+
+template <>
+struct ParamTraits<AutomationMsg_ExtensionResponseValues> {
+ typedef AutomationMsg_ExtensionResponseValues param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteInt(p);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ int type;
+ if (!m->ReadInt(iter, &type))
+ return false;
+ *p = static_cast<AutomationMsg_ExtensionResponseValues>(type);
+ return true;
+ }
+ static void Log(const param_type& p, std::string* l) {
+ std::string control;
+ switch (p) {
+ case AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED:
+ control = "AUTOMATION_MSG_EXTENSION_INSTALL_SUCCEEDED";
+ break;
+ case AUTOMATION_MSG_EXTENSION_INSTALL_FAILED:
+ control = "AUTOMATION_MSG_EXTENSION_INSTALL_FAILED";
+ break;
+ default:
+ control = "UNKNOWN";
+ break;
+ }
+
+ LogParam(control, l);
+ }
+};
+
+template <>
+struct ParamTraits<AutomationMsg_ExtensionProperty> {
+ typedef AutomationMsg_ExtensionProperty param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteInt(p);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ int type;
+ if (!m->ReadInt(iter, &type))
+ return false;
+ *p = static_cast<AutomationMsg_ExtensionProperty>(type);
+ return true;
+ }
+ static void Log(const param_type& p, std::string* l) {
+ std::string control;
+ switch (p) {
+ case AUTOMATION_MSG_EXTENSION_ID:
+ control = "AUTOMATION_MSG_EXTENSION_ID";
+ break;
+ case AUTOMATION_MSG_EXTENSION_NAME:
+ control = "AUTOMATION_MSG_EXTENSION_NAME";
+ break;
+ case AUTOMATION_MSG_EXTENSION_VERSION:
+ control = "AUTOMATION_MSG_EXTENSION_VERSION";
+ break;
+ case AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX:
+ control = "AUTOMATION_MSG_EXTENSION_BROWSER_ACTION_INDEX";
+ break;
+ default:
+ control = "UNKNOWN";
+ break;
+ }
+
+ LogParam(control, l);
+ }
+};
+
+template <>
+struct ParamTraits<SecurityStyle> {
+ typedef SecurityStyle param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteInt(p);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ int type;
+ if (!m->ReadInt(iter, &type))
+ return false;
+ *p = static_cast<SecurityStyle>(type);
+ return true;
+ }
+ static void Log(const param_type& p, std::string* l) {
+ std::string control;
+ switch (p) {
+ case SECURITY_STYLE_UNKNOWN:
+ control = "SECURITY_STYLE_UNKNOWN";
+ break;
+ case SECURITY_STYLE_UNAUTHENTICATED:
+ control = "SECURITY_STYLE_UNAUTHENTICATED";
+ break;
+ case SECURITY_STYLE_AUTHENTICATION_BROKEN:
+ control = "SECURITY_STYLE_AUTHENTICATION_BROKEN";
+ break;
+ case SECURITY_STYLE_AUTHENTICATED:
+ control = "SECURITY_STYLE_AUTHENTICATED";
+ break;
+ default:
+ control = "UNKNOWN";
+ break;
+ }
+
+ LogParam(control, l);
+ }
+};
+
+template <>
+struct ParamTraits<PageType> {
+ typedef PageType param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteInt(p);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ int type;
+ if (!m->ReadInt(iter, &type))
+ return false;
+ *p = static_cast<PageType>(type);
+ return true;
+ }
+ static void Log(const param_type& p, std::string* l) {
+ std::string control;
+ switch (p) {
+ case NORMAL_PAGE:
+ control = "NORMAL_PAGE";
+ break;
+ case ERROR_PAGE:
+ control = "ERROR_PAGE";
+ break;
+ case INTERSTITIAL_PAGE:
+ control = "INTERSTITIAL_PAGE";
+ break;
+ default:
+ control = "UNKNOWN";
+ break;
+ }
+
+ LogParam(control, l);
+ }
+};
+
+#if defined(OS_WIN)
+struct Reposition_Params {
+ HWND window;
+ HWND window_insert_after;
+ int left;
+ int top;
+ int width;
+ int height;
+ int flags;
+ bool set_parent;
+ HWND parent_window;
+};
+
+// Traits for SetWindowPos_Params structure to pack/unpack.
+template <>
+struct ParamTraits<Reposition_Params> {
+ typedef Reposition_Params param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.window);
+ WriteParam(m, p.window_insert_after);
+ WriteParam(m, p.left);
+ WriteParam(m, p.top);
+ WriteParam(m, p.width);
+ WriteParam(m, p.height);
+ WriteParam(m, p.flags);
+ WriteParam(m, p.set_parent);
+ WriteParam(m, p.parent_window);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return ReadParam(m, iter, &p->window) &&
+ ReadParam(m, iter, &p->window_insert_after) &&
+ ReadParam(m, iter, &p->left) &&
+ ReadParam(m, iter, &p->top) &&
+ ReadParam(m, iter, &p->width) &&
+ ReadParam(m, iter, &p->height) &&
+ ReadParam(m, iter, &p->flags) &&
+ ReadParam(m, iter, &p->set_parent) &&
+ ReadParam(m, iter, &p->parent_window);
+ }
+ static void Log(const param_type& p, std::string* l) {
+ l->append("(");
+ LogParam(p.window, l);
+ l->append(", ");
+ LogParam(p.window_insert_after, l);
+ l->append(", ");
+ LogParam(p.left, l);
+ l->append(", ");
+ LogParam(p.top, l);
+ l->append(", ");
+ LogParam(p.width, l);
+ l->append(", ");
+ LogParam(p.height, l);
+ l->append(", ");
+ LogParam(p.flags, l);
+ l->append(", ");
+ LogParam(p.set_parent, l);
+ l->append(", ");
+ LogParam(p.parent_window, l);
+ l->append(")");
+ }
+};
+#endif // defined(OS_WIN)
+
+struct AutomationURLRequest {
+ std::string url;
+ std::string method;
+ std::string referrer;
+ std::string extra_request_headers;
+ scoped_refptr<net::UploadData> upload_data;
+ int resource_type; // see webkit/glue/resource_type.h
+ int load_flags; // see net/base/load_flags.h
+};
+
+// Traits for AutomationURLRequest structure to pack/unpack.
+template <>
+struct ParamTraits<AutomationURLRequest> {
+ typedef AutomationURLRequest param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.url);
+ WriteParam(m, p.method);
+ WriteParam(m, p.referrer);
+ WriteParam(m, p.extra_request_headers);
+ WriteParam(m, p.upload_data);
+ WriteParam(m, p.resource_type);
+ WriteParam(m, p.load_flags);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return ReadParam(m, iter, &p->url) &&
+ ReadParam(m, iter, &p->method) &&
+ ReadParam(m, iter, &p->referrer) &&
+ ReadParam(m, iter, &p->extra_request_headers) &&
+ ReadParam(m, iter, &p->upload_data) &&
+ ReadParam(m, iter, &p->resource_type) &&
+ ReadParam(m, iter, &p->load_flags);
+ }
+ static void Log(const param_type& p, std::string* l) {
+ l->append("(");
+ LogParam(p.url, l);
+ l->append(", ");
+ LogParam(p.method, l);
+ l->append(", ");
+ LogParam(p.referrer, l);
+ l->append(", ");
+ LogParam(p.extra_request_headers, l);
+ l->append(", ");
+ LogParam(p.upload_data, l);
+ l->append(", ");
+ LogParam(p.resource_type, l);
+ l->append(", ");
+ LogParam(p.load_flags, l);
+ l->append(")");
+ }
+};
+
+struct AutomationURLResponse {
+ std::string mime_type;
+ std::string headers;
+ int64 content_length;
+ base::Time last_modified;
+ std::string redirect_url;
+ int redirect_status;
+};
+
+// Traits for AutomationURLResponse structure to pack/unpack.
+template <>
+struct ParamTraits<AutomationURLResponse> {
+ typedef AutomationURLResponse param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.mime_type);
+ WriteParam(m, p.headers);
+ WriteParam(m, p.content_length);
+ WriteParam(m, p.last_modified);
+ WriteParam(m, p.redirect_url);
+ WriteParam(m, p.redirect_status);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return ReadParam(m, iter, &p->mime_type) &&
+ ReadParam(m, iter, &p->headers) &&
+ ReadParam(m, iter, &p->content_length) &&
+ ReadParam(m, iter, &p->last_modified) &&
+ ReadParam(m, iter, &p->redirect_url) &&
+ ReadParam(m, iter, &p->redirect_status);
+ }
+ static void Log(const param_type& p, std::string* l) {
+ l->append("(");
+ LogParam(p.mime_type, l);
+ l->append(", ");
+ LogParam(p.headers, l);
+ l->append(", ");
+ LogParam(p.content_length, l);
+ l->append(", ");
+ LogParam(p.last_modified, l);
+ l->append(", ");
+ LogParam(p.redirect_url, l);
+ l->append(", ");
+ LogParam(p.redirect_status, l);
+ l->append(")");
+ }
+};
+
+struct ExternalTabSettings {
+ gfx::NativeWindow parent;
+ gfx::Rect dimensions;
+ unsigned int style;
+ bool is_off_the_record;
+ bool load_requests_via_automation;
+ bool handle_top_level_requests;
+ GURL initial_url;
+ GURL referrer;
+ bool infobars_enabled;
+ bool route_all_top_level_navigations;
+};
+
+// Traits for ExternalTabSettings structure to pack/unpack.
+template <>
+struct ParamTraits<ExternalTabSettings> {
+ typedef ExternalTabSettings param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.parent);
+ WriteParam(m, p.dimensions);
+ WriteParam(m, p.style);
+ WriteParam(m, p.is_off_the_record);
+ WriteParam(m, p.load_requests_via_automation);
+ WriteParam(m, p.handle_top_level_requests);
+ WriteParam(m, p.initial_url);
+ WriteParam(m, p.referrer);
+ WriteParam(m, p.infobars_enabled);
+ WriteParam(m, p.route_all_top_level_navigations);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return ReadParam(m, iter, &p->parent) &&
+ ReadParam(m, iter, &p->dimensions) &&
+ ReadParam(m, iter, &p->style) &&
+ ReadParam(m, iter, &p->is_off_the_record) &&
+ ReadParam(m, iter, &p->load_requests_via_automation) &&
+ ReadParam(m, iter, &p->handle_top_level_requests) &&
+ ReadParam(m, iter, &p->initial_url) &&
+ ReadParam(m, iter, &p->referrer) &&
+ ReadParam(m, iter, &p->infobars_enabled) &&
+ ReadParam(m, iter, &p->route_all_top_level_navigations);
+ }
+ static void Log(const param_type& p, std::string* l) {
+ l->append("(");
+ LogParam(p.parent, l);
+ l->append(", ");
+ LogParam(p.dimensions, l);
+ l->append(", ");
+ LogParam(p.style, l);
+ l->append(", ");
+ LogParam(p.is_off_the_record, l);
+ l->append(", ");
+ LogParam(p.load_requests_via_automation, l);
+ l->append(", ");
+ LogParam(p.handle_top_level_requests, l);
+ l->append(", ");
+ LogParam(p.initial_url, l);
+ l->append(", ");
+ LogParam(p.referrer, l);
+ l->append(", ");
+ LogParam(p.infobars_enabled, l);
+ l->append(", ");
+ LogParam(p.route_all_top_level_navigations, l);
+ l->append(")");
+ }
+};
+
+struct NavigationInfo {
+ int navigation_type;
+ int relative_offset;
+ int navigation_index;
+ std::wstring title;
+ GURL url;
+ GURL referrer;
+ SecurityStyle security_style;
+ bool displayed_insecure_content;
+ bool ran_insecure_content;
+};
+
+// Traits for NavigationInfo structure to pack/unpack.
+template <>
+struct ParamTraits<NavigationInfo> {
+ typedef NavigationInfo param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.navigation_type);
+ WriteParam(m, p.relative_offset);
+ WriteParam(m, p.navigation_index);
+ WriteParam(m, p.title);
+ WriteParam(m, p.url);
+ WriteParam(m, p.referrer);
+ WriteParam(m, p.security_style);
+ WriteParam(m, p.displayed_insecure_content);
+ WriteParam(m, p.ran_insecure_content);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return ReadParam(m, iter, &p->navigation_type) &&
+ ReadParam(m, iter, &p->relative_offset) &&
+ ReadParam(m, iter, &p->navigation_index) &&
+ ReadParam(m, iter, &p->title) &&
+ ReadParam(m, iter, &p->url) &&
+ ReadParam(m, iter, &p->referrer) &&
+ ReadParam(m, iter, &p->security_style) &&
+ ReadParam(m, iter, &p->displayed_insecure_content) &&
+ ReadParam(m, iter, &p->ran_insecure_content);
+ }
+ static void Log(const param_type& p, std::string* l) {
+ l->append("(");
+ LogParam(p.navigation_type, l);
+ l->append(", ");
+ LogParam(p.relative_offset, l);
+ l->append(", ");
+ LogParam(p.navigation_index, l);
+ l->append(", ");
+ LogParam(p.title, l);
+ l->append(", ");
+ LogParam(p.url, l);
+ l->append(", ");
+ LogParam(p.referrer, l);
+ l->append(", ");
+ LogParam(p.security_style, l);
+ l->append(", ");
+ LogParam(p.displayed_insecure_content, l);
+ l->append(", ");
+ LogParam(p.ran_insecure_content, l);
+ l->append(")");
+ }
+};
+
+// A stripped down version of ContextMenuParams in webkit/glue/context_menu.h.
+struct MiniContextMenuParams {
+ // The x coordinate for displaying the menu.
+ int screen_x;
+
+ // The y coordinate for displaying the menu.
+ int screen_y;
+
+ // This is the URL of the link that encloses the node the context menu was
+ // invoked on.
+ GURL link_url;
+
+ // The link URL to be used ONLY for "copy link address". We don't validate
+ // this field in the frontend process.
+ GURL unfiltered_link_url;
+
+ // This is the source URL for the element that the context menu was
+ // invoked on. Example of elements with source URLs are img, audio, and
+ // video.
+ GURL src_url;
+
+ // This is the URL of the top level page that the context menu was invoked
+ // on.
+ GURL page_url;
+
+ // This is the URL of the subframe that the context menu was invoked on.
+ GURL frame_url;
+};
+
+// Traits for MiniContextMenuParams structure to pack/unpack.
+template <>
+struct ParamTraits<MiniContextMenuParams> {
+ typedef MiniContextMenuParams param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.screen_x);
+ WriteParam(m, p.screen_y);
+ WriteParam(m, p.link_url);
+ WriteParam(m, p.unfiltered_link_url);
+ WriteParam(m, p.src_url);
+ WriteParam(m, p.page_url);
+ WriteParam(m, p.frame_url);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return ReadParam(m, iter, &p->screen_x) &&
+ ReadParam(m, iter, &p->screen_y) &&
+ ReadParam(m, iter, &p->link_url) &&
+ ReadParam(m, iter, &p->unfiltered_link_url) &&
+ ReadParam(m, iter, &p->src_url) &&
+ ReadParam(m, iter, &p->page_url) &&
+ ReadParam(m, iter, &p->frame_url);
+ }
+ static void Log(const param_type& p, std::string* l) {
+ l->append("(");
+ LogParam(p.screen_x, l);
+ l->append(", ");
+ LogParam(p.screen_y, l);
+ l->append(", ");
+ LogParam(p.link_url, l);
+ l->append(", ");
+ LogParam(p.unfiltered_link_url, l);
+ l->append(", ");
+ LogParam(p.src_url, l);
+ l->append(", ");
+ LogParam(p.page_url, l);
+ l->append(", ");
+ LogParam(p.frame_url, l);
+ l->append(")");
+ }
+};
+
+struct AttachExternalTabParams {
+ uint64 cookie;
+ GURL url;
+ gfx::Rect dimensions;
+ int disposition;
+ bool user_gesture;
+ std::string profile_name;
+};
+
+template <>
+struct ParamTraits<AttachExternalTabParams> {
+ typedef AttachExternalTabParams param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.cookie);
+ WriteParam(m, p.url);
+ WriteParam(m, p.dimensions);
+ WriteParam(m, p.disposition);
+ WriteParam(m, p.user_gesture);
+ WriteParam(m, p.profile_name);
+ }
+
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return ReadParam(m, iter, &p->cookie) &&
+ ReadParam(m, iter, &p->url) &&
+ ReadParam(m, iter, &p->dimensions) &&
+ ReadParam(m, iter, &p->disposition) &&
+ ReadParam(m, iter, &p->user_gesture) &&
+ ReadParam(m, iter, &p->profile_name);
+ }
+
+ static void Log(const param_type& p, std::string* l) {
+ l->append("(");
+ LogParam(p.cookie, l);
+ l->append(", ");
+ LogParam(p.url, l);
+ l->append(", ");
+ LogParam(p.dimensions, l);
+ l->append(", ");
+ LogParam(p.disposition, l);
+ l->append(", ");
+ LogParam(p.user_gesture, l);
+ l->append(",");
+ LogParam(p.profile_name, l);
+ l->append(")");
+ }
+};
+
+} // namespace IPC
+
+#define MESSAGES_INTERNAL_FILE \
+ "chrome/common/automation_messages_internal.h"
+#include "ipc/ipc_message_macros.h"
+
+#endif // CHROME_COMMON_AUTOMATION_MESSAGES_H__
diff --git a/chrome/common/automation_messages_internal.h b/chrome/common/automation_messages_internal.h
new file mode 100644
index 0000000..e2198a1
--- /dev/null
+++ b/chrome/common/automation_messages_internal.h
@@ -0,0 +1,1460 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Defines the IPC messages used by the automation interface.
+
+// This header is meant to be included in multiple passes, hence no traditional
+// header guard.
+// See ipc_message_macros.h for explanation of the macros and passes.
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/string16.h"
+#include "chrome/common/content_settings.h"
+#include "chrome/common/navigation_types.h"
+#include "chrome/test/automation/autocomplete_edit_proxy.h"
+#include "gfx/point.h"
+#include "gfx/rect.h"
+#include "googleurl/src/gurl.h"
+#include "ipc/ipc_message_macros.h"
+#include "net/url_request/url_request_status.h"
+
+// NOTE: All IPC messages have either a routing_id of 0 (for asynchronous
+// messages), or one that's been assigned by the proxy (for calls
+// which expect a response). The routing_id shouldn't be used for
+// any other purpose in these message types.
+
+// NOTE: All the new IPC messages should go at the end (before IPC_END_MESSAGES)
+// The IPC message IDs are part of an enum and hence the value
+// assumed to be constant across the builds may change.
+// The messages AutomationMsg_WindowHWND* in particular should not change
+// since the PageCyclerReferenceTest depends on the correctness of the
+// message IDs across the builds.
+
+IPC_BEGIN_MESSAGES(Automation)
+
+ // This message is fired when the AutomationProvider is up and running
+ // in the app (the app is not fully up at this point). The parameter to this
+ // message is the version string of the automation provider. This parameter
+ // is defined to be the version string as returned by
+ // chrome::VersionInfo::Version().
+ // The client can choose to use this version string to decide whether or not
+ // it can talk to the provider.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_Hello, std::string)
+
+ // This message is fired when the initial tab(s) are finished loading.
+ IPC_MESSAGE_ROUTED0(AutomationMsg_InitialLoadsComplete)
+
+ // This message notifies the AutomationProvider to append a new tab the
+ // window with the given handle. The return value contains the index of
+ // the new tab, or -1 if the request failed.
+ // The second parameter is the url to be loaded in the new tab.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_AppendTab, int, GURL, int)
+
+ // This message requests the (zero-based) index for the currently
+ // active tab in the window with the given handle. The return value contains
+ // the index of the active tab, or -1 if the request failed.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_ActiveTabIndex, int, int)
+
+ // This message notifies the AutomationProvider to active the tab.
+ // The first parameter is the handle to window resource.
+ // The second parameter is the (zero-based) index to be activated
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_ActivateTab, int, int, int)
+
+ // This message requests the cookie value for given url in the
+ // profile of the tab identified by the second parameter. The first
+ // parameter is the URL string. The response contains the length of the
+ // cookie value string. On failure, this length = -1.
+ IPC_SYNC_MESSAGE_ROUTED2_2(AutomationMsg_GetCookies, GURL, int,
+ int, std::string)
+
+ // This message notifies the AutomationProvider to set and broadcast a cookie
+ // with given name and value for the given url in the profile of the tab
+ // identified by the third parameter. The first parameter is the URL
+ // string, and the second parameter is the cookie name and value to be set.
+ // The return value is a non-negative value on success.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_SetCookie, GURL, std::string,
+ int, int)
+
+ // This message notifies the AutomationProvider to navigate to a specified
+ // url in the tab with given handle. The first parameter is the handle to
+ // the tab resource. The second parameter is the target url. The return
+ // value contains a status code which is nonnegative on success.
+ // See AutomationMsg_NavigationResponseValues for the return value.
+ //
+ // Deprecated in favor of
+ // AutomationMsg_NavigateToURLBlockUntilNavigationsComplete.
+ // TODO(phajdan.jr): Remove when the reference build gets updated.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_NavigateToURL, int, GURL,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message is used to implement the asynchronous version of
+ // NavigateToURL.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_NavigationAsync,
+ int /* tab handle */,
+ GURL,
+ bool /* result */)
+
+ // This message notifies the AutomationProvider to navigate back in session
+ // history in the tab with given handle. The first parameter is the handle
+ // to the tab resource.
+ // See AutomationMsg_NavigationResponseValues for the navigation response
+ // values.
+ //
+ // Deprecated in favor of AutomationMsg_GoBackBlockUntilNavigationsComplete.
+ // TODO(phajdan.jr): Remove when the reference build gets updated.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_GoBack, int,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message notifies the AutomationProvider to navigate forward in session
+ // history in the tab with given handle. The first parameter is the handle
+ // to the tab resource.
+ // See AutomationMsg_NavigationResponseValues for the navigation response
+ // values.
+ //
+ // Deprecated in favor of
+ // AutomationMsg_GoForwardBlockUntilNavigationsComplete.
+ // TODO(phajdan.jr): Remove when the reference build gets updated.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_GoForward, int,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message requests the number of browser windows that the app currently
+ // has open. The return value is the number of windows.
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_BrowserWindowCount, int)
+
+ // This message requests the handle (int64 app-unique identifier) of the
+ // window with the given (zero-based) index. On error, the returned handle
+ // value is 0.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_BrowserWindow, int, int)
+
+ // This message requests the number of tabs in the window with the given
+ // handle. The return value contains the number of tabs, or -1 if the
+ // request failed.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_TabCount, int, int)
+
+ // This message requests the handle of the tab with the given (zero-based)
+ // index in the given app window. First parameter specifies the given window
+ // handle, second specifies the given tab_index. On error, the returned handle
+ // value is 0.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_Tab, int, int, int)
+
+ // This message requests the the title of the tab with the given handle.
+ // The return value contains the size of the title string. On error, this
+ // value should be -1 and empty string. Note that the title can be empty in
+ // which case the size would be 0.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_TabTitle,
+ int,
+ int,
+ std::wstring)
+
+ // This message requests the url of the tab with the given handle.
+ // The return value contains a success flag and the URL string. The URL will
+ // be empty on failure, and it still may be empty on success.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_TabURL,
+ int /* tab handle */,
+ bool /* success flag */,
+ GURL)
+
+#if defined(OS_WIN)
+ // TODO(estade): delete this unused message.
+ IPC_SYNC_MESSAGE_ROUTED0_0(AutomationMsg_WindowHWND)
+
+ // This message requests the HWND of the tab that corresponds
+ // to the given automation handle.
+ // The return value contains the HWND value, which is 0 if the call fails.
+ //
+ // TODO(estade): The only test that uses this message is
+ // NPAPIVisiblePluginTester.SelfDeletePluginInvokeInSynchronousMouseMove. It
+ // can probably be done in another way, and this can be removed.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_TabHWND,
+ int /* tab_handle */,
+ HWND /* win32 Window Handle */)
+#endif // defined(OS_WIN)
+
+ // This message notifies the AutomationProxy that a handle that it has
+ // previously been given is now invalid. (For instance, if the handle
+ // represented a window which has now been closed.) The parameter
+ // value is the handle.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_InvalidateHandle, int)
+
+ // This message notifies the AutomationProvider that a handle is no
+ // longer being used, so it can stop paying attention to the
+ // associated resource. The parameter value is the handle.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_HandleUnused, int)
+
+ // This message tells the AutomationProvider to provide the given
+ // authentication data to the specified tab, in response to an HTTP/FTP
+ // authentication challenge.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_SetAuth,
+ int, // tab handle
+ std::wstring, // username
+ std::wstring, // password
+ AutomationMsg_NavigationResponseValues) // status
+
+ // This message tells the AutomationProvider to cancel the login in the
+ // specified tab.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_CancelAuth,
+ int, // tab handle
+ AutomationMsg_NavigationResponseValues) // status
+
+ // Requests that the automation provider ask history for the most recent
+ // chain of redirects coming from the given URL. The response must be
+ // decoded by the caller manually; it contains an integer indicating the
+ // number of URLs, followed by that many wstrings indicating a chain of
+ // redirects. On failure, the count will be negative.
+ IPC_SYNC_MESSAGE_ROUTED2_2(AutomationMsg_RedirectsFrom,
+ int, // tab handle
+ GURL, // source URL
+ bool /* succeeded */,
+ std::vector<GURL> /* redirects */)
+
+ // This message asks the AutomationProvider whether a tab is waiting for
+ // login info.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_NeedsAuth,
+ int, // tab handle
+ bool) // status
+
+ // This message requests the AutomationProvider to apply a certain
+ // accelerator. It is completely asynchronous with the resulting accelerator
+ // action.
+ IPC_SYNC_MESSAGE_ROUTED2_0(AutomationMsg_ApplyAccelerator,
+ int, // window handle
+ int) // accelerator id like (IDC_BACK,
+ // IDC_FORWARD, etc)
+ // The list can be found at
+ // chrome/app/chrome_command_ids.h
+
+ // This message requests that the AutomationProvider executes a JavaScript,
+ // which is sent embedded in a 'javascript:' URL.
+ // The javascript is executed in context of child frame whose xpath
+ // is passed as parameter (context_frame). The execution results in
+ // a serialized JSON string response.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_DomOperation,
+ int, // tab handle
+ std::wstring, // context_frame
+ std::wstring, // the javascript to be executed
+ std::string) // the serialized json string
+ // containing the result of a
+ // javascript execution
+
+ // Is the Download Shelf visible for the specified browser?
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_ShelfVisibility,
+ int /* browser_handle */,
+ bool /* is_visible */)
+
+ // This message requests the number of constrained windows in the tab with
+ // the given handle. The return value contains the number of constrained
+ // windows, or -1 if the request failed.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_ConstrainedWindowCount,
+ int /* tab_handle */,
+ int /* constrained_window_count */)
+
+ // This message requests the bounds of the specified View element in
+ // window coordinates.
+ // Request:
+ // int - the handle of the window in which the view appears
+ // int - the ID of the view, as specified in chrome/browser/view_ids.h
+ // bool - whether the bounds should be returned in the screen coordinates
+ // (if true) or in the browser coordinates (if false).
+ // Response:
+ // bool - true if the view was found
+ // gfx::Rect - the bounds of the view, in window coordinates
+ IPC_SYNC_MESSAGE_ROUTED3_2(AutomationMsg_WindowViewBounds, int, int,
+ bool, bool, gfx::Rect)
+
+ // This message sets the bounds of the window.
+ // Request:
+ // int - the handle of the window to resize
+ // gfx::Rect - the bounds of the window
+ // Response:
+ // bool - true if the resize was successful
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_SetWindowBounds, int, gfx::Rect,
+ bool)
+
+#if defined(OS_WIN)
+ // TODO(port): Port these messages.
+ //
+ // This message requests that a drag be performed in window coordinate space
+ // Request:
+ // int - the handle of the window that's the context for this drag
+ // std::vector<gfx::Point> - the path of the drag in window coordinate
+ // space; it should have at least 2 points
+ // (start and end)
+ // int - the flags which identify the mouse button(s) for the drag, as
+ // defined in chrome/views/event.h
+ // Response:
+ // bool - true if the drag could be performed
+ IPC_SYNC_MESSAGE_ROUTED4_1(AutomationMsg_WindowDrag,
+ int, std::vector<gfx::Point>, int, bool, bool)
+#endif // defined(OS_WIN)
+
+ // Similar to AutomationMsg_InitialLoadsComplete, this indicates that the
+ // new tab ui has completed the initial load of its data.
+ // Time is how many milliseconds the load took.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_InitialNewTabUILoadComplete,
+ int /* time */)
+
+ // This message starts a find within a tab corresponding to the supplied
+ // tab handle. The return value contains the number of matches found on the
+ // page within the tab specified. The parameter 'search_string' specifies
+ // what string to search for, 'forward' specifies whether to search in
+ // forward direction (1=forward, 0=back), 'match_case' specifies case
+ // sensitivity
+ // (1=case sensitive, 0=case insensitive). If an error occurs, matches_found
+ // will be -1.
+ //
+ // NOTE: This message has been deprecated, please use the new message
+ // AutomationMsg_Find below.
+ //
+ IPC_SYNC_MESSAGE_ROUTED4_2(AutomationMsg_FindInPage, // DEPRECATED.
+ int, /* tab_handle */
+ std::wstring, /* find_request */
+ int, /* forward */
+ int /* match_case */,
+ int /* active_ordinal */,
+ int /* matches_found */)
+
+ // This message sends a inspect element request for a given tab. The response
+ // contains the number of resources loaded by the inspector controller.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_InspectElement,
+ int, /* tab_handle */
+ int, /* x */
+ int /* y */,
+ int)
+
+ // This message requests the process ID of the tab that corresponds
+ // to the given automation handle.
+ // The return value has an integer corresponding to the PID of the tab's
+ // renderer, 0 if the tab currently has no renderer process, or -1 on error.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_TabProcessID,
+ int /* tab_handle */,
+ int /* process ID */)
+
+ // This tells the browser to enable or disable the filtered network layer.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_SetFilteredInet,
+ bool /* enabled */)
+
+ // Gets the directory that downloads will occur in for the active profile.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_DownloadDirectory,
+ int /* tab_handle */,
+ FilePath /* directory */)
+
+ // This message requests the id of the view that has the focus in the
+ // specified window. If no view is focused, -1 is returned. Note that the
+ // window should either be a ViewWindow or a Browser.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_GetFocusedViewID,
+ int /* view_handle */,
+ int /* focused_view_id */)
+
+ // This message shows/hides the window.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_SetWindowVisible,
+ int /* view_handle */,
+ bool /* visible */,
+ bool /* success */)
+
+ // Gets the active status of a window.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_IsWindowActive,
+ int /* view_handle */,
+ bool /* success */,
+ bool /* active */)
+
+ // Makes the specified window the active window.
+ IPC_SYNC_MESSAGE_ROUTED1_0(AutomationMsg_ActivateWindow,
+ int /* view_handle */)
+
+ // Opens a new browser window.
+ // TODO(sky): remove this and replace with OpenNewBrowserWindowOfType.
+ // Doing this requires updating the reference build.
+ IPC_SYNC_MESSAGE_ROUTED1_0(AutomationMsg_OpenNewBrowserWindow,
+ bool /* show */ )
+
+ // This message requests the handle (int64 app-unique identifier) of the
+ // current active top window. On error, the returned handle value is 0.
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_ActiveWindow, int)
+
+ // This message requests the browser associated with the specified window
+ // handle.
+ // The return value contains a success flag and the handle of the browser.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_BrowserForWindow,
+ int /* window handle */,
+ bool /* success flag */,
+ int /* browser handle */)
+
+ // This message requests the window associated with the specified browser
+ // handle.
+ // The return value contains a success flag and the handle of the window.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_WindowForBrowser,
+ int /* browser handle */,
+ bool /* success flag */,
+ int /* window handle */)
+
+ // This message requests the AutocompleteEdit associated with the specified
+ // browser handle.
+ // The return value contains a success flag and the handle of the omnibox.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_AutocompleteEditForBrowser,
+ int /* browser handle */,
+ bool /* success flag */,
+ int /* AutocompleteEdit handle */)
+
+#if defined(OS_WIN)
+ // TODO(estade): This message is defined later on for Mac and Linux. This is
+ // to avoid adding a new IPC in the middle for those platforms (see comment
+ // at top). The message is exactly the same, so they should be remerged when
+ // all messages in this file have been made cross-platform (at which point we
+ // will need to check in new reference builds).
+ //
+ // This message requests that a mouse click be performed in window coordinate
+ // space.
+ // Request:
+ // int - the handle of the window that's the context for this click
+ // gfx::Point - the point to click
+ // int - the flags which identify the mouse button(s) for the click, as
+ // defined in chrome/views/event.h
+ IPC_MESSAGE_ROUTED3(AutomationMsg_WindowClick, int, gfx::Point, int)
+#endif // defined(OS_WIN)
+
+ // This message requests that a key press be performed.
+ // Request:
+ // int - the handle of the window that's the context for this click
+ // int - the app::KeyboardCode of the key that was pressed.
+ // int - the flags which identify the modifiers (shift, ctrl, alt)
+ // associated for, as defined in chrome/views/event.h
+ IPC_MESSAGE_ROUTED3(AutomationMsg_WindowKeyPress, int, int, int)
+
+ // This message notifies the AutomationProvider to create a tab which is
+ // hosted by an external process.
+ // Request:
+ // ExternalTabSettings - settings for external tab
+ IPC_SYNC_MESSAGE_ROUTED1_4(AutomationMsg_CreateExternalTab,
+ IPC::ExternalTabSettings /* settings*/,
+ gfx::NativeWindow /* Tab container window */,
+ gfx::NativeWindow /* Tab window */,
+ int /* Handle to the new tab */,
+ int /* Session Id of the new tab */)
+
+ // This message notifies the AutomationProvider to navigate to a specified
+ // url in the external tab with given handle. The first parameter is the
+ // handle to the tab resource. The second parameter is the target url.
+ // The third parameter is the referrer.
+ // The return value contains a status code which is nonnegative on success.
+ // see AutomationMsg_NavigationResponseValues for the navigation response.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_NavigateInExternalTab,
+ int,
+ GURL,
+ GURL,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message is an outgoing message from Chrome to an external host.
+ // It is a notification that the NavigationState was changed
+ // Request:
+ // -int: The flags specifying what changed
+ // (see TabContents::InvalidateTypes)
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED3(AutomationMsg_NavigationStateChanged,
+ int, // tab handle
+ int, // TabContents::InvalidateTypes
+ IPC::NavigationInfo) // title, url etc.
+
+ // This message is an outgoing message from Chrome to an external host.
+ // It is a notification that the target URL has changed (the target URL
+ // is the URL of the link that the user is hovering on)
+ // Request:
+ // -int: The tab handle
+ // -std::wstring: The new target URL
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED2(AutomationMsg_UpdateTargetUrl, int, std::wstring)
+
+ // This message notifies the AutomationProvider to show the specified html
+ // text in an interstitial page in the tab with given handle. The first
+ // parameter is the handle to the tab resource. The second parameter is the
+ // html text to be displayed.
+ // The return value contains a success flag.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_ShowInterstitialPage,
+ int,
+ std::string,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message notifies the AutomationProvider to hide the current
+ // interstitial page in the tab with given handle. The parameter is the
+ // handle to the tab resource.
+ // The return value contains a success flag.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_HideInterstitialPage, int,
+ bool)
+
+ // This message requests that a tab be closed.
+ // Request:
+ // - int: handle of the tab to close
+ // - bool: if true the proxy blocks until the tab has completely closed,
+ // otherwise the proxy only blocks until it initiates the close.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_CloseTab, int, bool, bool)
+
+ // This message requests that the browser be closed.
+ // Request:
+ // - int: handle of the browser which contains the tab
+ // Response:
+ // - bool: whether the operation was successfull.
+ // - bool: whether the browser process will be terminated as a result (if
+ // this was the last closed browser window).
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_CloseBrowser, int, bool,
+ bool)
+
+ IPC_MESSAGE_ROUTED1(AutomationMsg_CloseBrowserRequestAsync, int)
+
+ // Unused.
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED1(AutomationMsg_Unused, int)
+
+#if defined(OS_WIN)
+ // TODO(port): Port these messages.
+ //
+ // This message is an outgoing message from Chrome to an external host.
+ // It is a request to process a keyboard accelerator.
+ // Request:
+ // -int: Tab handle
+ // -MSG: The keyboard message
+ // Response:
+ // None expected
+ // TODO(sanjeevr): Ideally we need to add a response from the external
+ // host saying whether it processed the accelerator
+ IPC_MESSAGE_ROUTED2(AutomationMsg_HandleAccelerator, int, MSG)
+
+ // This message is sent by the container of an externally hosted tab to
+ // reflect any accelerator keys that it did not process. This gives the
+ // tab a chance to handle the keys
+ // Request:
+ // - int: handle of the tab
+ // -MSG: The keyboard message that the container did not handle
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED2(AutomationMsg_ProcessUnhandledAccelerator, int, MSG)
+#endif // defined(OS_WIN)
+
+ // Sent by the external tab to the host to notify that the user has tabbed
+ // out of the tab.
+ // Request:
+ // - int: Tab handle
+ // - bool: |reverse| set to true when shift-tabbing out of the tab, false
+ // otherwise.
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED2(AutomationMsg_TabbedOut, int, bool)
+
+ // Sent by the external tab host to ask focus to be set to either the first
+ // or last element on the page.
+ // Request:
+ // - int: handle of the tab
+ // - bool: |reverse|
+ // true: Focus will be set to the last focusable element
+ // false: Focus will be set to the first focusable element
+ // - bool: |restore_focus_to_view|
+ // true: The renderer view associated with the current tab will be
+ // infomed that it is receiving focus.
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED3(AutomationMsg_SetInitialFocus, int, bool, bool)
+
+ // This message is an outgoing message from Chrome to an external host.
+ // It is a request to open a url
+ // Request:
+ // -int: Tab handle
+ // -GURL: The URL to open
+ // -GURL: The referrer
+ // -int: The WindowOpenDisposition that specifies where the URL should
+ // be opened (new tab, new window etc).
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED4(AutomationMsg_OpenURL, int, GURL, GURL, int)
+
+ // This message requests the provider to wait until the specified tab has
+ // finished restoring after session restore.
+ // Request:
+ // - int: handle of the tab
+ // Response:
+ // - bool: whether the operation was successful.
+ IPC_SYNC_MESSAGE_ROUTED1_0(AutomationMsg_WaitForTabToBeRestored, int)
+
+ // This message is an outgoing message from Chrome to an external host.
+ // It is a notification that a navigation happened
+ // Request:
+ // -int: Tab handle
+ //
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED2(AutomationMsg_DidNavigate, int, IPC::NavigationInfo)
+
+ // This message requests the different security states of the page displayed
+ // in the specified tab.
+ // Request:
+ // - int: handle of the tab
+ // Response:
+ // - bool: whether the operation was successful.
+ // - SecurityStyle: the security style of the tab.
+ // - int: the status of the server's ssl cert (0 means no errors or no ssl
+ // was used).
+ // - int: the insecure content state, 0 means no insecure contents.
+
+ IPC_SYNC_MESSAGE_ROUTED1_4(AutomationMsg_GetSecurityState,
+ int,
+ bool,
+ SecurityStyle,
+ int,
+ int)
+
+ // This message requests the page type of the page displayed in the specified
+ // tab (normal, error or interstitial).
+ // Request:
+ // - int: handle of the tab
+ // Response:
+ // - bool: whether the operation was successful.
+ // - PageType: the type of the page currently displayed.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_GetPageType, int, bool, PageType)
+
+ // This message simulates the user action on the SSL blocking page showing in
+ // the specified tab. This message is only effective if an interstitial page
+ // is showing in the tab.
+ // Request:
+ // - int: handle of the tab
+ // - bool: whether to proceed or abort the navigation
+ // Response:
+ // - AutomationMsg_NavigationResponseValues: result of the operation.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_ActionOnSSLBlockingPage, int, bool,
+ AutomationMsg_NavigationResponseValues)
+
+ // Message to request that a browser window is brought to the front and
+ // activated.
+ // Request:
+ // - int: handle of the browser window.
+ // Response:
+ // - bool: True if the browser is brought to the front.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_BringBrowserToFront, int, bool)
+
+ // Message to request whether a certain item is enabled of disabled in the
+ // menu in the browser window
+ //
+ // Request:
+ // - int: handle of the browser window.
+ // - int: IDC message identifier to query if enabled
+ // Response:
+ // - bool: True if the command is enabled on the menu
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_IsMenuCommandEnabled, int, int, bool)
+
+ // This message notifies the AutomationProvider to print the tab with given
+ // handle. The first parameter is the handle to the tab resource. The
+ // return value contains a bool which is true on success.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_PrintNow, int, bool)
+
+ // This message notifies the AutomationProvider to reload the current page in
+ // the tab with given handle. The first parameter is the handle to the tab
+ // resource. The return value contains a status code which is nonnegative on
+ // success.
+ // see AutomationMsg_NavigationResponseValues for the navigation response.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_Reload, int,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message requests the handle (int64 app-unique identifier) of the
+ // last active browser window, or the browser at index 0 if there is no last
+ // active browser, or it no longer exists. Returns 0 if no browser windows
+ // exist.
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_LastActiveBrowserWindow, int)
+
+ // This message notifies the AutomationProvider to save the page with given
+ // handle. The first parameter is the handle to the tab resource. The second
+ // parameter is the main HTML file name. The third parameter is the directory
+ // for saving resources. The fourth parameter is the saving type: 0 for HTML
+ // only; 1 for complete web page.
+ // The return value contains a bool which is true on success.
+ IPC_SYNC_MESSAGE_ROUTED4_1(AutomationMsg_SavePage, int, FilePath, FilePath,
+ int, bool)
+
+ // This message requests the text currently being displayed in the
+ // AutocompleteEdit. The parameter is the handle to the AutocompleteEdit.
+ // The return value is a string indicating the text in the AutocompleteEdit.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_AutocompleteEditGetText,
+ int /* autocomplete edit handle */,
+ bool /* the requested autocomplete edit exists */,
+ std::wstring /* omnibox text */)
+
+ // This message sets the text being displayed in the AutocompleteEdit. The
+ // first parameter is the handle to the omnibox and the second parameter is
+ // the text to be displayed in the AutocompleteEdit.
+ // The return value has no parameters and is returned when the operation has
+ // completed.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_AutocompleteEditSetText,
+ int /* autocomplete edit handle */,
+ std::wstring /* text to set */,
+ bool /* the requested autocomplete edit exists */)
+
+ // This message requests if a query to a autocomplete provider is still in
+ // progress. The first parameter in the request is the handle to the
+ // autocomplete edit.
+ // The first return value indicates if the request succeeded.
+ // The second return value indicates if a query is still in progress.
+ IPC_SYNC_MESSAGE_ROUTED1_2( \
+ AutomationMsg_AutocompleteEditIsQueryInProgress,
+ int /* autocomplete edit handle*/,
+ bool /* the requested autocomplete edit exists */,
+ bool /* indicates if a query is in progress */)
+
+ // This message requests a list of the autocomplete messages currently being
+ // displayed by the popup. The parameter in the request is a handle to the
+ // autocomplete edit.
+ // The first return value indicates if the request was successful, while
+ // while the second is the actual list of matches.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_AutocompleteEditGetMatches,
+ int /* autocomplete edit handle*/,
+ bool /* the requested autocomplete edit exists */,
+ std::vector<AutocompleteMatchData> /* matches */)
+
+ // This message requests the execution of a browser command in the browser
+ // for which the handle is specified.
+ // The return value contains a boolean, whether the command was dispatched.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_WindowExecuteCommandAsync,
+ int /* automation handle */,
+ int /* browser command */,
+ bool /* success flag */)
+
+ // This message requests the execution of a browser command in the browser
+ // for which the handle is specified.
+ // The return value contains a boolean, whether the command was dispatched
+ // and successful executed.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_WindowExecuteCommand,
+ int /* automation handle */,
+ int /* browser command */,
+ bool /* success flag */)
+
+
+ // This message opens the Find window within a tab corresponding to the
+ // supplied tab handle.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_OpenFindInPage,
+ int /* tab_handle */)
+
+ // Posts a message from external host to chrome renderer.
+ IPC_MESSAGE_ROUTED4(AutomationMsg_HandleMessageFromExternalHost,
+ int /* automation handle */,
+ std::string /* message */,
+ std::string /* origin */,
+ std::string /* target */)
+
+ // A message for an external host.
+ IPC_MESSAGE_ROUTED4(AutomationMsg_ForwardMessageToExternalHost,
+ int, /* handle */
+ std::string /* message */,
+ std::string /* origin */,
+ std::string /* target */)
+
+ // This message starts a find within a tab corresponding to the supplied
+ // tab handle. The parameter |request| specifies what to search for.
+ // If an error occurs, |matches_found| will be -1.
+ //
+ IPC_SYNC_MESSAGE_ROUTED2_2(AutomationMsg_Find,
+ int /* tab_handle */,
+ AutomationMsg_Find_Params /* params */,
+ int /* active_ordinal */,
+ int /* matches_found */)
+
+ // Is the Find window fully visible (and not animating) for the specified
+ // tab?
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_FindWindowVisibility,
+ int /* tab_handle */,
+ bool /* is_visible */)
+
+ // Where is the Find window located. |x| and |y| will be -1, -1 on failure.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_FindWindowLocation,
+ int /* tab_handle */,
+ int /* x */,
+ int /* y */)
+
+ // Is the Bookmark bar visible? The return value will indicate whether it is
+ // visible or not and whether it is being animated into (or out of its place).
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_BookmarkBarVisibility,
+ int /* browser_handle */,
+ bool, /* is_visible */
+ bool /* still_animating */)
+
+ // This message requests the number of related info bars opened. It
+ // returns -1 if an error occurred.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_GetInfoBarCount,
+ int /* tab_handle */,
+ int /* info bar count */)
+
+ // This message triggers the action associated with the "accept" button in
+ // the info-bar at the specified index. If |wait for navigation| is true, it
+ // won't return until a navigation has occurred.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_ClickInfoBarAccept,
+ int /* tab_handle */,
+ int /* info bar index */,
+ bool /* wait for navigation */,
+
+ /* navigation result */
+ AutomationMsg_NavigationResponseValues)
+
+ // This message retrieves the last time a navigation occurred in the specified
+ // tab. The value is intended to be used with WaitForNavigation.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_GetLastNavigationTime,
+ int /* tab_handle */,
+ int64 /* last navigation time */)
+
+ // This messages is used to block until a new navigation occurs (if there is
+ // none more recent then the time specified).
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_WaitForNavigation,
+ int /* tab_handle */,
+ int64 /* last navigation time */,
+
+ /* navigation result */
+ AutomationMsg_NavigationResponseValues)
+
+ // This messages sets an int-value preference.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_SetIntPreference,
+ int /* browser handle */,
+ std::string /* pref name */,
+ int /* value */,
+ bool /* success */)
+
+ // Queries whether an app modal dialog is currently being shown. (i.e. a
+ // javascript alert) and which buttons it contains.
+ IPC_SYNC_MESSAGE_ROUTED0_2(AutomationMsg_ShowingAppModalDialog,
+ bool /* showing dialog */,
+ int /* view::DelegateDialog::DialogButton */)
+
+ // This message triggers the specified button for the currently showing
+ // modal dialog.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_ClickAppModalDialogButton,
+ int /* view::DelegateDialog::DialogButton */,
+ bool /* success */)
+
+ // This messages sets a string-value preference.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_SetStringPreference,
+ int /* browser handle */,
+ std::string /* pref name */,
+ std::string /* pref value */,
+ bool)
+
+ // This messages gets a boolean-value preference.
+ IPC_SYNC_MESSAGE_ROUTED2_2(AutomationMsg_GetBooleanPreference,
+ int /* browser handle */,
+ std::string /* pref name */,
+ bool /* success */,
+ bool /* pref value */)
+
+ // This messages sets a boolean-value preference.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_SetBooleanPreference,
+ int /* browser handle */,
+ std::string /* pref name */,
+ bool /* pref value */,
+ bool /* success */)
+
+ // Queries the current used encoding name of the page in the specified
+ // web content tab.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_GetPageCurrentEncoding,
+ int /* tab handle */,
+ std::string /* current used encoding name */)
+
+ // Uses the specified encoding to override the encoding of the page in the
+ // specified web content tab.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_OverrideEncoding,
+ int /* tab handle */,
+ std::string /* overrided encoding name */,
+ bool /* success */)
+
+ // Used to disable the dialog box that prompts the user for a path when
+ // saving a web page.
+ IPC_SYNC_MESSAGE_ROUTED1_0(AutomationMsg_SavePackageShouldPromptUser,
+ bool /* false if we want to not show the dialog */)
+
+ // This message is an outgoing message from Chrome to an external host.
+ // It is a notification that a navigation failed
+ // Request:
+ // -int : Tab handle
+ // -int : The status code.
+ // -GURL: The URL we failed to navigate to.
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED3(AutomationMsg_NavigationFailed, int, int, GURL)
+
+#if defined(OS_WIN)
+ // This message is an outgoing message from an automation client to Chrome.
+ // It is used to reposition a chrome tab window.
+ IPC_MESSAGE_ROUTED2(AutomationMsg_TabReposition,
+ int /* tab handle */,
+ IPC::Reposition_Params /* SetWindowPos params */)
+#endif // defined(OS_WIN)
+
+ // Gets the title of the top level browser window.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_WindowTitle,
+ int /* automation handle */,
+ string16 /* title text */ )
+
+ // Tab load complete
+ IPC_MESSAGE_ROUTED2(AutomationMsg_TabLoaded,
+ int, // tab handle
+ GURL)
+
+ // This message requests the tabstrip index of the tab with the given handle.
+ // The return value contains the index, which will be -1 on failure.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_TabIndex, int, int)
+
+ // This message requests the handle (int64 app-unique identifier) of
+ // a valid normal browser window, i.e. normal type and non-incognito mode.
+ // On error, the returned handle value is 0.
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_FindNormalBrowserWindow, int)
+
+ // This message requests the number of normal browser windows, i.e. normal
+ // type and non-incognito mode that the app currently has open. The return
+ // value is the number of windows.
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_NormalBrowserWindowCount, int)
+
+ // Used to put the browser into "extension automation mode" for a given
+ // set of Chrome Extensions API functions for the current profile, or turn
+ // off automation mode. The specified tab is used as the conduit for all
+ // automated API functions. It must be an external tab (as in
+ // AutomationMsg_CreateExternalTab).
+ IPC_MESSAGE_ROUTED2(AutomationMsg_SetEnableExtensionAutomation,
+ // Tab handle.
+ int,
+ // Empty to disable automation, non-empty to enable
+ // automation of the specified API functions, single
+ // entry of "*" to enable automation of all API
+ // functions.
+ std::vector<std::string>)
+
+ // This message tells the browser to start using the new proxy configuration
+ // represented by the given JSON string. The parameters used in the JSON
+ // string are defined in automation_constants.h.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_SetProxyConfig,
+ std::string /* proxy_config_json_string */)
+
+ // Sets Download Shelf visibility for the specified browser.
+ IPC_SYNC_MESSAGE_ROUTED2_0(AutomationMsg_SetShelfVisibility,
+ int /* browser_handle */,
+ bool /* is_visible */)
+
+ // This message requests the number of blocked popups in a certain tab with
+ // the given handle. The return value is the number of blocked popups, or -1
+ // if this request failed.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_BlockedPopupCount,
+ int /* tab_handle */,
+ int /* blocked_popup_count */)
+
+ // This message retrieves the locale of the browser process. On success
+ // |chrome_locale| will contain the locale as reported by ICU. On failure
+ // |chrome_locale| is the empty string.
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_GetBrowserLocale,
+ string16 /* chrome_locale */)
+
+#if defined(OS_WIN)
+ IPC_MESSAGE_ROUTED4(AutomationMsg_ForwardContextMenuToExternalHost,
+ int /* tab_handle */,
+ HANDLE /* source menu handle */,
+ int /* align flags */,
+ IPC::MiniContextMenuParams /* params */)
+
+ IPC_MESSAGE_ROUTED2(AutomationMsg_ForwardContextMenuCommandToChrome,
+ int /* tab_handle */,
+ int /* selected_command */)
+#endif // OS_WIN
+
+ // A URL request to be fetched via automation
+ IPC_MESSAGE_ROUTED3(AutomationMsg_RequestStart,
+ int /* tab_handle */,
+ int /* request_id */,
+ IPC::AutomationURLRequest /* request */)
+
+ // Read data from a URL request to be fetched via automation
+ IPC_MESSAGE_ROUTED3(AutomationMsg_RequestRead,
+ int /* tab_handle */,
+ int /* request_id */,
+ int /* bytes_to_read */)
+
+ // Response to a AutomationMsg_RequestStart message
+ IPC_MESSAGE_ROUTED3(AutomationMsg_RequestStarted,
+ int /* tab_handle */,
+ int /* request_id */,
+ IPC::AutomationURLResponse /* response */)
+
+ // Data read via automation
+ IPC_MESSAGE_ROUTED3(AutomationMsg_RequestData,
+ int /* tab_handle */,
+ int /* request_id */,
+ std::string /* data */)
+
+ IPC_MESSAGE_ROUTED3(AutomationMsg_RequestEnd,
+ int /* tab_handle */,
+ int /* request_id */,
+ URLRequestStatus /* status */)
+
+ IPC_MESSAGE_ROUTED1(AutomationMsg_PrintAsync,
+ int /* tab_handle */)
+
+ IPC_MESSAGE_ROUTED3(AutomationMsg_SetCookieAsync,
+ int /* tab_handle */,
+ GURL /* url */,
+ std::string /* cookie */)
+
+ IPC_MESSAGE_ROUTED1(AutomationMsg_SelectAll,
+ int /* tab handle */)
+
+ IPC_MESSAGE_ROUTED1(AutomationMsg_Cut,
+ int /* tab handle */)
+
+ IPC_MESSAGE_ROUTED1(AutomationMsg_Copy,
+ int /* tab handle */)
+
+ IPC_MESSAGE_ROUTED1(AutomationMsg_Paste,
+ int /* tab handle */)
+
+ IPC_MESSAGE_ROUTED1(AutomationMsg_ReloadAsync,
+ int /* tab handle */)
+
+ IPC_MESSAGE_ROUTED1(AutomationMsg_StopAsync,
+ int /* tab handle */)
+
+ // Returns the number of times a filter was used to service an URL request.
+ // See AutomationMsg_SetFilteredInet.
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_GetFilteredInetHitCount,
+ int /* hit_count */)
+
+ // Is the browser in fullscreen mode?
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_IsFullscreen,
+ int /* browser_handle */,
+ bool /* is_fullscreen */)
+
+ // Is the fullscreen bubble visible?
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_IsFullscreenBubbleVisible,
+ int /* browser_handle */,
+ bool /* is_visible */)
+
+#if defined(OS_POSIX)
+ // See previous definition of this message for explanation of why it is
+ // defined twice.
+ IPC_MESSAGE_ROUTED3(AutomationMsg_WindowClick, int, gfx::Point, int)
+#endif
+
+ // This message notifies the AutomationProvider to navigate to a specified
+ // url in the tab with given handle. The first parameter is the handle to
+ // the tab resource. The second parameter is the target url. The third
+ // parameter is the number of navigations that are required for a successful
+ // return value. See AutomationMsg_NavigationResponseValues for the return
+ // value.
+ IPC_SYNC_MESSAGE_ROUTED3_1(
+ AutomationMsg_NavigateToURLBlockUntilNavigationsComplete, int, GURL, int,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message notifies the AutomationProvider to navigate to a specified
+ // navigation entry index in the external tab with given handle. The first
+ // parameter is the handle to the tab resource. The second parameter is the
+ // index of navigation entry.
+ // The return value contains a status code which is nonnegative on success.
+ // see AutomationMsg_NavigationResponseValues for the navigation response.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_NavigateExternalTabAtIndex, int, int,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message requests the provider to wait until the window count
+ // reached the specified value.
+ // Request:
+ // - int: target browser window count
+ // Response:
+ // - bool: whether the operation was successful.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_WaitForBrowserWindowCountToBecome,
+ int, bool)
+
+ // This message requests the provider to wait until an application modal
+ // dialog is shown.
+ // Response:
+ // - bool: whether the operation was successful
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_WaitForAppModalDialogToBeShown, bool)
+
+ // This message notifies the AutomationProvider to navigate back in session
+ // history in the tab with given handle. The first parameter is the handle
+ // to the tab resource. The second parameter is the number of navigations the
+ // provider will wait for.
+ // See AutomationMsg_NavigationResponseValues for the navigation response
+ // values.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_GoBackBlockUntilNavigationsComplete,
+ int, int,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message notifies the AutomationProvider to navigate forward in session
+ // history in the tab with given handle. The first parameter is the handle
+ // to the tab resource. The second parameter is the number of navigations
+ // the provider will wait for.
+ // See AutomationMsg_NavigationResponseValues for the navigation response
+ // values.
+ IPC_SYNC_MESSAGE_ROUTED2_1(
+ AutomationMsg_GoForwardBlockUntilNavigationsComplete, int, int,
+ AutomationMsg_NavigationResponseValues)
+
+ // This message is used by automation clients to upload histogram data to the
+ // browser process.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_RecordHistograms,
+ std::vector<std::string> /* histogram_list */)
+
+ IPC_MESSAGE_ROUTED2(AutomationMsg_AttachExternalTab,
+ int /* 'source' tab_handle */,
+ IPC::AttachExternalTabParams)
+
+ // Sent when the automation client connects to an existing tab.
+ IPC_SYNC_MESSAGE_ROUTED3_4(AutomationMsg_ConnectExternalTab,
+ uint64 /* cookie */,
+ bool /* allow/block tab*/,
+ gfx::NativeWindow /* parent window */,
+ gfx::NativeWindow /* Tab container window */,
+ gfx::NativeWindow /* Tab window */,
+ int /* Handle to the new tab */,
+ int /* Session Id of the new tab */)
+
+#if defined(OS_POSIX)
+ // TODO(estade): this should be merged with the windows message of the same
+ // name. See comment for WindowClick.
+ IPC_SYNC_MESSAGE_ROUTED4_1(AutomationMsg_WindowDrag,
+ int, std::vector<gfx::Point>, int, bool, bool)
+#endif // defined(OS_POSIX)
+
+ // This message gets the bounds of the window.
+ // Request:
+ // int - the handle of the window to query
+ // Response:
+ // gfx::Rect - the bounds of the window
+ // bool - true if the query was successful
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_GetWindowBounds, int, gfx::Rect,
+ bool)
+
+ // Simulate an end of session. Normally this happens when the user
+ // shuts down the machine or logs off.
+ // Request:
+ // int - the handle of the browser
+ // Response:
+ // bool - true if succesful
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_TerminateSession, int, bool)
+
+ // Returns whether the window is maximized.
+ // Request:
+ // int - the handle of the window
+ // Response:
+ // bool - true if the window is maximized
+ // bool - true if query is successful
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_IsWindowMaximized, int, bool, bool)
+
+ IPC_MESSAGE_ROUTED2(AutomationMsg_SetPageFontSize,
+ int /* tab_handle */,
+ int /* The font size */)
+
+ // Returns a metric event duration that was last recorded. Returns -1 if the
+ // event hasn't occurred yet.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_GetMetricEventDuration,
+ std::string /* event_name */,
+ int /* duration ms */)
+
+ // Sent by automation provider - go to history entry via automation.
+ IPC_MESSAGE_ROUTED2(AutomationMsg_RequestGoToHistoryEntryOffset,
+ int, // tab handle
+ int) // numbers of entries (negative or positive)
+
+ // Silently install the extension in the given crx file.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_InstallExtension,
+ FilePath /* full path to crx file */,
+ AutomationMsg_ExtensionResponseValues)
+
+ // Silently load the extension in the given directory. This expects an
+ // extension expanded into the directory, not a crx file.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_LoadExpandedExtension,
+ FilePath /* root directory of extension */,
+ AutomationMsg_ExtensionResponseValues)
+
+ // Retrieves a list of the root directories of all enabled extensions
+ // that have been installed into Chrome by dropping a .crx file onto
+ // Chrome or an equivalent action (including loaded extensions).
+ // Other types of extensions are not included on the list (e.g. "component"
+ // or "external" extensions) since they are generally not useful for testing
+ // (e.g. an external extension could mess with an automated test if it's
+ // present on some systems only).
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_GetEnabledExtensions,
+ std::vector<FilePath>)
+
+ // This message requests the type of the window with the given handle. The
+ // return value contains the type (Browser::Type), or -1 if the request
+ // failed.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_Type, int, int)
+
+ // Opens a new browser window of a specific type.
+ IPC_SYNC_MESSAGE_ROUTED2_0(AutomationMsg_OpenNewBrowserWindowOfType,
+ int /* Type (Browser::Type) */,
+ bool /* show */ )
+
+ // This message requests that the mouse be moved to this location, in
+ // window coordinate space.
+ // Request:
+ // int - the handle of the window that's the context for this click
+ // gfx::Point - the location to move to
+ IPC_MESSAGE_ROUTED2(AutomationMsg_WindowMouseMove, int, gfx::Point)
+
+ // Called when requests should be downloaded using a host browser's
+ // download mechanism when chrome is being embedded.
+ IPC_MESSAGE_ROUTED2(AutomationMsg_DownloadRequestInHost,
+ int /* tab_handle */,
+ int /* request_id */)
+
+ // Shuts down the session service for the browser identified by
+ // |browser_handle|. On success |result| is set to true.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_ShutdownSessionService,
+ int /* browser_handle */,
+ bool /* result */)
+
+ IPC_MESSAGE_ROUTED1(AutomationMsg_SaveAsAsync,
+ int /* tab handle */)
+
+#if defined(OS_WIN)
+ // An incoming message from an automation host to Chrome. Signals that
+ // the browser containing |tab_handle| has moved.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_BrowserMove,
+ int /* tab handle */)
+#endif
+
+ // Used to get cookies for the given URL.
+ IPC_MESSAGE_ROUTED3(AutomationMsg_GetCookiesFromHost,
+ int /* tab_handle */,
+ GURL /* url */,
+ int /* opaque_cookie_id */)
+
+ IPC_MESSAGE_ROUTED5(AutomationMsg_GetCookiesHostResponse,
+ int /* tab_handle */,
+ bool /* success */,
+ GURL /* url */,
+ std::string /* cookies */,
+ int /* opaque_cookie_id */)
+
+ // If the given host is empty, then the default content settings are
+ // modified.
+ IPC_SYNC_MESSAGE_ROUTED4_1(AutomationMsg_SetContentSetting,
+ int /* browser handle */,
+ std::string /* host */,
+ ContentSettingsType /* content type */,
+ ContentSetting /* setting */,
+ bool /* success */)
+
+#if defined(OS_CHROMEOS)
+ // Logs in through the browser's login wizard if available.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_LoginWithUserAndPass,
+ std::string /* username*/,
+ std::string /* password*/,
+ bool /* Whether successful*/)
+#endif
+
+ // Return the bookmarks encoded as a JSON string.
+ IPC_SYNC_MESSAGE_ROUTED1_2(AutomationMsg_GetBookmarksAsJSON,
+ int /* browser_handle */,
+ std::string /* bookmarks as a JSON string */,
+ bool /* success */)
+
+ // Wait for the bookmark model to load.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_WaitForBookmarkModelToLoad,
+ int /* browser_handle */,
+ bool /* success */)
+
+ // Bookmark addition, modification, and removal.
+ // Bookmarks are indexed by their id.
+ IPC_SYNC_MESSAGE_ROUTED4_1(AutomationMsg_AddBookmarkGroup,
+ int /* browser_handle */,
+ int64 /* parent_id */,
+ int /* index */,
+ std::wstring /* title */,
+ bool /* success */)
+ IPC_SYNC_MESSAGE_ROUTED5_1(AutomationMsg_AddBookmarkURL,
+ int /* browser_handle */,
+ int64 /* parent_id */,
+ int /* index */,
+ std::wstring /* title */,
+ GURL /* url */,
+ bool /* success */)
+ IPC_SYNC_MESSAGE_ROUTED4_1(AutomationMsg_ReparentBookmark,
+ int /* browser_handle */,
+ int64 /* id */,
+ int64 /* new_parent_id */,
+ int /* index */,
+ bool /* success */)
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_SetBookmarkTitle,
+ int /* browser_handle */,
+ int64 /* id */,
+ std::wstring /* title */,
+ bool /* success */)
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_SetBookmarkURL,
+ int /* browser_handle */,
+ int64 /* id */,
+ GURL /* url */,
+ bool /* success */)
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_RemoveBookmark,
+ int /* browser_handle */,
+ int64 /* id */,
+ bool /* success */)
+
+ // This message informs the browser process to remove the history entries
+ // for the specified types across all time ranges. See
+ // browsing_data_remover.h for a list of REMOVE_* types supported in the
+ // remove_mask parameter.
+ IPC_MESSAGE_ROUTED1(AutomationMsg_RemoveBrowsingData, int)
+
+ // Block until the focused view id changes to something other than
+ // |previous_view_id|.
+ IPC_SYNC_MESSAGE_ROUTED2_2(AutomationMsg_WaitForFocusedViewIDToChange,
+ int /* window handle */,
+ int /* previous_view_id */,
+ bool /* success */,
+ int /* new_view_id */)
+
+ // To avoid race conditions, waiting until a popup menu opens is a
+ // three-step process:
+ // 1. Call StartTrackingPopupMenus.
+ // 2. Call an automation method that results in opening the popup menu.
+ // 3. Call WaitForPopupMenuToOpen and check for success.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_StartTrackingPopupMenus,
+ int /* browser handle */,
+ bool /* success */)
+ IPC_SYNC_MESSAGE_ROUTED0_1(AutomationMsg_WaitForPopupMenuToOpen,
+ bool /* success */)
+
+ // Generic pyauto pattern to help avoid future addition of
+ // automation messages.
+ IPC_SYNC_MESSAGE_ROUTED2_2(AutomationMsg_SendJSONRequest,
+ int /* browser_handle */,
+ std::string /* JSON request */,
+ std::string /* JSON response */,
+ bool /* success */)
+
+ // Installs an extension from the crx file and returns its id.
+ // On error, |extension handle| will be 0.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_InstallExtensionAndGetHandle,
+ FilePath /* full path to crx file */,
+ bool /* with UI */,
+ int /* extension handle */)
+
+ // Waits for the next extension test result. Sets |test result| as the
+ // received result and |message| as any accompanying message with the
+ // result, which could be the empty string.
+ IPC_SYNC_MESSAGE_ROUTED0_2(AutomationMsg_WaitForExtensionTestResult,
+ bool /* test result */,
+ std::string /* message */)
+
+ // Uninstalls an extension. On success |success| is true.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_UninstallExtension,
+ int /* extension handle */,
+ bool /* success */)
+
+ // Enables an extension. On success |success| is true.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_EnableExtension,
+ int /* extension handle */,
+ bool /* success */)
+
+ // Disables an extension. On success |success| is true.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_DisableExtension,
+ int /* extension handle */,
+ bool /* success */)
+
+ // Executes the action associated with the given extension. This executes
+ // the extension's page or browser action in the given browser, but does
+ // not open popups. On success |success| is true.
+ IPC_SYNC_MESSAGE_ROUTED2_1(
+ AutomationMsg_ExecuteExtensionActionInActiveTabAsync,
+ int /* extension handle */,
+ int /* browser handle */,
+ bool /* success */)
+
+ // Moves the browser action to the given index in the browser action toolbar.
+ // On success |success| is true.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_MoveExtensionBrowserAction,
+ int /* extension handle */,
+ int /* index */,
+ bool /* success */)
+
+ // Gets an extension property |property type|. On success |success| is true,
+ // and |property value| is set.
+ IPC_SYNC_MESSAGE_ROUTED2_2(AutomationMsg_GetExtensionProperty,
+ int /* extension handle */,
+ AutomationMsg_ExtensionProperty /* property type */,
+ bool /* success */,
+ std::string /* property value */)
+
+ // Resets to the default theme.
+ IPC_SYNC_MESSAGE_ROUTED0_0(AutomationMsg_ResetToDefaultTheme)
+
+ // Navigates asynchronously to a URL with a certain disposition,
+ // like in a new tab.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_NavigationAsyncWithDisposition,
+ int /* tab handle */,
+ GURL,
+ WindowOpenDisposition,
+ bool /* result */)
+
+
+ // This message requests the cookie be deleted for given url in the
+ // profile of the tab identified by the first parameter. The second
+ // parameter is the cookie name.
+ IPC_SYNC_MESSAGE_ROUTED3_1(AutomationMsg_DeleteCookie, GURL, std::string,
+ int /* tab handle */,
+ bool /* result */)
+
+ // This message triggers the collected cookies dialog for a specific tab.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_ShowCollectedCookiesDialog,
+ int /* tab handle */,
+ bool /* result */)
+
+ // This message requests the external tab identified by the tab handle
+ // passed in be closed.
+ // Request:
+ // -int: Tab handle
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED1(AutomationMsg_CloseExternalTab, int)
+
+ // This message requests that the external tab identified by the tab handle
+ // runs unload handlers if any on the current page.
+ // Request:
+ // -int: Tab handle
+ // -bool: result: true->unload, false->don't unload
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_RunUnloadHandlers, int, bool)
+
+ // This message sets the current zoom level on the tab
+ // Request:
+ // -int: Tab handle
+ // -int: Zoom level. Values ZOOM_OUT = -1, RESET = 0, ZOOM_IN = 1
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED2(AutomationMsg_SetZoomLevel, int, int)
+
+ // Waits for tab count to reach target value.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_WaitForTabCountToBecome,
+ int /* browser handle */,
+ int /* target tab count */,
+ bool /* success */)
+
+ // Waits for the infobar count to reach given number.
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_WaitForInfoBarCount,
+ int /* tab handle */,
+ int /* target count */,
+ bool /* success */)
+
+ // Waits for the autocomplete edit to receive focus.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_WaitForAutocompleteEditFocus,
+ int /* autocomplete edit handle */,
+ bool /* success */)
+
+ // Loads all blocked plug-ins on the page.
+ IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_LoadBlockedPlugins,
+ int /* tab handle */,
+ bool /* success */)
+
+ // Captures the entire page for the tab, including those portions not in
+ // view, and saves the image as a PNG in the given file location.
+ // Request:
+ // -int: Tab handle
+ // -FilePath: Path to save the captured image to
+ // Response:
+ // -bool: Whether the method succeeded
+ IPC_SYNC_MESSAGE_ROUTED2_1(AutomationMsg_CaptureEntirePageAsPNG, int,
+ FilePath, bool)
+
+IPC_END_MESSAGES(Automation)
diff --git a/chrome/common/child_process_info.cc b/chrome/common/child_process_info.cc
index bd94ff2..1af0cdb 100644
--- a/chrome/common/child_process_info.cc
+++ b/chrome/common/child_process_info.cc
@@ -64,6 +64,8 @@ std::string ChildProcessInfo::GetTypeNameInEnglish(
return "Native Client broker";
case GPU_PROCESS:
return "GPU";
+ case PPAPI_PLUGIN_PROCESS:
+ return "Pepper Plugin";
case UNKNOWN_PROCESS:
default:
DCHECK(false) << "Unknown child process type!";
@@ -96,6 +98,7 @@ string16 ChildProcessInfo::GetLocalizedTitle() const {
return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NACL_BROKER_PREFIX);
case ChildProcessInfo::PLUGIN_PROCESS:
+ case ChildProcessInfo::PPAPI_PLUGIN_PROCESS:
return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PLUGIN_PREFIX,
title,
WideToUTF16Hack(version_));
diff --git a/chrome/common/child_process_info.h b/chrome/common/child_process_info.h
index 78b0a2a..651978f 100644
--- a/chrome/common/child_process_info.h
+++ b/chrome/common/child_process_info.h
@@ -28,7 +28,8 @@ class ChildProcessInfo {
ZYGOTE_PROCESS,
SANDBOX_HELPER_PROCESS,
NACL_BROKER_PROCESS,
- GPU_PROCESS
+ GPU_PROCESS,
+ PPAPI_PLUGIN_PROCESS
};
ChildProcessInfo(const ChildProcessInfo& original);
diff --git a/chrome/common/child_process_logging.h b/chrome/common/child_process_logging.h
index bcc5ecd..4c4343c 100644
--- a/chrome/common/child_process_logging.h
+++ b/chrome/common/child_process_logging.h
@@ -14,7 +14,7 @@
class GPUInfo;
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_MACOSX)
// The maximum number of active extensions we will report.
// Also used in chrome/app, but we define it here to avoid a common->app
// dependency.
diff --git a/chrome/common/child_process_logging_mac.mm b/chrome/common/child_process_logging_mac.mm
index a61202c..ca12d1c 100644
--- a/chrome/common/child_process_logging_mac.mm
+++ b/chrome/common/child_process_logging_mac.mm
@@ -26,6 +26,8 @@ const char *kGPUPixelShaderVersionParamName = "gpu-psver";
const char *kGPUVertexShaderVersionParamName = "gpu-vsver";
const char *kGPUGLVersionParamName = "gpu-glver";
const char *kNumberOfViews = "num-views";
+NSString* const kNumExtensionsName = @"num-extensions";
+NSString* const kExtensionNameFormat = @"extension-%d";
static SetCrashKeyValueFuncPtr g_set_key_func;
static ClearCrashKeyValueFuncPtr g_clear_key_func;
@@ -112,7 +114,25 @@ std::string GetClientId() {
}
void SetActiveExtensions(const std::set<std::string>& extension_ids) {
- // TODO(port)
+ if (!g_set_key_func)
+ return;
+
+ // Log the count separately to track heavy users.
+ const int count = static_cast<int>(extension_ids.size());
+ g_set_key_func(kNumExtensionsName, [NSString stringWithFormat:@"%i", count]);
+
+ // Record up to |kMaxReportedActiveExtensions| extensions, clearing
+ // keys if there aren't that many.
+ std::set<std::string>::const_iterator iter = extension_ids.begin();
+ for (int i = 0; i < kMaxReportedActiveExtensions; ++i) {
+ NSString* key = [NSString stringWithFormat:kExtensionNameFormat, i];
+ if (iter != extension_ids.end()) {
+ g_set_key_func(key, [NSString stringWithUTF8String:iter->c_str()]);
+ ++iter;
+ } else {
+ g_clear_key_func(key);
+ }
+ }
}
void SetGpuKeyValue(const char* param_name, const std::string& value_str,
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index ff007df..6ba6de8 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -22,6 +22,10 @@ const char kActivateOnLaunch[] = "activate-on-launch";
// override for developers who need the old behavior for testing.
const char kAllowFileAccessFromFiles[] = "allow-file-access-from-files";
+// On ChromeOS, file:// access is disabled except for certain whitelisted
+// directories. This switch re-enables file:// for testing.
+const char kAllowFileAccess[] = "allow-file-access";
+
// Disable checking of the renegotiation extension and any future checks over
// and above what a "traditional" SSL stack might do. This has been requested
// in order to support some web development tools that intercept SSL
@@ -47,6 +51,11 @@ const char kApp[] = "app";
// according to its configuration.
const char kAppId[] = "app-id";
+// Specifying this flag allows the webstorePrivate APIs to return browser (aka
+// sync) login tokens to be used for auto-login in the Web Store (normally they
+// do not).
+const char kAppsGalleryReturnTokens[] = "apps-gallery-return-tokens";
+
// The URL to use for the gallery link in the app launcher.
const char kAppsGalleryURL[] = "apps-gallery-url";
@@ -92,6 +101,10 @@ const char kCheckForUpdateIntervalSec[] = "check-for-update-interval";
// as a dependent process of the Chrome Frame plugin.
const char kChromeFrame[] = "chrome-frame";
+// Tells chrome to load the specified version of chrome.dll on Windows. If
+// this version cannot be loaded, Chrome will exit.
+const char kChromeVersion[] = "chrome-version";
+
// The unique id to be used for this cloud print proxy instance.
const char kCloudPrintProxyId[] = "cloud-print-proxy-id";
@@ -112,6 +125,11 @@ const char kCountry[] = "country";
// Enables support to debug printing subsystem.
const char kDebugPrint[] = "debug-print";
+// Specifies the URL at which to fetch configuration policy from the device
+// management backend. Specifying this switch turns on managed policy from the
+// device management backend.
+const char kDeviceManagementUrl[] = "device-management-url";
+
// Triggers a pletora of diagnostic modes.
const char kDiagnostics[] = "diagnostics";
@@ -148,9 +166,6 @@ const char kDisableBackgroundNetworking[] = "disable-background-networking";
// users with many windows/tabs and lots of memory.
const char kDisableBackingStoreLimit[] = "disable-backing-store-limit";
-// Disable click-to-play for blocked plug-ins.
-const char kDisableClickToPlay[] = "disable-click-to-play";
-
// Disables establishing a backup TCP connection if a specified timeout is
// exceeded.
const char kDisableConnectBackupJobs[] = "disable-connect-backup-jobs";
@@ -189,6 +204,9 @@ const char kDisableExtensionsFileAccessCheck[] =
// Disable FileSystem API.
const char kDisableFileSystem[] = "disable-file-system";
+// Disables the sandbox for the built-in flash player.
+const char kDisableFlashSandbox[] = "disable-flash-sandbox";
+
// Suppresses support for the Geolocation javascript API.
const char kDisableGeolocation[] = "disable-geolocation";
@@ -382,6 +400,9 @@ const char kEnableBenchmarking[] = "enable-benchmarking";
// until there's a server endpoint deployed.
const char kEnableClearServerData[] = "enable-clear-server-data";
+// Enable click-to-play for blocked plug-ins.
+const char kEnableClickToPlay[] = "enable-click-to-play";
+
// This applies only when the process type is "service". Enables the
// Cloud Print Proxy component within the service process.
const char kEnableCloudPrintProxy[] = "enable-cloud-print-proxy";
@@ -490,6 +511,9 @@ const char kEnableSearchProviderApiV2[] = "enable-search-provider-api-v2";
// Enables 0-RTT HTTPS handshakes.
const char kEnableSnapStart[] = "enable-snap-start";
+// Enables speech input.
+const char kEnableSpeechInput[] = "enable-speech-input";
+
// Enables StatsTable, logging statistics to a global named shared memory table.
const char kEnableStatsTable[] = "enable-stats-table";
@@ -625,6 +649,9 @@ const char kGpuProcess[] = "gpu-process";
// Causes the GPU process to display a dialog on launch.
const char kGpuStartupDialog[] = "gpu-startup-dialog";
+// Specifies a custom name for the GSSAPI library to load.
+const char kGSSAPILibraryName[] = "gssapi-library-name";
+
// These flags show the man page on Linux. They are equivalent to each
// other.
const char kHelp[] = "help";
@@ -841,6 +868,18 @@ const char kPluginProcess[] = "plugin";
// Causes the plugin process to display a dialog on launch.
const char kPluginStartupDialog[] = "plugin-startup-dialog";
+// Runs PPAPI (Pepper) plugins out-of-process.
+const char kPpapiOutOfProcess[] = "ppapi-out-of-process";
+
+// Like kPluginLauncher for PPAPI plugins.
+const char kPpapiPluginLauncher[] = "ppapi-plugin-launcher";
+
+// Argument to the process type that indicates a PPAPI plugin process type.
+const char kPpapiPluginProcess[] = "ppapi";
+
+// Causes the PPAPI sub process to display a dialog on launch.
+const char kPpapiStartupDialog[] = "ppapi-startup-dialog";
+
// Establishes a channel to the GPU process asynchronously and (re)launches it
// if necessary when a renderer process starts.
const char kPrelaunchGpuProcess[] = "prelaunch-gpu-process";
@@ -972,9 +1011,6 @@ const char kServiceAccountLsid[] = "service-account-lsid";
// See kHideIcons.
const char kShowIcons[] = "show-icons";
-// If true the instant opt-in promo is shown in the omnibox.
-const char kShowInstantOptIn[] = "show-instant-opt-in";
-
// Renders a border around composited Render Layers to help debug and study
// layer compositing.
const char kShowCompositedLayerBorders[] = "show-composited-layer-borders";
@@ -1164,6 +1200,9 @@ const char kLoginUser[] = "login-user";
// Specifies a password to be used to login (along with login-user).
const char kLoginPassword[] = "login-password";
+// Allows to emulate situation when user logins with new password.
+const char kLoginUserWithNewPassword[] = "login-user-with-new-password";
+
// Attempts to perform Chrome OS offline and online login in parallel.
const char kParallelAuth[] = "parallel-auth";
@@ -1189,11 +1228,16 @@ const char kCompressSystemFeedback[] = "compress-sys-feedback";
// Forces usage of libcros stub implementation. For testing purposes, this
// switch separates chrome code from the rest of ChromeOS.
-const char kForceStubLibcros[] = "force-stub-libcros";
+const char kForceStubLibcros[] = "force-stub-libcros";
// Enables DOMUI menu.
-const char kEnableDOMUIMenu[] = "enable-domui-menu";
+const char kEnableDOMUIMenu[] = "enable-domui-menu";
+
+// Enables Media Player.
+const char kEnableMediaPlayer[] = "enable-media-player";
+// Enables Advanced File System.
+const char kEnableAdvancedFileSystem[] = "enable-advanced-fs";
#endif
#if defined(OS_LINUX)
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 49c3e49..2f30352 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -22,12 +22,14 @@ namespace switches {
// alongside the definition of their values in the .cc file.
extern const char kActivateOnLaunch[];
extern const char kAllowFileAccessFromFiles[];
+extern const char kAllowFileAccess[];
extern const char kAllowSSLMITMProxies[];
extern const char kAllowSandboxDebugging[];
extern const char kAllowScriptingGallery[];
extern const char kAlwaysEnableDevTools[];
extern const char kApp[];
extern const char kAppId[];
+extern const char kAppsGalleryReturnTokens[];
extern const char kAppsGalleryURL[];
extern const char kAppsNoThrob[];
extern const char kAuthNegotiateDelegateWhitelist[];
@@ -40,11 +42,13 @@ extern const char kBrowserCrashTest[];
extern const char kBrowserSubprocessPath[];
extern const char kCheckForUpdateIntervalSec[];
extern const char kChromeFrame[];
+extern const char kChromeVersion[];
extern const char kCloudPrintProxyId[];
extern const char kCloudPrintServiceURL[];
extern const char kConflictingModulesCheck[];
extern const char kCountry[];
extern const char kDebugPrint[];
+extern const char kDeviceManagementUrl[];
extern const char kDiagnostics[];
extern const char kDisableAcceleratedCompositing[];
extern const char kDisableAltWinstation[];
@@ -53,7 +57,6 @@ extern const char kDisableAudio[];
extern const char kDisableAuthNegotiateCnameLookup[];
extern const char kDisableBackgroundNetworking[];
extern const char kDisableBackingStoreLimit[];
-extern const char kDisableClickToPlay[];
extern const char kDisableConnectBackupJobs[];
extern const char kDisableContentPrefetch[];
extern const char kDisableCustomJumpList[];
@@ -65,6 +68,7 @@ extern const char kDisableExperimentalWebGL[];
extern const char kDisableExtensionsFileAccessCheck[];
extern const char kDisableExtensions[];
extern const char kDisableFileSystem[];
+extern const char kDisableFlashSandbox[];
extern const char kDisableGLSLTranslator[];
extern const char kDisableGeolocation[];
extern const char kDisableGpuWatchdog[];
@@ -119,6 +123,7 @@ extern const char kEnableAuthNegotiatePort[];
extern const char kEnableBackgroundMode[];
extern const char kEnableBenchmarking[];
extern const char kEnableClearServerData[];
+extern const char kEnableClickToPlay[];
extern const char kEnableCloudPrintProxy[];
extern const char kEnableCloudPrint[];
extern const char kEnableConfirmToQuit[];
@@ -149,6 +154,7 @@ extern const char kEnableRemoting[];
extern const char kEnableResourceContentSettings[];
extern const char kEnableSearchProviderApiV2[];
extern const char kEnableSnapStart[];
+extern const char kEnableSpeechInput[];
extern const char kEnableStatsTable[];
extern const char kEnableSync[];
extern const char kEnableSyncAutofill[];
@@ -185,6 +191,7 @@ extern const char kForceRendererAccessibility[];
extern const char kGpuLauncher[];
extern const char kGpuProcess[];
extern const char kGpuStartupDialog[];
+extern const char kGSSAPILibraryName[];
extern const char kHelp[];
extern const char kHelpShort[];
extern const char kHideIcons[];
@@ -242,6 +249,10 @@ extern const char kPluginLauncher[];
extern const char kPluginPath[];
extern const char kPluginProcess[];
extern const char kPluginStartupDialog[];
+extern const char kPpapiOutOfProcess[];
+extern const char kPpapiPluginLauncher[];
+extern const char kPpapiPluginProcess[];
+extern const char kPpapiStartupDialog[];
extern const char kPrelaunchGpuProcess[];
extern const char kPrint[];
extern const char kProcessPerSite[];
@@ -274,7 +285,6 @@ extern const char kServiceProcess[];
extern const char kServiceAccountLsid[];
extern const char kShowCompositedLayerBorders[];
extern const char kShowIcons[];
-extern const char kShowInstantOptIn[];
extern const char kShowPaintRects[];
extern const char kSilentDumpOnDCHECK[];
extern const char kSimpleDataSource[];
@@ -329,6 +339,7 @@ extern const char kTestLoadLibcros[];
extern const char kLoginProfile[];
extern const char kLoginUser[];
extern const char kLoginPassword[];
+extern const char kLoginUserWithNewPassword[];
extern const char kParallelAuth[];
extern const char kChromeosFrame[];
extern const char kCandidateWindowLang[];
@@ -338,6 +349,8 @@ extern const char kScreenSaverUrl[];
extern const char kCompressSystemFeedback[];
extern const char kForceStubLibcros[];
extern const char kEnableDOMUIMenu[];
+extern const char kEnableMediaPlayer[];
+extern const char kEnableAdvancedFileSystem[];
#endif
#if defined(OS_LINUX)
diff --git a/chrome/common/common_param_traits.cc b/chrome/common/common_param_traits.cc
index 2fd8bdd..ca5e90b 100644
--- a/chrome/common/common_param_traits.cc
+++ b/chrome/common/common_param_traits.cc
@@ -9,6 +9,7 @@
#include "chrome/common/content_settings.h"
#include "chrome/common/geoposition.h"
#include "chrome/common/thumbnail_score.h"
+#include "chrome/common/web_apps.h"
#include "gfx/rect.h"
#include "googleurl/src/gurl.h"
#include "net/base/upload_data.h"
@@ -18,7 +19,6 @@
#ifndef EXCLUDE_SKIA_DEPENDENCIES
#include "third_party/skia/include/core/SkBitmap.h"
#endif
-#include "webkit/glue/dom_operations.h"
#include "webkit/glue/password_form.h"
namespace IPC {
@@ -227,8 +227,8 @@ void ParamTraits<ContentSettings>::Log(
l->append("<ContentSettings>");
}
-void ParamTraits<webkit_glue::WebApplicationInfo>::Write(
- Message* m, const webkit_glue::WebApplicationInfo& p) {
+void ParamTraits<WebApplicationInfo>::Write(Message* m,
+ const WebApplicationInfo& p) {
WriteParam(m, p.title);
WriteParam(m, p.description);
WriteParam(m, p.app_url);
@@ -240,8 +240,8 @@ void ParamTraits<webkit_glue::WebApplicationInfo>::Write(
}
}
-bool ParamTraits<webkit_glue::WebApplicationInfo>::Read(
- const Message* m, void** iter, webkit_glue::WebApplicationInfo* r) {
+bool ParamTraits<WebApplicationInfo>::Read(
+ const Message* m, void** iter, WebApplicationInfo* r) {
size_t icon_count;
bool result =
ReadParam(m, iter, &r->title) &&
@@ -263,8 +263,8 @@ bool ParamTraits<webkit_glue::WebApplicationInfo>::Read(
return true;
}
-void ParamTraits<webkit_glue::WebApplicationInfo>::Log(
- const webkit_glue::WebApplicationInfo& p, std::string* l) {
+void ParamTraits<WebApplicationInfo>::Log(const WebApplicationInfo& p,
+ std::string* l) {
l->append("<WebApplicationInfo>");
}
diff --git a/chrome/common/common_param_traits.h b/chrome/common/common_param_traits.h
index d8796d6..6862482 100644
--- a/chrome/common/common_param_traits.h
+++ b/chrome/common/common_param_traits.h
@@ -40,6 +40,7 @@ class DictionaryValue;
class ListValue;
struct ThumbnailScore;
class URLRequestStatus;
+struct WebApplicationInfo;
class WebCursor;
namespace gfx {
@@ -58,7 +59,6 @@ struct PageRange;
namespace webkit_glue {
struct PasswordForm;
-struct WebApplicationInfo;
} // namespace webkit_glue
namespace IPC {
@@ -231,8 +231,8 @@ struct ParamTraits<WebCursor> {
template <>
-struct ParamTraits<webkit_glue::WebApplicationInfo> {
- typedef webkit_glue::WebApplicationInfo param_type;
+struct ParamTraits<WebApplicationInfo> {
+ typedef WebApplicationInfo param_type;
static void Write(Message* m, const param_type& p);
static bool Read(const Message* m, void** iter, param_type* r);
static void Log(const param_type& p, std::string* l);
diff --git a/chrome/common/common_param_traits_unittest.cc b/chrome/common/common_param_traits_unittest.cc
index 48b08f8..6086c12 100644
--- a/chrome/common/common_param_traits_unittest.cc
+++ b/chrome/common/common_param_traits_unittest.cc
@@ -18,15 +18,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#if defined(OS_WIN)
-#ifndef NDEBUG
-namespace {
-void IgnoreAssertHandler(const std::string& str) {
-}
-} // namespace
-#endif // NDEBUG
-#endif // defined(OS_WIN)
-
// Tests that serialize/deserialize correctly understand each other
TEST(IPCMessageTest, Serialize) {
const char* serialize_cases[] = {
@@ -234,12 +225,11 @@ TEST(IPCMessageTest, PageRange) {
EXPECT_TRUE(input == output);
}
-// Enabling this test breaks assert handling for test suite. Bug 55177.
// Tests printing::NativeMetafile serialization.
-TEST(IPCMessageTest, DISABLED_Metafile) {
- // TODO(sanjeevr): Make this test meaningful for non-Windows platforms. We
- // need to initialize the metafile using alternate means on the other OSes.
+// TODO(sanjeevr): Make this test meaningful for non-Windows platforms. We
+// need to initialize the metafile using alternate means on the other OSes.
#if defined(OS_WIN)
+TEST(IPCMessageTest, Metafile) {
printing::NativeMetafile metafile;
RECT test_rect = {0, 0, 100, 100};
// Create a metsfile using the screen DC as a reference.
@@ -269,14 +259,8 @@ TEST(IPCMessageTest, DISABLED_Metafile) {
// Make sure we don't read out the metafile!
printing::NativeMetafile bad_output;
iter = NULL;
- // The Emf code on Windows DCHECKs if it cannot create the metafile.
-#ifndef NDEBUG
- logging::SetLogAssertHandler(IgnoreAssertHandler);
-#endif // NDEBUG
EXPECT_FALSE(IPC::ParamTraits<printing::NativeMetafile>::Read(
&bad_msg, &iter, &bad_output));
-#else // defined(OS_WIN)
- NOTIMPLEMENTED();
-#endif // defined(OS_WIN)
}
+#endif // defined(OS_WIN)
diff --git a/chrome/common/common_resources.grd b/chrome/common/common_resources.grd
index ea1b784..fb7d8f9 100644
--- a/chrome/common/common_resources.grd
+++ b/chrome/common/common_resources.grd
@@ -12,6 +12,7 @@
<include name="IDR_EXTENSION_API_JSON" file="extensions\api\extension_api.json" type="BINDATA" />
<include name="IDR_I18N_TEMPLATE_JS" file="..\browser\resources\shared\js\i18n_template.js" type="BINDATA" />
<include name="IDR_JSTEMPLATE_JS" file="..\third_party\jstemplate\jstemplate_compiled.js" type="BINDATA" />
+ <include name="IDR_WEB_APP_SCHEMA" file="web_app_schema.json" type="BINDATA" />
</includes>
</release>
</grit>
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index 45d9409..08235fb 100644
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -46,6 +46,7 @@
"lastError": {
"type": "object",
"optional": true,
+ "unprivileged": true,
"description": "Set for the lifetime of a callback if an ansychronous extension api has resulted in an error. If no error has occured lastError will be <var>undefined</var>.",
"properties": {
"message": { "type": "string", "description": "Description of the error that has taken place." }
@@ -80,14 +81,14 @@
],
"returns": {
"$ref": "Port",
- "description": "Port through which messages can be sent and received with the extension."
+ "description": "Port through which messages can be sent and received with the extension. The port's <a href='extension.html#type-Port'>onDisconnect</a> event is fired if extension does not exist. "
}
},
{
"name": "sendRequest",
"type": "function",
"unprivileged": true,
- "description": "Sends a single request to other listeners within the extension. Similar to chrome.extension.connect, but only sends a single request with an optional response.",
+ "description": "Sends a single request to other listeners within the extension. Similar to chrome.extension.connect, but only sends a single request with an optional response. The <a href='extension.html#event-onRequest'>chrome.extension.onRequest</a> event is fired in each page of the extension.",
"parameters": [
{"type": "string", "name": "extensionId", "optional": true, "description": "The extension ID of the extension you want to connect to. If omitted, default is your own extension."},
{ "type": "any", "name": "request" },
@@ -99,7 +100,7 @@
{
"name": "response",
"type": "any",
- "description": "The JSON response object sent by the handler of the request."
+ "description": "The JSON response object sent by the handler of the request. If an error occurs while connecting to the extension, the callback will be called with no arguments and <a href='extension.html#property-lastError'>chrome.extension.lastError</a> will be set to the error message."
}
]
}
@@ -188,6 +189,14 @@
"description": "Array of global window objects",
"items": { "type": "object", "isInstanceOf": "DOMWindow", "properties": {}, "additionalProperties": { "type": "any" } }
}
+ },
+ {
+ "name": "setUpdateUrlData",
+ "type": "function",
+ "description": "Sets the value of the ap CGI parameter used in the extension's update URL. This value is ignored for extensions that are hosted in the Chrome Extension Gallery.",
+ "parameters": [
+ {"type": "string", "name": "data", "maxLength": 1024}
+ ]
}
],
"events": [
@@ -3899,7 +3908,7 @@
]
},
{
- "namespace": "experimental.omnibox",
+ "namespace": "omnibox",
"types": [
{
"id": "SuggestResult",
@@ -3919,12 +3928,13 @@
"descriptionStyles": {
"type": "array",
"optional": true,
+ "description": "An array of style objects, created using styleUrl, styleMatch, or styleDim. A style applies to the region of text specified by the style's starting offset and length. If there are any overlapping regions of text covered by multiple styles, they will be added together (e.g. 'match' + 'dim' will display a dimmed match). Not all style combinations will be visually distinct (e.g. 'url' + 'dim' may look identical to 'url').",
"items": {
"type": "object",
- "description": "A style object, created using styleNone, styleUrl, styleMatch, or styleDim. A style applies to the region of text starting at the style's offset, until either the next style or the end of the description.",
"properties": {
- "type": {"type": "string", "enum": ["none", "url", "match", "dim"]},
- "offset": {"type": "integer"}
+ "type": {"type": "string", "enum": ["url", "match", "dim"]},
+ "offset": {"type": "integer"},
+ "length": {"type": "integer", "optional": true}
}
}
}
@@ -3949,28 +3959,31 @@
]
},
{
- "name": "styleNone",
- "type": "function",
- "description": "Constructor for the descriptionStyles parameter of the suggest callback.",
- "parameters": [ {"type": "integer", "name": "offset", "minimum": 0} ]
- },
- {
"name": "styleUrl",
"type": "function",
- "description": "Constructor for the descriptionStyles parameter of the suggest callback. This style designates a region of text matching a URL or filename.",
- "parameters": [ {"type": "integer", "name": "offset", "minimum": 0} ]
+ "description": "Constructor for the descriptionStyles parameter of the suggest callback. This style designates a region of text matching a URL or filename. A negative offset means the region will start at that many characters from the end of the description. If length is omitted, the region will apply for the rest of the description text.",
+ "parameters": [
+ {"type": "integer", "name": "offset"},
+ {"type": "integer", "name": "length", "minimum": 0, "optional": true}
+ ]
},
{
"name": "styleMatch",
"type": "function",
- "description": "Constructor for the descriptionStyles parameter of the suggest callback. This style designates a region of text matching what the user typed.",
- "parameters": [ {"type": "integer", "name": "offset", "minimum": 0} ]
+ "description": "Constructor for the descriptionStyles parameter of the suggest callback. This style designates a region of text matching what the user typed. A negative offset means the region will start at that many characters from the end of the description. If length is omitted, the region will apply for the rest of the description text.",
+ "parameters": [
+ {"type": "integer", "name": "offset"},
+ {"type": "integer", "name": "length", "minimum": 0, "optional": true}
+ ]
},
{
"name": "styleDim",
"type": "function",
- "description": "Constructor for the descriptionStyles parameter of the suggest callback. This style designates a region of dim helper text.",
- "parameters": [ {"type": "integer", "name": "offset", "minimum": 0} ]
+ "description": "Constructor for the descriptionStyles parameter of the suggest callback. This style designates a region of dim helper text. A negative offset means the region will start at that many characters from the end of the description. If length is omitted, the region will apply for the rest of the description text.",
+ "parameters": [
+ {"type": "integer", "name": "offset"},
+ {"type": "integer", "name": "length", "minimum": 0, "optional": true}
+ ]
}
],
"events": [
@@ -3994,7 +4007,6 @@
"type": "function",
"description": "A callback passed to the onInputChanged event used for sending suggestions back to the browser.",
"parameters": [
- {"type": "integer", "name": "requestId"},
{
"type": "array",
"description": "Array of suggest results",
@@ -4239,6 +4251,40 @@
]
},
{
+ "name": "beginInstall",
+ "description": "Initiates the install process for the given extension id",
+ "parameters": [
+ {
+ "name": "expected_id",
+ "type": "string",
+ "description": "The id of the extension to be installled. Must be called during a user gesture."
+ },
+ {
+ "name": "callback",
+ "type": "function",
+ "optional": "true",
+ "parameters": []
+ }
+ ]
+ },
+ {
+ "name": "completeInstall",
+ "description": "",
+ "parameters": [
+ {
+ "name": "expected_id",
+ "type": "string",
+ "description": "The id of the extension to be installled. This should match a previous call to beginInstall."
+ },
+ {
+ "name": "callback",
+ "type": "function",
+ "optional": "true",
+ "parameters": []
+ }
+ ]
+ },
+ {
"name": "getBrowserLogin",
"description": "Returns the logged-in sync user login if there is one, or the empty string otherwise.",
"parameters": [
diff --git a/chrome/common/extensions/docs/a11y.html b/chrome/common/extensions/docs/a11y.html
index 5c34cff..21e0c3b 100644
--- a/chrome/common/extensions/docs/a11y.html
+++ b/chrome/common/extensions/docs/a11y.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/api_index.html b/chrome/common/extensions/docs/api_index.html
index 299f041..b3aac33 100644
--- a/chrome/common/extensions/docs/api_index.html
+++ b/chrome/common/extensions/docs/api_index.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
@@ -323,7 +331,7 @@ Here are the supported chrome.* APIs:
</p>
<ul>
- <li><a href="bookmarks.html" js="">bookmarks</a></li><li><a href="browserAction.html" js="">browserAction</a></li><li><a href="contextMenus.html" js="">contextMenus</a></li><li><a href="cookies.html" js="">cookies</a></li><li><a href="extension.html" js="">extension</a></li><li><a href="history.html" js="">history</a></li><li><a href="i18n.html" js="">i18n</a></li><li><a href="idle.html" js="">idle</a></li><li><a href="management.html" js="">management</a></li><li><a href="pageAction.html" js="">pageAction</a></li><li><a href="tabs.html" js="">tabs</a></li><li><a href="windows.html" js="">windows</a></li>
+ <li><a href="bookmarks.html" js="">bookmarks</a></li><li><a href="browserAction.html" js="">browserAction</a></li><li><a href="contextMenus.html" js="">contextMenus</a></li><li><a href="cookies.html" js="">cookies</a></li><li><a href="extension.html" js="">extension</a></li><li><a href="history.html" js="">history</a></li><li><a href="i18n.html" js="">i18n</a></li><li><a href="idle.html" js="">idle</a></li><li><a href="management.html" js="">management</a></li><li><a href="omnibox.html" js="">omnibox</a></li><li><a href="pageAction.html" js="">pageAction</a></li><li><a href="tabs.html" js="">tabs</a></li><li><a href="windows.html" js="">windows</a></li>
</ul>
<h2 id="experimental">Experimental APIs</h2>
diff --git a/chrome/common/extensions/docs/api_other.html b/chrome/common/extensions/docs/api_other.html
index a4c11c6..aed296a 100644
--- a/chrome/common/extensions/docs/api_other.html
+++ b/chrome/common/extensions/docs/api_other.html
@@ -223,7 +223,15 @@
<li class="leftNavSelected">Other APIs</li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/autoupdate.html b/chrome/common/extensions/docs/autoupdate.html
index b8c8ea5..57a70d2 100644
--- a/chrome/common/extensions/docs/autoupdate.html
+++ b/chrome/common/extensions/docs/autoupdate.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/background_pages.html b/chrome/common/extensions/docs/background_pages.html
index e0760ef..b1029a1 100644
--- a/chrome/common/extensions/docs/background_pages.html
+++ b/chrome/common/extensions/docs/background_pages.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/bookmarks.html b/chrome/common/extensions/docs/bookmarks.html
index b906190..20a1084 100644
--- a/chrome/common/extensions/docs/bookmarks.html
+++ b/chrome/common/extensions/docs/bookmarks.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/browserAction.html b/chrome/common/extensions/docs/browserAction.html
index 4e00a55..b9827ea 100644
--- a/chrome/common/extensions/docs/browserAction.html
+++ b/chrome/common/extensions/docs/browserAction.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/build/build.py b/chrome/common/extensions/docs/build/build.py
index 1ff2e0f..220924e 100755
--- a/chrome/common/extensions/docs/build/build.py
+++ b/chrome/common/extensions/docs/build/build.py
@@ -204,11 +204,14 @@ def main():
# Write zipped versions of the samples listed in the manifest to the
# filesystem, unless the user has disabled it
if options.zips:
- samples_manifest.writeZippedSamples()
+ modified_zips = samples_manifest.writeZippedSamples()
+ else:
+ modified_zips = []
modified_files = RenderPages(page_names, test_shell)
+ modified_files.extend(modified_zips)
- if (len(modified_files) == 0):
+ if len(modified_files) == 0:
print "Output files match existing files. No changes made."
else:
print ("ATTENTION: EXTENSION DOCS HAVE CHANGED\n" +
@@ -216,7 +219,7 @@ def main():
"into source control (ideally in the same changelist as the\n" +
"underlying files that resulting in their changing).")
for f in modified_files:
- print f
+ print " * %s" % f
# Hack. Sleep here, otherwise windows doesn't properly close the debug.log
# and the os.remove will fail with a "Permission denied".
diff --git a/chrome/common/extensions/docs/build/directory.py b/chrome/common/extensions/docs/build/directory.py
index 79f5dd7..f95344f 100644
--- a/chrome/common/extensions/docs/build/directory.py
+++ b/chrome/common/extensions/docs/build/directory.py
@@ -225,8 +225,7 @@ class SamplesManifest(object):
Args:
path: The path to write the samples manifest file to.
"""
-
- manifest_text = json.dumps(self._manifest_data, indent=2)
+ manifest_text = json.dumps(self._manifest_data, indent=2, sort_keys=True)
output_path = os.path.realpath(path)
try:
output_file = open(output_path, 'w')
@@ -238,10 +237,18 @@ class SamplesManifest(object):
def writeZippedSamples(self):
""" For each sample in the current manifest, create a zip file with the
- sample contents in the sample's parent directory. """
+ sample contents in the sample's parent directory if not zip exists, or
+ update the zip file if the sample has been updated.
+ Returns:
+ A set of paths representing zip files which have been modified.
+ """
+ modified_paths = []
for sample in self._manifest_data['samples']:
- sample.write_zip()
+ path = sample.write_zip()
+ if path:
+ modified_paths.append(path)
+ return modified_paths
class Sample(dict):
""" Represents metadata about a Chrome extension sample.
@@ -264,10 +271,13 @@ class Sample(dict):
self._manifest = parse_json_file(self._manifest_path)
self._locale_data = self._parse_locale_data()
- # The following properties will be serialized when converting this object
- # to JSON.
+ # The following calls set data which will be serialized when converting
+ # this object to JSON.
+ source_data = self._parse_source_data(api_methods)
+ self['api_calls'] = source_data['api_calls']
+ self['source_files'] = source_data['source_files']
+ self['source_hash'] = source_data['source_hash']
- self['api_calls'] = self._parse_api_calls(api_methods)
self['name'] = self._parse_name()
self['description'] = self._parse_description()
self['icon'] = self._parse_icon()
@@ -275,7 +285,6 @@ class Sample(dict):
self['protocols'] = self._parse_protocols()
self['path'] = self._get_relative_path()
self['search_string'] = self._get_search_string()
- self['source_files'] = self._parse_source_files()
self['id'] = hashlib.sha1(self['path']).hexdigest()
self['zip_path'] = self._get_relative_zip_path()
@@ -421,62 +430,6 @@ class Sample(dict):
sample_dirname = os.path.basename(sample_path)
return "%s.zip" % sample_dirname
- def _parse_api_calls(self, api_methods):
- """ Returns a list of Chrome extension API calls the sample makes.
-
- Parses any *.html and *.js files in the sample directory and matches them
- against the supplied list of all available API methods, returning methods
- which show up in the sample code.
-
- Args:
- api_methods: A list of strings containing the potential
- API calls the and the extension sample could be making.
-
- Returns:
- A set of every member of api_methods that appears in any *.html or *.js
- file contained in this sample's directory (or subdirectories).
-
- Raises:
- Exception: If any of the *.html or *.js files cannot be read.
- """
- api_calls = set()
- extension_dir_path = os.path.dirname(self._manifest_path)
- for root, dirs, files in sorted_walk(extension_dir_path):
- for file in files:
- if file[-5:] == '.html' or file[-3:] == '.js':
- path = os.path.join(root, file)
- try:
- code_file = open(path)
- except IOError, msg:
- raise Exception("Failed to read %s: %s" % (path, msg))
- code_contents = code_file.read()
- code_file.close()
-
- for method in api_methods:
- if (code_contents.find(method) > -1):
- api_calls.add(method)
- return sorted(api_calls)
-
- def _parse_source_files(self):
- """ Returns a list of paths to source files present in the extenion.
-
- Returns:
- A list of paths relative to the manifest file directory.
- """
- source_paths = []
- base_path = os.path.realpath(os.path.dirname(self._manifest_path))
- for root, directories, files in sorted_walk(base_path):
- if '.svn' in directories:
- directories.remove('.svn') # Don't go into SVN metadata directories
-
- for file_name in files:
- ext = os.path.splitext(file_name)[1]
- if ext in self._SOURCE_FILE_EXTENSIONS:
- path = os.path.realpath(os.path.join(root, file_name))
- path = path.replace(base_path, '')[1:]
- source_paths.append(path)
- return sorted(source_paths)
-
def _parse_description(self):
""" Returns a localized description of the extension.
@@ -577,6 +530,66 @@ class Sample(dict):
protocols.append(split[0] + "://")
return protocols
+ def _parse_source_data(self, api_methods):
+ """ Iterates over the sample's source files and parses data from them.
+
+ Parses any files in the sample directory with known source extensions
+ (as defined in self._SOURCE_FILE_EXTENSIONS). For each file, this method:
+
+ 1. Stores a relative path from the manifest.json directory to the file.
+ 2. Searches through the contents of the file for chrome.* API calls.
+ 3. Calculates a SHA1 digest for the contents of the file.
+
+ Args:
+ api_methods: A list of strings containing the potential
+ API calls the and the extension sample could be making.
+
+ Raises:
+ Exception: If any of the source files cannot be read.
+
+ Returns:
+ A dictionary containing the keys/values:
+ 'api_calls' A sorted list of API calls the sample makes.
+ 'source_files' A sorted list of paths to files the extension uses.
+ 'source_hash' A hash of the individual file hashes.
+ """
+ data = {}
+ source_paths = []
+ source_hashes = []
+ api_calls = set()
+ base_path = os.path.realpath(os.path.dirname(self._manifest_path))
+ for root, directories, files in sorted_walk(base_path):
+ if '.svn' in directories:
+ directories.remove('.svn') # Don't go into SVN metadata directories
+
+ for file_name in files:
+ ext = os.path.splitext(file_name)[1]
+ if ext in self._SOURCE_FILE_EXTENSIONS:
+ # Add the file path to the list of source paths.
+ fullpath = os.path.realpath(os.path.join(root, file_name))
+ path = fullpath.replace(base_path, '')[1:]
+ source_paths.append(path)
+
+ # Read the contents and parse out API calls.
+ try:
+ code_file = open(fullpath, "r")
+ except IOError, msg:
+ raise Exception("Failed to read %s: %s" % (fullpath, msg))
+ code_contents = unicode(code_file.read(), errors="replace")
+ code_file.close()
+ for method in api_methods:
+ if (code_contents.find(method) > -1):
+ api_calls.add(method)
+
+ # Get a hash of the file contents for zip file generation.
+ hash = hashlib.sha1(code_contents.encode("ascii", "replace"))
+ source_hashes.append(hash.hexdigest())
+
+ data['api_calls'] = sorted(api_calls)
+ data['source_files'] = sorted(source_paths)
+ data['source_hash'] = hashlib.sha1(''.join(source_hashes)).hexdigest()
+ return data
+
def _uses_background(self):
""" Returns true if the extension defines a background page. """
return self._manifest.has_key('background_page')
@@ -618,6 +631,26 @@ class Sample(dict):
zip_filename = self._get_zip_filename()
zip_path = os.path.join(sample_parentpath, zip_filename)
+ zip_manifest_path = os.path.join(sample_dirname, 'manifest.json')
+
+ zipfile.ZipFile.debug = 3
+
+ if os.path.isfile(zip_path):
+ try:
+ old_zip_file = zipfile.ZipFile(zip_path, 'r')
+ except IOError, msg:
+ raise Exception("Could not read zip at %s: %s" % (zip_path, msg))
+
+ try:
+ info = old_zip_file.getinfo(zip_manifest_path)
+ hash = info.comment
+ if hash == self['source_hash']:
+ return None # Hashes match - no need to generate file
+ except KeyError, msg:
+ pass # The old zip file doesn't contain a hash - overwrite
+ finally:
+ old_zip_file.close()
+
zip_file = zipfile.ZipFile(zip_path, 'w')
try:
@@ -629,8 +662,14 @@ class Sample(dict):
abspath = os.path.realpath(os.path.join(root, file))
# Relative path to store the file in under the zip.
relpath = sample_dirname + abspath.replace(sample_path, "")
+
zip_file.write(abspath, relpath)
+ if file == 'manifest.json':
+ info = zip_file.getinfo(zip_manifest_path)
+ info.comment = self['source_hash']
except RuntimeError, msg:
- raise Exception("Could not write zip at " % zip_path)
+ raise Exception("Could not write zip at %s: %s" % (zip_path, msg))
finally:
zip_file.close()
+
+ return self._get_relative_zip_path()
diff --git a/chrome/common/extensions/docs/content_scripts.html b/chrome/common/extensions/docs/content_scripts.html
index c2845b8..407ae71 100644
--- a/chrome/common/extensions/docs/content_scripts.html
+++ b/chrome/common/extensions/docs/content_scripts.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/contextMenus.html b/chrome/common/extensions/docs/contextMenus.html
index 6f055fd..4e9833a 100644
--- a/chrome/common/extensions/docs/contextMenus.html
+++ b/chrome/common/extensions/docs/contextMenus.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/cookies.html b/chrome/common/extensions/docs/cookies.html
index 482a342..8fcc978 100644
--- a/chrome/common/extensions/docs/cookies.html
+++ b/chrome/common/extensions/docs/cookies.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/crx.html b/chrome/common/extensions/docs/crx.html
index 22ad2b5..92e395f 100644
--- a/chrome/common/extensions/docs/crx.html
+++ b/chrome/common/extensions/docs/crx.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/css/ApiRefStyles.css b/chrome/common/extensions/docs/css/ApiRefStyles.css
index ebc8669..5759b38 100644
--- a/chrome/common/extensions/docs/css/ApiRefStyles.css
+++ b/chrome/common/extensions/docs/css/ApiRefStyles.css
@@ -1370,3 +1370,10 @@ table.noborders td {
float:none
}
+#gc-toc div.line {
+ border-top: thin dotted #bbb;
+ height: 1px;
+ margin: 1.3em 1em 0 0;
+ padding: 0;
+}
+
diff --git a/chrome/common/extensions/docs/devguide.html b/chrome/common/extensions/docs/devguide.html
index 2669a04..0ea612b 100644
--- a/chrome/common/extensions/docs/devguide.html
+++ b/chrome/common/extensions/docs/devguide.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/docs.html b/chrome/common/extensions/docs/docs.html
index 685f6aa..81ff7a0 100644
--- a/chrome/common/extensions/docs/docs.html
+++ b/chrome/common/extensions/docs/docs.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/events.html b/chrome/common/extensions/docs/events.html
index be42e7b..c00cc03 100644
--- a/chrome/common/extensions/docs/events.html
+++ b/chrome/common/extensions/docs/events.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/examples/api/bookmarks/basic.zip b/chrome/common/extensions/docs/examples/api/bookmarks/basic.zip
index fddc7df..73a1258 100644
--- a/chrome/common/extensions/docs/examples/api/bookmarks/basic.zip
+++ b/chrome/common/extensions/docs/examples/api/bookmarks/basic.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/make_page_red.zip b/chrome/common/extensions/docs/examples/api/browserAction/make_page_red.zip
index aab9498..bcae4aa 100644
--- a/chrome/common/extensions/docs/examples/api/browserAction/make_page_red.zip
+++ b/chrome/common/extensions/docs/examples/api/browserAction/make_page_red.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/print.zip b/chrome/common/extensions/docs/examples/api/browserAction/print.zip
index bf50d51..940789e 100644
--- a/chrome/common/extensions/docs/examples/api/browserAction/print.zip
+++ b/chrome/common/extensions/docs/examples/api/browserAction/print.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path.zip b/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path.zip
index 47b69c5..487d396 100644
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path.zip
+++ b/chrome/common/extensions/docs/examples/api/browserAction/set_icon_path.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color.zip b/chrome/common/extensions/docs/examples/api/browserAction/set_page_color.zip
index 9f2691f..9ed8ad8 100644
--- a/chrome/common/extensions/docs/examples/api/browserAction/set_page_color.zip
+++ b/chrome/common/extensions/docs/examples/api/browserAction/set_page_color.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/contextMenus/basic.zip b/chrome/common/extensions/docs/examples/api/contextMenus/basic.zip
index 3e505f9..5c942c4 100644
--- a/chrome/common/extensions/docs/examples/api/contextMenus/basic.zip
+++ b/chrome/common/extensions/docs/examples/api/contextMenus/basic.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/cookies.zip b/chrome/common/extensions/docs/examples/api/cookies.zip
index a02c566..30bf11a 100644
--- a/chrome/common/extensions/docs/examples/api/cookies.zip
+++ b/chrome/common/extensions/docs/examples/api/cookies.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/history/showHistory.zip b/chrome/common/extensions/docs/examples/api/history/showHistory.zip
index f347d0c..167c3dc 100644
--- a/chrome/common/extensions/docs/examples/api/history/showHistory.zip
+++ b/chrome/common/extensions/docs/examples/api/history/showHistory.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/i18n/cld.zip b/chrome/common/extensions/docs/examples/api/i18n/cld.zip
index 5cf6424..217241f 100644
--- a/chrome/common/extensions/docs/examples/api/i18n/cld.zip
+++ b/chrome/common/extensions/docs/examples/api/i18n/cld.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/i18n/getMessage.zip b/chrome/common/extensions/docs/examples/api/i18n/getMessage.zip
index 9dab5b0..f80317b 100644
--- a/chrome/common/extensions/docs/examples/api/i18n/getMessage.zip
+++ b/chrome/common/extensions/docs/examples/api/i18n/getMessage.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/idle/idle_simple.zip b/chrome/common/extensions/docs/examples/api/idle/idle_simple.zip
index b8d1b1d..81761f5 100644
--- a/chrome/common/extensions/docs/examples/api/idle/idle_simple.zip
+++ b/chrome/common/extensions/docs/examples/api/idle/idle_simple.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/infobars/sandwichbar.zip b/chrome/common/extensions/docs/examples/api/infobars/sandwichbar.zip
index 7961781..659af62 100644
--- a/chrome/common/extensions/docs/examples/api/infobars/sandwichbar.zip
+++ b/chrome/common/extensions/docs/examples/api/infobars/sandwichbar.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/messaging/timer.zip b/chrome/common/extensions/docs/examples/api/messaging/timer.zip
index 6fbefab..5f52559 100644
--- a/chrome/common/extensions/docs/examples/api/messaging/timer.zip
+++ b/chrome/common/extensions/docs/examples/api/messaging/timer.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/notifications.zip b/chrome/common/extensions/docs/examples/api/notifications.zip
index dc3b72c..46af038 100644
--- a/chrome/common/extensions/docs/examples/api/notifications.zip
+++ b/chrome/common/extensions/docs/examples/api/notifications.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/extension-docs.zip b/chrome/common/extensions/docs/examples/api/omnibox/extension-docs.zip
index 7e81cea..cc0a940 100644
--- a/chrome/common/extensions/docs/examples/api/omnibox/extension-docs.zip
+++ b/chrome/common/extensions/docs/examples/api/omnibox/extension-docs.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/extension-docs/background.html b/chrome/common/extensions/docs/examples/api/omnibox/extension-docs/background.html
index 19fcc45..96885d4 100644
--- a/chrome/common/extensions/docs/examples/api/omnibox/extension-docs/background.html
+++ b/chrome/common/extensions/docs/examples/api/omnibox/extension-docs/background.html
@@ -301,9 +301,9 @@
this.SEPARATOR = ' - ';
this.corpus_ = corpus;
this.tabManager_ = tabManager;
- chrome.experimental.omnibox.onInputChanged.addListener(
+ chrome.omnibox.onInputChanged.addListener(
this.onChanged_.bind(this));
- chrome.experimental.omnibox.onInputEntered.addListener(
+ chrome.omnibox.onInputEntered.addListener(
this.onEntered_.bind(this));
};
@@ -319,8 +319,8 @@
var name = match['name'];
var lastIndex = 0;
for (var i = 0; i < ranges.length; i++) {
- styles.push(chrome.experimental.omnibox.styleMatch(ranges[i][0]));
- styles.push(chrome.experimental.omnibox.styleNone(ranges[i][1]));
+ styles.push(chrome.omnibox.styleMatch(ranges[i][0]));
+ styles.push(chrome.omnibox.styleNone(ranges[i][1]));
lastIndex = ranges[i][1];
}
@@ -401,9 +401,9 @@
*/
OmniboxManager.prototype.pushStyle_ = function(styles, type, desc, text) {
desc += this.SEPARATOR;
- styles.push(chrome.experimental.omnibox['style' + type](desc.length));
+ styles.push(chrome.omnibox['style' + type](desc.length));
desc += text;
- styles.push(chrome.experimental.omnibox.styleNone(desc.length));
+ styles.push(chrome.omnibox.styleNone(desc.length));
return desc;
};
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/extension-docs/manifest.json b/chrome/common/extensions/docs/examples/api/omnibox/extension-docs/manifest.json
index 8e6b3b9..43c7e46 100644
--- a/chrome/common/extensions/docs/examples/api/omnibox/extension-docs/manifest.json
+++ b/chrome/common/extensions/docs/examples/api/omnibox/extension-docs/manifest.json
@@ -3,7 +3,6 @@
"description" : "Search the Chrome Extensions documentation. To use, type 'crdoc' plus a search term into the Omnibox.",
"version" : "1.0.0",
"permissions" : [
- "experimental",
"http://src.chromium.org/viewvc/*",
"tabs"
],
@@ -11,6 +10,6 @@
"16" : "icon-16.png",
"128" : "icon-128.png"
},
- "omnibox_keyword" : "crdoc",
+ "omnibox": { "keyword" : "crdoc" },
"background_page" : "background.html"
}
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/simple-example.zip b/chrome/common/extensions/docs/examples/api/omnibox/simple-example.zip
index 532eb00..069886a 100644
--- a/chrome/common/extensions/docs/examples/api/omnibox/simple-example.zip
+++ b/chrome/common/extensions/docs/examples/api/omnibox/simple-example.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/simple-example/background.html b/chrome/common/extensions/docs/examples/api/omnibox/simple-example/background.html
index ff83ff2..77868d6 100644
--- a/chrome/common/extensions/docs/examples/api/omnibox/simple-example/background.html
+++ b/chrome/common/extensions/docs/examples/api/omnibox/simple-example/background.html
@@ -1,7 +1,7 @@
<script>
// This event is fired each time the user updates the text in the omnibox,
// as long as the extension's keyword mode is still active.
-chrome.experimental.omnibox.onInputChanged.addListener(
+chrome.omnibox.onInputChanged.addListener(
function(text, suggest) {
console.log('inputChanged: ' + text);
suggest([
@@ -11,7 +11,7 @@ chrome.experimental.omnibox.onInputChanged.addListener(
});
// This event is fired with the user accepts the input in the omnibox.
-chrome.experimental.omnibox.onInputEntered.addListener(
+chrome.omnibox.onInputEntered.addListener(
function(text) {
console.log('inputEntered: ' + text);
alert('You just typed "' + text + '"');
diff --git a/chrome/common/extensions/docs/examples/api/omnibox/simple-example/manifest.json b/chrome/common/extensions/docs/examples/api/omnibox/simple-example/manifest.json
index c48a345..8f9c8a5 100644
--- a/chrome/common/extensions/docs/examples/api/omnibox/simple-example/manifest.json
+++ b/chrome/common/extensions/docs/examples/api/omnibox/simple-example/manifest.json
@@ -2,7 +2,6 @@
"name": "Omnibox Example",
"description" : "To use, type 'omnix' plus a search term into the Omnibox.",
"version": "1.0",
- "permissions": [ "experimental" ],
"background_page": "background.html",
- "omnibox_keyword": "omnix"
+ "omnibox": { "keyword" : "omnix" }
}
diff --git a/chrome/common/extensions/docs/examples/api/override/blank_ntp.zip b/chrome/common/extensions/docs/examples/api/override/blank_ntp.zip
index 08ccd58..dd7ae40 100644
--- a/chrome/common/extensions/docs/examples/api/override/blank_ntp.zip
+++ b/chrome/common/extensions/docs/examples/api/override/blank_ntp.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/override/override_igoogle.zip b/chrome/common/extensions/docs/examples/api/override/override_igoogle.zip
index daae5dc..f44a72a 100644
--- a/chrome/common/extensions/docs/examples/api/override/override_igoogle.zip
+++ b/chrome/common/extensions/docs/examples/api/override/override_igoogle.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content.zip b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content.zip
index 2c172a7..67d0a8a 100644
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content.zip
+++ b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_content.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url.zip b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url.zip
index 13e3ee3..e54ad62 100644
--- a/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url.zip
+++ b/chrome/common/extensions/docs/examples/api/pageAction/pageaction_by_url.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/pageAction/set_icon.zip b/chrome/common/extensions/docs/examples/api/pageAction/set_icon.zip
index c82a96c..afcf9e6 100644
--- a/chrome/common/extensions/docs/examples/api/pageAction/set_icon.zip
+++ b/chrome/common/extensions/docs/examples/api/pageAction/set_icon.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/processes/process_monitor.zip b/chrome/common/extensions/docs/examples/api/processes/process_monitor.zip
index 60d5641..0a3b8ef 100644
--- a/chrome/common/extensions/docs/examples/api/processes/process_monitor.zip
+++ b/chrome/common/extensions/docs/examples/api/processes/process_monitor.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/processes/show_tabs.zip b/chrome/common/extensions/docs/examples/api/processes/show_tabs.zip
index ba3c761..ebcc255 100644
--- a/chrome/common/extensions/docs/examples/api/processes/show_tabs.zip
+++ b/chrome/common/extensions/docs/examples/api/processes/show_tabs.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/tabs/inspector.zip b/chrome/common/extensions/docs/examples/api/tabs/inspector.zip
index 3041820..308a1e7 100644
--- a/chrome/common/extensions/docs/examples/api/tabs/inspector.zip
+++ b/chrome/common/extensions/docs/examples/api/tabs/inspector.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/tabs/screenshot.zip b/chrome/common/extensions/docs/examples/api/tabs/screenshot.zip
index 2fac0cd..02bf3a9 100644
--- a/chrome/common/extensions/docs/examples/api/tabs/screenshot.zip
+++ b/chrome/common/extensions/docs/examples/api/tabs/screenshot.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/api/windows/merge_windows.zip b/chrome/common/extensions/docs/examples/api/windows/merge_windows.zip
index 8e39ff7..a3f07ce 100644
--- a/chrome/common/extensions/docs/examples/api/windows/merge_windows.zip
+++ b/chrome/common/extensions/docs/examples/api/windows/merge_windows.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/benchmark.zip b/chrome/common/extensions/docs/examples/extensions/benchmark.zip
index 7f43bdb..a322ab3 100644
--- a/chrome/common/extensions/docs/examples/extensions/benchmark.zip
+++ b/chrome/common/extensions/docs/examples/extensions/benchmark.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/buildbot.zip b/chrome/common/extensions/docs/examples/extensions/buildbot.zip
index 1add723..d7eb8c4 100644
--- a/chrome/common/extensions/docs/examples/extensions/buildbot.zip
+++ b/chrome/common/extensions/docs/examples/extensions/buildbot.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar.zip b/chrome/common/extensions/docs/examples/extensions/calendar.zip
new file mode 100644
index 0000000..4ce9b2f
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en/messages.json b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en/messages.json
new file mode 100644
index 0000000..bb7517f
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en/messages.json
@@ -0,0 +1,38 @@
+{
+ "name": {"message": "Google Calendar Checker (by Google)"},
+ "description": {"message": "Quickly see the time until your next meeting from any of your calendars. Click on the button to be taken to your calendar."},
+ "title": {"message": "Google Calendar Checker"},
+ "direction": {"message" : "ltr"},
+ "noTitle": {"message" : "(No Title)"},
+ "optionsTitle": {"message" : "Google Calendar Checker"},
+ "minutes": {
+ "message": "$minutes$m",
+ "placeholders": {
+ "minutes": {
+ "content": "$1"
+ }
+ }
+ },
+ "hours": {
+ "message": "$hours$h",
+ "placeholders": {
+ "hours": {
+ "content": "$1"
+ }
+ }
+ },
+ "days": {
+ "message": "$days$d",
+ "placeholders": {
+ "days": {
+ "content": "$1"
+ }
+ }
+ },
+ "multiCalendarText": {"message": "Multi Calendar Support"},
+ "extensionName": {"message": "Google Calendar Checker"},
+ "status_saved": {"message": "Settings Saved."},
+ "status_saving": {"message": "Saving...."},
+ "multiCalendarToolTip": {"message": "Please check the box to enable multiple calendar support"},
+ "imageTooltip": {"message": "Google Calendar"}
+}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/images/calendar_logo.gif b/chrome/common/extensions/docs/examples/extensions/calendar/images/calendar_logo.gif
new file mode 100644
index 0000000..e082dc9
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/images/calendar_logo.gif
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-128.gif b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-128.gif
new file mode 100644
index 0000000..78d34bc
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-128.gif
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16.gif b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16.gif
new file mode 100644
index 0000000..054e628
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16.gif
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16_bw.gif b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16_bw.gif
new file mode 100644
index 0000000..c20d7b8
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/images/icon-16_bw.gif
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/javascript/background.js b/chrome/common/extensions/docs/examples/extensions/calendar/javascript/background.js
new file mode 100644
index 0000000..6abedb0
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/javascript/background.js
@@ -0,0 +1,728 @@
+/**
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+ */
+
+/**
+ * PHASES
+ * 1) Load next event from server refresh every 30 minutes or every time
+ * you go to calendar or every time you logout drop in a data object.
+ * 2) Display on screen periodically once per minute or on demand.
+ */
+
+// Message shown in badge title when no title is given to an event.
+var MSG_NO_TITLE = chrome.i18n.getMessage('noTitle');
+
+// Time between server polls = 30 minutes.
+var POLL_INTERVAL = 30 * 60 * 1000;
+
+// Redraw interval is 1 min.
+var DRAW_INTERVAL = 60 * 1000;
+
+// The time when we last polled.
+var lastPollTime_ = 0;
+
+// Object for BadgeAnimation
+var badgeAnimation_;
+
+//Object for CanvasAnimation
+var canvasAnimation_;
+
+// Object containing the event.
+var nextEvent_ = null;
+
+// Storing events.
+var eventList = [];
+var nextEvents = [];
+
+// Storing calendars.
+var calendars = [];
+
+var pollUnderProgress = false;
+var defaultAuthor = '';
+var isMultiCalendar = false;
+
+//URL for getting feed of individual calendar support.
+var SINGLE_CALENDAR_SUPPORT_URL = 'https://www.google.com/calendar/feeds' +
+ '/default/private/embed?toolbar=true&max-results=10';
+
+//URL for getting feed of multiple calendar support.
+var MULTIPLE_CALENDAR_SUPPORT_URL = 'https://www.google.com/calendar/feeds' +
+ '/default/allcalendars/full';
+
+//URL for opening Google Calendar in new tab.
+var GOOGLE_CALENDAR_URL = 'http://www.google.com/calendar/render';
+
+//URL for declining invitation of the event.
+var DECLINED_URL = 'http://schemas.google.com/g/2005#event.declined';
+
+//This is used to poll only once per second at most, and delay that if
+//we keep hitting pages that would otherwise force a load.
+var pendingLoadId_ = null;
+
+/**
+ * A "loading" animation displayed while we wait for the first response from
+ * Calendar. This animates the badge text with a dot that cycles from left to
+ * right.
+ * @constructor
+ */
+function BadgeAnimation() {
+ this.timerId_ = 0;
+ this.maxCount_ = 8; // Total number of states in animation
+ this.current_ = 0; // Current state
+ this.maxDot_ = 4; // Max number of dots in animation
+};
+
+/**
+ * Paints the badge text area while loading the data.
+ */
+BadgeAnimation.prototype.paintFrame = function() {
+ var text = '';
+ for (var i = 0; i < this.maxDot_; i++) {
+ text += (i == this.current_) ? '.' : ' ';
+ }
+
+ chrome.browserAction.setBadgeText({text: text});
+ this.current_++;
+ if (this.current_ == this.maxCount_) {
+ this.current_ = 0;
+ }
+};
+
+/**
+ * Starts the animation process.
+ */
+BadgeAnimation.prototype.start = function() {
+ if (this.timerId_) {
+ return;
+ }
+
+ var self = this;
+ this.timerId_ = window.setInterval(function() {
+ self.paintFrame();
+ }, 100);
+};
+
+/**
+ * Stops the animation process.
+ */
+BadgeAnimation.prototype.stop = function() {
+ if (!this.timerId_) {
+ return;
+ }
+
+ window.clearInterval(this.timerId_);
+ this.timerId_ = 0;
+};
+
+/**
+ * Animates the canvas after loading the data from all the calendars. It
+ * rotates the icon and defines the badge text and title.
+ * @constructor
+ */
+function CanvasAnimation() {
+ this.animationFrames_ = 36; // The number of animation frames
+ this.animationSpeed_ = 10; // Time between each frame(in ms).
+ this.canvas_ = $('canvas'); // The canvas width + height.
+ this.canvasContext_ = this.canvas_.getContext('2d'); // Canvas context.
+ this.loggedInImage_ = $('logged_in');
+ this.rotation_ = 0; //Keeps count of rotation angle of extension icon.
+ this.w = this.canvas_.width; // Setting canvas width.
+ this.h = this.canvas_.height; // Setting canvas height.
+ this.RED = [208, 0, 24, 255]; //Badge color of extension icon in RGB format.
+ this.BLUE = [0, 24, 208, 255];
+ this.currentBadge_ = null; // The text in the current badge.
+};
+
+/**
+ * Flips the icon around and draws it.
+ */
+CanvasAnimation.prototype.animate = function() {
+ this.rotation_ += (1 / this.animationFrames_);
+ this.drawIconAtRotation();
+ var self = this;
+ if (this.rotation_ <= 1) {
+ setTimeout(function() {
+ self.animate();
+ }, self.animationSpeed_);
+ } else {
+ this.drawFinal();
+ }
+};
+
+/**
+ * Renders the icon.
+ */
+CanvasAnimation.prototype.drawIconAtRotation = function() {
+ this.canvasContext_.save();
+ this.canvasContext_.clearRect(0, 0, this.w, this.h);
+ this.canvasContext_.translate(Math.ceil(this.w / 2), Math.ceil(this.h / 2));
+ this.canvasContext_.rotate(2 * Math.PI * this.getSector(this.rotation_));
+ this.canvasContext_.drawImage(this.loggedInImage_, -Math.ceil(this.w / 2),
+ -Math.ceil(this.h / 2));
+ this.canvasContext_.restore();
+ chrome.browserAction.setIcon(
+ {imageData: this.canvasContext_.getImageData(0, 0, this.w, this.h)});
+};
+
+/**
+ * Calculates the sector which has to be traversed in a single call of animate
+ * function(360/animationFrames_ = 360/36 = 10 radians).
+ * @param {integer} sector angle to be rotated(in radians).
+ * @return {integer} value in radian of the sector which it has to cover.
+ */
+CanvasAnimation.prototype.getSector = function(sector) {
+ return (1 - Math.sin(Math.PI / 2 + sector * Math.PI)) / 2;
+};
+
+/**
+ * Draws the event icon and determines the badge title and icon title.
+ */
+CanvasAnimation.prototype.drawFinal = function() {
+ badgeAnimation_.stop();
+
+ if (!nextEvent_) {
+ this.showLoggedOut();
+ } else {
+ this.drawIconAtRotation();
+ this.rotation_ = 0;
+
+ var ms = nextEvent_.startTime.getTime() - getCurrentTime();
+ var nextEventMin = ms / (1000 * 60);
+ var bgColor = (nextEventMin < 60) ? this.RED : this.BLUE;
+
+ chrome.browserAction.setBadgeBackgroundColor({color: bgColor});
+ currentBadge_ = this.getBadgeText(nextEvent_);
+ chrome.browserAction.setBadgeText({text: currentBadge_});
+
+ if (nextEvents.length > 0) {
+ var text = '';
+ for (var i = 0, event; event = nextEvents[i]; i++) {
+ text += event.title;
+ if (event.author || event.location) {
+ text += '\n';
+ }
+ if (event.location) {
+ text += event.location + ' ';
+ }
+ if (event.author) {
+ text += event.author;
+ }
+ if (i < (nextEvents.length - 1)) {
+ text += '\n----------\n';
+ }
+ }
+ text = filterSpecialChar(text);
+ chrome.browserAction.setTitle({'title' : text});
+ }
+ }
+ pollUnderProgress = false;
+
+ chrome.extension.sendRequest({
+ message: 'enableSave'
+ }, function() {
+ });
+
+ return;
+};
+
+/**
+ * Shows the user logged out.
+ */
+CanvasAnimation.prototype.showLoggedOut = function() {
+ currentBadge_ = '?';
+ chrome.browserAction.setIcon({path: '../images/icon-16_bw.gif'});
+ chrome.browserAction.setBadgeBackgroundColor({color: [190, 190, 190, 230]});
+ chrome.browserAction.setBadgeText({text: '?'});
+ chrome.browserAction.setTitle({ 'title' : ''});
+};
+
+/**
+ * Gets the badge text.
+ * @param {Object} nextEvent_ next event in the calendar.
+ * @return {String} text Badge text to be shown in extension icon.
+ */
+CanvasAnimation.prototype.getBadgeText = function(nextEvent_) {
+ if (!nextEvent_) {
+ return '';
+ }
+
+ var ms = nextEvent_.startTime.getTime() - getCurrentTime();
+ var nextEventMin = Math.ceil(ms / (1000 * 60));
+
+ var text = '';
+ if (nextEventMin < 60) {
+ text = chrome.i18n.getMessage('minutes', nextEventMin.toString());
+ } else if (nextEventMin < 1440) {
+ text = chrome.i18n.getMessage('hours',
+ Math.round(nextEventMin / 60).toString());
+ } else if (nextEventMin < (1440 * 10)) {
+ text = chrome.i18n.getMessage('days',
+ Math.round(nextEventMin / 60 / 24).toString());
+ }
+ return text;
+};
+
+/**
+ * Provides all the calendar related utils.
+ */
+CalendarManager = {};
+
+/**
+ * Extracts event from the each entry of the calendar.
+ * @param {Object} elem The XML node to extract the event from.
+ * @return {Object} out An object containing the event properties.
+ */
+CalendarManager.extractEvent = function(elem) {
+ var out = {};
+
+ for (var node = elem.firstChild; node != null; node = node.nextSibling) {
+ if (node.nodeName == 'title') {
+ out.title = node.firstChild ? node.firstChild.nodeValue : MSG_NO_TITLE;
+ } else if (node.nodeName == 'link' &&
+ node.getAttribute('rel') == 'alternate') {
+ out.url = node.getAttribute('href');
+ } else if (node.nodeName == 'gd:where') {
+ out.location = node.getAttribute('valueString');
+ } else if (node.nodeName == 'gd:who') {
+ if (node.firstChild) {
+ out.attendeeStatus = node.firstChild.getAttribute('value');
+ }
+ } else if (node.nodeName == 'gd:eventStatus') {
+ out.status = node.getAttribute('value');
+ } else if (node.nodeName == 'gd:when') {
+ var startTimeStr = node.getAttribute('startTime');
+ var endTimeStr = node.getAttribute('endTime');
+
+ startTime = rfc3339StringToDate(startTimeStr);
+ endTime = rfc3339StringToDate(endTimeStr);
+
+ if (startTime == null || endTime == null) {
+ continue;
+ }
+
+ out.isAllDay = (startTimeStr.length <= 11);
+ out.startTime = startTime;
+ out.endTime = endTime;
+ }
+ }
+ return out;
+};
+
+/**
+ * Polls the server to get the feed of the user.
+ */
+CalendarManager.pollServer = function() {
+ if (! pollUnderProgress) {
+ eventList = [];
+ pollUnderProgress = true;
+ pendingLoadId_ = null;
+ calendars = [];
+ lastPollTime_ = getCurrentTime();
+ var url;
+ var xhr = new XMLHttpRequest();
+ try {
+ xhr.onreadystatechange = CalendarManager.genResponseChangeFunc(xhr);
+ xhr.onerror = function(error) {
+ console.log('error: ' + error);
+ nextEvent_ = null;
+ canvasAnimation_.drawFinal();
+ };
+ if (isMultiCalendar) {
+ url = MULTIPLE_CALENDAR_SUPPORT_URL;
+ } else {
+ url = SINGLE_CALENDAR_SUPPORT_URL;
+ }
+
+ xhr.open('GET', url);
+ xhr.send(null);
+ } catch (e) {
+ console.log('ex: ' + e);
+ nextEvent_ = null;
+ canvasAnimation_.drawFinal();
+ }
+ }
+};
+
+/**
+ * Gathers the list of all calendars of a specific user for multiple calendar
+ * support and event entries in single calendar.
+ * @param {xmlHttpRequest} xhr xmlHttpRequest object containing server response.
+ * @return {Object} anonymous function which returns to onReadyStateChange.
+ */
+CalendarManager.genResponseChangeFunc = function(xhr) {
+ return function() {
+ if (xhr.readyState != 4) {
+ return;
+ }
+ if (!xhr.responseXML) {
+ console.log('No responseXML');
+ nextEvent_ = null;
+ canvasAnimation_.drawFinal();
+ return;
+ }
+ if (isMultiCalendar) {
+ var entry_ = xhr.responseXML.getElementsByTagName('entry');
+ if (entry_ && entry_.length > 0) {
+ calendars = [];
+ for (var i = 0, entry; entry = entry_[i]; ++i) {
+ if (!i) {
+ defaultAuthor = entry.querySelector('title').textContent;
+ }
+ // Include only those calendars which are not hidden and selected
+ var isHidden = entry.querySelector('hidden');
+ var isSelected = entry.querySelector('selected');
+ if (isHidden && isHidden.getAttribute('value') == 'false') {
+ if (isSelected && isSelected.getAttribute('value') == 'true') {
+ var calendar_content = entry.querySelector('content');
+ var cal_src = calendar_content.getAttribute('src');
+ cal_src += '?toolbar=true&max-results=10';
+ calendars.push(cal_src);
+ }
+ }
+ }
+ CalendarManager.getCalendarFeed(0);
+ return;
+ }
+ } else {
+ calendars = [];
+ calendars.push(SINGLE_CALENDAR_SUPPORT_URL);
+ CalendarManager.parseCalendarEntry(xhr.responseXML, 0);
+ return;
+ }
+
+ console.error('Error: feed retrieved, but no event found');
+ nextEvent_ = null;
+ canvasAnimation_.drawFinal();
+ };
+};
+
+/**
+ * Retrieves feed for a calendar
+ * @param {integer} calendarId Id of the calendar in array of calendars.
+ */
+CalendarManager.getCalendarFeed = function(calendarId) {
+ var xmlhttp = new XMLHttpRequest();
+ try {
+ xmlhttp.onreadystatechange = CalendarManager.onCalendarResponse(xmlhttp,
+ calendarId);
+ xmlhttp.onerror = function(error) {
+ console.log('error: ' + error);
+ nextEvent_ = null;
+ canvasAnimation_.drawFinal();
+ };
+
+ xmlhttp.open('GET', calendars[calendarId]);
+ xmlhttp.send(null);
+ }
+ catch (e) {
+ console.log('ex: ' + e);
+ nextEvent_ = null;
+ canvasAnimation_.drawFinal();
+ }
+};
+
+/**
+ * Gets the event entries of every calendar subscribed in default user calendar.
+ * @param {xmlHttpRequest} xmlhttp xmlHttpRequest containing server response
+ * for the feed of a specific calendar.
+ * @param {integer} calendarId Variable for storing the no of calendars
+ * processed.
+ * @return {Object} anonymous function which returns to onReadyStateChange.
+ */
+CalendarManager.onCalendarResponse = function(xmlhttp, calendarId) {
+ return function() {
+ if (xmlhttp.readyState != 4) {
+ return;
+ }
+ if (!xmlhttp.responseXML) {
+ console.log('No responseXML');
+ nextEvent_ = null;
+ canvasAnimation_.drawFinal();
+ return;
+ }
+ CalendarManager.parseCalendarEntry(xmlhttp.responseXML, calendarId);
+ };
+};
+
+/**
+ * Parses events from calendar response XML
+ * @param {string} responseXML Response XML for calendar.
+ * @param {integer} calendarId Id of the calendar in array of calendars.
+ */
+CalendarManager.parseCalendarEntry = function(responseXML, calendarId) {
+ var entry_ = responseXML.getElementsByTagName('entry');
+ var author = responseXML.querySelector('author name').textContent;
+
+ if (entry_ && entry_.length > 0) {
+ for (var i = 0, entry; entry = entry_[i]; ++i) {
+ var event_ = CalendarManager.extractEvent(entry);
+
+ // Get the time from then to now
+ if (event_.startTime) {
+ var t = event_.startTime.getTime() - getCurrentTime();
+ if (t >= 0 && (event_.attendeeStatus != DECLINED_URL)) {
+ if (isMultiCalendar) {
+ event_.author = author;
+ }
+ eventList.push(event_);
+ }
+ }
+ }
+ }
+
+ calendarId++;
+ //get the next calendar
+ if (calendarId < calendars.length) {
+ CalendarManager.getCalendarFeed(calendarId);
+ } else {
+ CalendarManager.populateLatestEvent(eventList);
+ }
+};
+
+/**
+ * Fills the event list with the events acquired from the calendar(s).
+ * Parses entire event list and prepares an array of upcoming events.
+ * @param {Array} eventList List of all events.
+ */
+CalendarManager.populateLatestEvent = function(eventList) {
+ nextEvents = [];
+ if (isMultiCalendar) {
+ eventList.sort(sortByDate);
+ }
+
+ //populating next events array.
+ if (eventList.length > 0) {
+ nextEvent_ = eventList[0];
+ nextEvent_.startTime.setSeconds(0, 0);
+ nextEvents.push(nextEvent_);
+ var startTime = nextEvent_.startTime;
+ for (var i = 1, event; event = eventList[i]; i++) {
+ var time = event.startTime.setSeconds(0, 0);
+ if (time == startTime) {
+ nextEvents.push(event);
+ } else {
+ break;
+ }
+ }
+ if (nextEvents.length > 1) {
+ nextEvents.sort(sortByAuthor);
+ }
+ canvasAnimation_.animate();
+ return;
+ } else {
+ console.error('Error: feed retrieved, but no event found');
+ nextEvent_ = null;
+ canvasAnimation_.drawFinal();
+ }
+};
+
+var DATE_TIME_REGEX =
+ /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)\.\d+(\+|-)(\d\d):(\d\d)$/;
+var DATE_TIME_REGEX_Z = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)\.\d+Z$/;
+var DATE_REGEX = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
+
+/**
+* Convert the incoming date into a javascript date.
+* @param {String} rfc3339 The rfc date in string format as following
+* 2006-04-28T09:00:00.000-07:00
+* 2006-04-28T09:00:00.000Z
+* 2006-04-19.
+* @return {Date} The javascript date format of the incoming date.
+*/
+function rfc3339StringToDate(rfc3339) {
+ var parts = DATE_TIME_REGEX.exec(rfc3339);
+
+ // Try out the Z version
+ if (!parts) {
+ parts = DATE_TIME_REGEX_Z.exec(rfc3339);
+ }
+
+ if (parts && parts.length > 0) {
+ var d = new Date();
+ d.setUTCFullYear(parts[1], parseInt(parts[2], 10) - 1, parts[3]);
+ d.setUTCHours(parts[4]);
+ d.setUTCMinutes(parts[5]);
+ d.setUTCSeconds(parts[6]);
+
+ var tzOffsetFeedMin = 0;
+ if (parts.length > 7) {
+ tzOffsetFeedMin = parseInt(parts[8], 10) * 60 + parseInt(parts[9], 10);
+ if (parts[7] != '-') { // This is supposed to be backwards.
+ tzOffsetFeedMin = -tzOffsetFeedMin;
+ }
+ }
+ return new Date(d.getTime() + tzOffsetFeedMin * 60 * 1000);
+ }
+
+ parts = DATE_REGEX.exec(rfc3339);
+ if (parts && parts.length > 0) {
+ return new Date(parts[1], parseInt(parts[2], 10) - 1, parts[3]);
+ }
+ return null;
+};
+
+/**
+ * Sorts all the events by date and time.
+ * @param {object} event_1 Event object.
+ * @param {object} event_2 Event object.
+ * @return {integer} timeDiff Difference in time.
+ */
+function sortByDate(event_1, event_2) {
+ return (event_1.startTime.getTime() - event_2.startTime.getTime());
+};
+
+/**
+ * Sorts all the events by author name.
+ * @param {object} event_1 Event object.
+ * @param {object} event_2 Event object.
+ * @return {integer} nameDiff Difference in default author and others.
+ */
+function sortByAuthor(event_1, event_2) {
+ var nameDiff;
+ if (event_2.author == defaultAuthor) {
+ nameDiff = 1;
+ } else {
+ return 0;
+ }
+ return nameDiff;
+};
+
+/**
+ * Fires once per minute to redraw extension icon.
+ */
+function redraw() {
+ // If the next event just passed, re-poll.
+ if (nextEvent_) {
+ var t = nextEvent_.startTime.getTime() - getCurrentTime();
+ if (t <= 0) {
+ CalendarManager.pollServer();
+ return;
+ }
+ }
+ canvasAnimation_.animate();
+
+ // if ((we are logged in) && (30 minutes have passed)) re-poll
+ if (nextEvent_ && (getCurrentTime() - lastPollTime_ >= POLL_INTERVAL)) {
+ CalendarManager.pollServer();
+ }
+};
+
+/**
+ * Returns the current time in milliseconds.
+ * @return {Number} Current time in milliseconds.
+ */
+function getCurrentTime() {
+ return (new Date()).getTime();
+};
+
+/**
+* Replaces ASCII characters from the title.
+* @param {String} data String containing ASCII code for special characters.
+* @return {String} data ASCII characters replaced with actual characters.
+*/
+function filterSpecialChar(data) {
+ if (data) {
+ data = data.replace(/&lt;/g, '<');
+ data = data.replace(/&gt;/g, '>');
+ data = data.replace(/&amp;/g, '&');
+ data = data.replace(/%7B/g, '{');
+ data = data.replace(/%7D/g, '}');
+ data = data.replace(/&quot;/g, '"');
+ data = data.replace(/&#39;/g, '\'');
+ }
+ return data;
+};
+
+/**
+ * Called from options.js page on saving the settings
+ */
+function onSettingsChange() {
+ isMultiCalendar = JSON.parse(localStorage.multiCalendar);
+ badgeAnimation_.start();
+ CalendarManager.pollServer();
+};
+
+/**
+ * Function runs on updating a tab having url of google applications.
+ * @param {integer} tabId Id of the tab which is updated.
+ * @param {String} changeInfo Gives the information of change in url.
+ * @param {String} tab Gives the url of the tab updated.
+ */
+function onTabUpdated(tabId, changeInfo, tab) {
+ var url = tab.url;
+ if (!url) {
+ return;
+ }
+
+ if ((url.indexOf('www.google.com/calendar/') != -1) ||
+ ((url.indexOf('www.google.com/a/') != -1) &&
+ (url.lastIndexOf('/acs') == url.length - 4)) ||
+ (url.indexOf('www.google.com/accounts/') != -1)) {
+
+ // The login screen isn't helpful
+ if (url.indexOf('https://www.google.com/accounts/ServiceLogin?') == 0) {
+ return;
+ }
+
+ if (pendingLoadId_) {
+ clearTimeout(pendingLoadId_);
+ pendingLoadId_ = null;
+ }
+
+ // try to poll in 2 second [which makes the redirects settle down]
+ pendingLoadId_ = setTimeout(CalendarManager.pollServer, 2000);
+ }
+};
+
+/**
+ * Called when the user clicks on extension icon and opens calendar page.
+ */
+function onClickAction() {
+ chrome.tabs.getAllInWindow(null, function(tabs) {
+ for (var i = 0, tab; tab = tabs[i]; i++) {
+ if (tab.url && isCalendarUrl(tab.url)) {
+ chrome.tabs.update(tab.id, {selected: true});
+ CalendarManager.pollServer();
+ return;
+ }
+ }
+ chrome.tabs.create({url: GOOGLE_CALENDAR_URL});
+ CalendarManager.pollServer();
+ });
+};
+
+/**
+ * Checks whether an instance of Google calendar is already open.
+ * @param {String} url Url of the tab visited.
+ * @return {boolean} true if the url is a Google calendar relative url, false
+ * otherwise.
+ */
+function isCalendarUrl(url) {
+ return url.indexOf('www.google.com/calendar') != -1 ? true : false;
+};
+
+/**
+ * Initializes everything.
+ */
+function init() {
+ badgeAnimation_ = new BadgeAnimation();
+ canvasAnimation_ = new CanvasAnimation();
+
+ isMultiCalendar = JSON.parse(localStorage.multiCalendar || false);
+
+ chrome.browserAction.setIcon({path: '../images/icon-16.gif'});
+ badgeAnimation_.start();
+ CalendarManager.pollServer();
+ window.setInterval(redraw, DRAW_INTERVAL);
+
+ chrome.tabs.onUpdated.addListener(onTabUpdated);
+
+ chrome.browserAction.onClicked.addListener(function(tab) {
+ onClickAction();
+ });
+};
+
+//Adding listener when body is loaded to call init function.
+window.addEventListener('load', init, false);
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/javascript/options.js b/chrome/common/extensions/docs/examples/extensions/calendar/javascript/options.js
new file mode 100644
index 0000000..1a6ce65
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/javascript/options.js
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+ */
+
+//Contains true if multiple calendar option is checked, false otherwise.
+var isMultiCalendar;
+
+//adding listener when body is loaded to call init function.
+window.addEventListener('load', init, false);
+
+/**
+ * Sets the value of multiple calendar checkbox based on value from
+ * local storage.
+ */
+ function init() {
+ isMultiCalendar = JSON.parse(localStorage.multiCalendar || false);
+ $('multiCalendar').checked = isMultiCalendar;
+ $('multiCalendarText').innerHTML =
+ chrome.i18n.getMessage('multiCalendarText');
+ $('optionsTitle').innerHTML = chrome.i18n.getMessage('optionsTitle');
+ $('imageTooltip').title = chrome.i18n.getMessage('imageTooltip');
+ $('imageTooltip').alt = chrome.i18n.getMessage('imageTooltip');
+ $('multiCalendarText').title = chrome.i18n.getMessage('multiCalendarToolTip');
+ $('multiCalendar').title = chrome.i18n.getMessage('multiCalendarToolTip');
+ $('extensionName').innerHTML = chrome.i18n.getMessage('extensionName');
+ if (chrome.i18n.getMessage('direction') == 'rtl') {
+ document.querySelector('body').style.direction = 'rtl';
+ }
+};
+
+/**
+ * Saves the value of the checkbox into local storage.
+ */
+function save() {
+ var multiCalendarId = $('multiCalendar');
+ localStorage.multiCalendar = multiCalendarId.checked;
+ if (multiCalendarId) {
+ multiCalendar.disabled = true;
+ }
+ $('status').innerHTML = chrome.i18n.getMessage('status_saving');
+ $('status').style.display = 'block';
+ chrome.extension.getBackgroundPage().onSettingsChange();
+};
+
+/**
+ * Fired when a request is sent from either an extension process or a content
+ * script. Add Listener to enable the save checkbox button on server response.
+ * @param {String} request Request sent by the calling script.
+ * @param {Object} sender Information about the script that sent a message or
+ * request.
+ * @param {Function} sendResponse Function to call when there is a response.
+ * The argument should be any JSON-ifiable object, or undefined if there
+ * is no response.
+ */
+chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
+ if (!request.message)
+ return;
+ switch (request.message) {
+ case 'enableSave':
+ if ($('multiCalendar')) {
+ if ($('multiCalendar').disabled) {
+ $('status').innerHTML = chrome.i18n.getMessage('status_saved');
+ $('status').style.display = 'block';
+ setTimeout("$('status').style.display = 'none'", 1500);
+ }
+ $('multiCalendar').disabled = false;
+ }
+ sendResponse();
+ break;
+ }
+});
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/javascript/util.js b/chrome/common/extensions/docs/examples/extensions/calendar/javascript/util.js
new file mode 100644
index 0000000..1ad5ac6
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/javascript/util.js
@@ -0,0 +1,14 @@
+/**
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+ */
+
+/**
+ * Alias for document.getElementById.
+ * @param {string} id The id of the element.
+ * @return {HTMLElement} The html element for the given element id.
+ */
+function $(id) {
+ return document.getElementById(id);
+};
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/manifest.json b/chrome/common/extensions/docs/examples/extensions/calendar/manifest.json
new file mode 100644
index 0000000..e5eb37b
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/manifest.json
@@ -0,0 +1,18 @@
+{
+ "name": "__MSG_name__",
+ "description": "__MSG_description__",
+ "default_locale":"en",
+ "options_page": "views/options.html",
+ "version": "1.1.0",
+ "background_page": "views/background.html",
+ "permissions": [
+ "tabs", "http://*.google.com/", "https://*.google.com/"
+ ],
+ "browser_action": {
+ "default_title": "__MSG_title__"
+ },
+ "icons": {
+ "128": "images/icon-128.gif",
+ "16":"images/icon-16.gif"
+ }
+}
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/views/background.html b/chrome/common/extensions/docs/examples/extensions/calendar/views/background.html
new file mode 100644
index 0000000..b90a41b
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/views/background.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<!--
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+-->
+<html>
+ <head>
+ <script src="../javascript/util.js"></script>
+ <script src="../javascript/background.js"></script>
+ </head>
+ <body>
+ <img id="logged_in" src="../images/icon-16.gif">
+ <canvas id="canvas" width="19" height="19"></canvas>
+ </body>
+</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/calendar/views/options.html b/chrome/common/extensions/docs/examples/extensions/calendar/views/options.html
new file mode 100644
index 0000000..1cc70c2
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/calendar/views/options.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<!--
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+-->
+<html>
+<head>
+ <title id=optionsTitle></title>
+ <script src="../javascript/options.js"></script>
+ <script src="../javascript/util.js"></script>
+ <style>
+ #content {
+ background-color: white;
+ border: 4px solid #B5C7DE;
+ border-radius: 12px;
+ margin: 40px auto 20px;
+ padding: 8px;
+ width: 600px;
+ }
+ .option_row {
+ clear: left;
+ padding: 2.5em 1em 0;
+ text-align:center
+ }
+ #status {
+ background-color: rgb(255, 241, 168);
+ display: none;
+ margin-left: 3px;
+ padding: 1px 2px;
+ text-align: center;
+ font-size: 15px;
+ color: #000;
+ }
+ #multiCalendarText {
+ font-size: 15px;
+ color: #000;
+ }
+ body {
+ background-color: "#ebeff9";
+ }
+ #logo {
+ font-size: 20px;
+ text-align: center;
+ }
+ #extensionName {
+ color: #444;
+ }
+ </style>
+
+</head>
+<body>
+ <div id="content">
+ <div id = "logo">
+ <img src="../images/icon-128.gif" width="48">&nbsp;&nbsp;&nbsp;
+ <img src="../images/calendar_logo.gif" id="imageTooltip" title="" alt="">
+ <br>
+ <label id="extensionName" ></label>
+ </div>
+
+ <div class="option_row">
+ <div>
+ <table cellpadding=1 width=100%>
+ <tr>
+ <td width="15%">
+ &nbsp;
+ </td>
+ <td width="5%">
+ <input type="checkbox" id="multiCalendar" name="multiCalendar" onclick="save()" title="">
+ </td>
+ <td width="40%" align="left">
+ <span id="multiCalendarText" title=""></span>
+ </td>
+ <td width="30%">
+ <label id="status"></label>
+ </td>
+ <td width="10%">
+ &nbsp;
+ </td>
+ </tr>
+ </table>
+ <br>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/chrome_search.zip b/chrome/common/extensions/docs/examples/extensions/chrome_search.zip
index b5be659..fc89e2f 100644
--- a/chrome/common/extensions/docs/examples/extensions/chrome_search.zip
+++ b/chrome/common/extensions/docs/examples/extensions/chrome_search.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/chrome_search/background.html b/chrome/common/extensions/docs/examples/extensions/chrome_search/background.html
index 5dd51b3..ca50d9b 100644
--- a/chrome/common/extensions/docs/examples/extensions/chrome_search/background.html
+++ b/chrome/common/extensions/docs/examples/extensions/chrome_search/background.html
@@ -1,7 +1,7 @@
<script>
var currentRequest = null;
-chrome.experimental.omnibox.onInputChanged.addListener(
+chrome.omnibox.onInputChanged.addListener(
function(text, suggest) {
if (text == '') {
return;
@@ -28,8 +28,7 @@ chrome.experimental.omnibox.onInputChanged.addListener(
description = description.replace(/<\/?.+?>/g, '');
description = file + ': ' + description;
descriptionStyles = [
- chrome.experimental.omnibox.styleUrl(0),
- chrome.experimental.omnibox.styleNone(file.length),
+ chrome.omnibox.styleUrl(0, file.length),
]
// Highlight all occurrences of the match text.
@@ -39,8 +38,7 @@ chrome.experimental.omnibox.onInputChanged.addListener(
if (index < 0) break;
if (index > file.length) {
descriptionStyles.push(
- chrome.experimental.omnibox.styleMatch(index),
- chrome.experimental.omnibox.styleNone(index + text.length)
+ chrome.omnibox.styleMatch(index, text.length)
);
}
}
@@ -92,7 +90,7 @@ function navigate(url) {
});
}
-chrome.experimental.omnibox.onInputEntered.addListener(
+chrome.omnibox.onInputEntered.addListener(
function(text) {
if (text.indexOf('@') > 0) {
var chunks = text.split('@');
diff --git a/chrome/common/extensions/docs/examples/extensions/chrome_search/manifest.json b/chrome/common/extensions/docs/examples/extensions/chrome_search/manifest.json
index 3eee569..3254391 100644
--- a/chrome/common/extensions/docs/examples/extensions/chrome_search/manifest.json
+++ b/chrome/common/extensions/docs/examples/extensions/chrome_search/manifest.json
@@ -1,9 +1,9 @@
-{
- "background_page": "background.html",
- "description": "Add support to the omnibox to search the Chromium source code.",
- "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRx0y4f/CuomPPeGxcVMo7yfYZ1apxD+9e3ItNtPRBi8WMmzG0xhjnqvm03LTfTljbzA1L93s31HkjS5Bd12qM8SSZxOOizsZveK1tdpX0QelikSUaz1wwIyjatoC/jJy7vuuk0j5kPeLkNAhYGJTqN3H/Pqt0lFF1VFX4+fCEvQIDAQAB",
- "name": "Chromium Search",
- "omnibox_keyword": "src",
- "permissions": [ "experimental", "tabs", "http://www.google.com/" ],
- "version": "4"
-}
+{
+ "background_page": "background.html",
+ "description": "Add support to the omnibox to search the Chromium source code.",
+ "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRx0y4f/CuomPPeGxcVMo7yfYZ1apxD+9e3ItNtPRBi8WMmzG0xhjnqvm03LTfTljbzA1L93s31HkjS5Bd12qM8SSZxOOizsZveK1tdpX0QelikSUaz1wwIyjatoC/jJy7vuuk0j5kPeLkNAhYGJTqN3H/Pqt0lFF1VFX4+fCEvQIDAQAB",
+ "name": "Chromium Search",
+ "omnibox": { "keyword" : "src" },
+ "permissions": [ "tabs", "http://www.google.com/" ],
+ "version": "4"
+}
diff --git a/chrome/common/extensions/docs/examples/extensions/email_this_page.zip b/chrome/common/extensions/docs/examples/extensions/email_this_page.zip
index 7f325d8..ab63c9b 100644
--- a/chrome/common/extensions/docs/examples/extensions/email_this_page.zip
+++ b/chrome/common/extensions/docs/examples/extensions/email_this_page.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/fx.zip b/chrome/common/extensions/docs/examples/extensions/fx.zip
index 1a3415f..027e286 100644
--- a/chrome/common/extensions/docs/examples/extensions/fx.zip
+++ b/chrome/common/extensions/docs/examples/extensions/fx.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gdocs.zip b/chrome/common/extensions/docs/examples/extensions/gdocs.zip
index 6019650..60b27a4 100644
--- a/chrome/common/extensions/docs/examples/extensions/gdocs.zip
+++ b/chrome/common/extensions/docs/examples/extensions/gdocs.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/gmail.zip b/chrome/common/extensions/docs/examples/extensions/gmail.zip
index 2d27d78..16ad002 100644
--- a/chrome/common/extensions/docs/examples/extensions/gmail.zip
+++ b/chrome/common/extensions/docs/examples/extensions/gmail.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/imageinfo.zip b/chrome/common/extensions/docs/examples/extensions/imageinfo.zip
index 3fb92d2..1fb7a3a 100644
--- a/chrome/common/extensions/docs/examples/extensions/imageinfo.zip
+++ b/chrome/common/extensions/docs/examples/extensions/imageinfo.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/mappy.zip b/chrome/common/extensions/docs/examples/extensions/mappy.zip
index f8b121b..79245b1 100644
--- a/chrome/common/extensions/docs/examples/extensions/mappy.zip
+++ b/chrome/common/extensions/docs/examples/extensions/mappy.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news.zip b/chrome/common/extensions/docs/examples/extensions/news.zip
index 6da19a6..7c8d358 100644
--- a/chrome/common/extensions/docs/examples/extensions/news.zip
+++ b/chrome/common/extensions/docs/examples/extensions/news.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/_locales/en/messages.json b/chrome/common/extensions/docs/examples/extensions/news/_locales/en/messages.json
new file mode 100644
index 0000000..97e07c1
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/_locales/en/messages.json
@@ -0,0 +1,102 @@
+{
+ "extName": {
+ "message": "News Reader (by Google)"
+ },
+ "extDesc": {
+ "message": "Displays the latest stories from Google News in a popup."
+ },
+ "ext_default_title": {
+ "message": "Google News"
+ },
+
+ "1": {
+ "message": "Top Stories"
+ },
+ "n": {
+ "message": "Nation"
+ },
+ "w": {
+ "message": "World"
+ },
+ "b": {
+ "message": "Business"
+ },
+ "t": {
+ "message": "Science/Technology"
+ },
+ "e": {
+ "message": "Entertainment"
+ },
+ "s": {
+ "message": "Sports"
+ },
+ "m": {
+ "message": "Health"
+ },
+ "po": {
+ "message": "Most Popular"
+ },
+
+ "options": {
+ "message": "Options"
+ },
+ "more_stories": {
+ "message": "More stories"
+ },
+
+ "direction": {
+ "message": "ltr"
+ },
+
+ "country": {
+ "message": "Country:"
+ },
+ "topic": {
+ "message": "Topics:"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveStatus": {
+ "message": "Options saved"
+ },
+ "storyCount": {
+ "message": "Number of stories:"
+ },
+ "newsOption": {
+ "message": "Google News Options"
+ },
+ "customText": {
+ "message": "Custom Topics:"
+ },
+ "maximumTopics": {
+ "message": "(Maximum $count$)",
+ "placeholders": {
+ "count": {
+ "content": "$1"
+ }
+ }
+ },
+ "submitButton": {
+ "message": "Add"
+ },
+ "deleteTitle": {
+ "message": "Delete"
+ },
+ "invalidChars": {
+ "message": "Invalid character(s)"
+ },
+ "noTopic": {
+ "message": "At least one Topic must be selected"
+ },
+
+ "fetchError": {
+ "message": "Error: Failed to fetch news stories."
+ },
+ "wrongTopic": {
+ "message": "Error: Not a valid feed."
+ },
+ "noStory": {
+ "message": "No story right now"
+ }
+}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/css/feed.css b/chrome/common/extensions/docs/examples/extensions/news/css/feed.css
new file mode 100644
index 0000000..49edf8f
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/css/feed.css
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+ *
+ * Sets style of different elements in pop-up page.
+ *
+ * Author: navneetg@google.com (Navneet Goel).
+ */
+
+body {
+ font-family: arial, sans-serif;
+ font-size: 12px;
+ min-width: 500px;
+ overflow: visible;
+}
+a {
+ color: #0000CC;
+ cursor: pointer;
+ text-decoration: underline;
+}
+#noStories {
+ background-color: rgb(255, 238, 136);
+ font-size: 13px;
+ font-weight: bold;
+ margin-left: 140px;
+ margin-right: 140px;
+ text-align: center;
+}
+.open_box {
+ background-image: url(/images/sprite_arrows.gif);
+ background-position: 0px -24px;
+ clear: left;
+ cursor: pointer;
+ display: block;
+ height: 12px;
+ margin-top: 2px;
+ overflow: hidden;
+ width: 12px;
+ float: left;
+}
+.opened .open_box {
+ background-position: -12px -24px;
+}
+.item {
+ padding: 2px 0;
+}
+.item_title {
+ cursor: pointer;
+ display: block;
+ min-width: 300px;
+ padding: 0 0 0 17px;
+}
+.item_desc {
+ border: none;
+ display: block;
+ height: 0;
+ margin: 0;
+ min-width: 500px;
+ padding: 0;
+ -webkit-transition: height 0.2s ease-out;
+}
+#title {
+ display: block;
+}
+.error {
+ background-color: rgb(255, 238, 136);
+ font-size: 13px;
+ font-weight: bold;
+ margin-left: 125px;
+ margin-right: 125px;
+ text-align: center;
+ white-space: nowrap;
+}
+.more {
+ color: #88C;
+ display: block;
+ margin-left: 385px;
+ padding-right: 10px;
+ padding-top: 5px;
+ text-align: right;
+}
+.topicsLTR {
+ direction: ltr;
+ font-size: 13px;
+ padding-left: 5px;
+}
+.topicsRTL {
+ direction: rtl;
+ font-size: 13px;
+ padding-right: 5px;
+}
+body.rtl #feed {
+ direction: rtl;
+}
+body.rtl .open_box {
+ float: right;
+}
+body.rtl .item_title {
+ padding: 0 17px 0 0;
+}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/css/options.css b/chrome/common/extensions/docs/examples/extensions/news/css/options.css
new file mode 100644
index 0000000..91aff7e
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/css/options.css
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+ *
+ * Sets style of different elements in options page.
+ *
+ * Author: navneetg@google.com (Navneet Goel).
+ */
+
+@CHARSET "UTF-8";
+body {
+ background-color: rgb(235, 239, 249);
+ font-family: arial , sans-serif;
+ font-size: 13px;
+}
+.suppr {
+ background-image: url(/images/delete-icon.png);
+ background-repeat: no-repeat;
+ cursor: pointer;
+ display: inline;
+ float: left;
+ height: 17px;
+ margin-top: 3px;
+ overflow: hidden;
+ width: 14px;
+}
+.checkBoxTopic {
+ float: left;
+ padding-left: 2px;
+ padding-top: 1px;
+}
+.checkBox {
+ float: left;
+}
+.boxAndTopic {
+ overflow: auto;
+ padding-bottom: 5px;
+}
+#invalid_status, #save_status {
+ background-color: rgb(255, 241, 168);
+ font-weight: bold;
+ margin-left: 10px;
+ opacity: 0;
+ padding-bottom: 3px;
+ padding-left: 7px;
+ padding-right: 7px;
+ padding-top: 3px;
+}
+#all_content {
+ background-color: white;
+ border-bottom-left-radius: 12px 12px;
+ border-bottom-right-radius: 12px 12px;
+ border-color: #B5C7DE;
+ border-style: solid;
+ border-top-left-radius: 12px 12px;
+ border-top-right-radius: 12px 12px;
+ border-width: 4px;
+ margin: 40px auto 20px;
+ padding: 12px;
+ width: 600px;
+}
+.col2 {
+ padding-left: 20px;
+}
+body.rtl .col1, body.rtl .col2 {
+ text-align: right;
+}
+body.rtl {
+ direction: rtl;
+}
+body.rtl .col2 {
+ padding-right: 20px;
+}
+body.rtl .checkBox, body.rtl .checkBoxTopic {
+ float: right;
+}
+body.rtl table.contentTable {
+ margin:0 55px 0 0;
+}
+body.rtl #save_div{
+ margin: 0 220px 0 0;
+}
+body.rtl #countryList{
+ margin:0 5px 0 0;
+}
+.col1 {
+ padding-top: 3px;
+ width: 115px;
+}
+.all_rows {
+ height: 35px;
+ vertical-align: top;
+}
+body.rtl .cusTopicsClass {
+ float: right;
+}
+.cusTopicsClass {
+ float: left;
+ width: 225px;
+}
+#save_div {
+ margin-left: 220px;
+}
+#countryList {
+ padding-left: 5px;
+}
+#logo {
+ font-size: 15px;
+ font-weight: bold;
+ text-align: center;
+}
+.noborder {
+ border: 0;
+ font-family: arial, sans-serif;
+ height: 15px;
+ outline: none;
+ overflow: hidden;
+ resize: none;
+ width:205px;
+}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/feed.html b/chrome/common/extensions/docs/examples/extensions/news/feed.html
deleted file mode 100644
index 6592a87..0000000
--- a/chrome/common/extensions/docs/examples/extensions/news/feed.html
+++ /dev/null
@@ -1,310 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<style>
-body {
- font-family: helvetica, arial, sans-serif;
- font-size: 12px;
- overflow: hidden;
-}
-
-a {
- color:#0000CC;
- text-decoration: underline;
- cursor: pointer;
-}
-
-.open_box {
- display: block;
- overflow: hidden;
- margin-right: 4px;
- margin-top: 2px;
- height: 12px;
- width: 12px;
- float: left;
- clear: left;
- background-image: url(sprite_arrows.gif);
- background-position: 0px -24px;
- cursor: pointer;
-}
-
-.opened .open_box {
- background-position:-12px -24px;
-}
-
-.item {
- padding: 2px 0px;
-}
-
-.item_title {
- display: block;
- min-width: 300px;
- padding-left: 15px;
- cursor: pointer;
-}
-
-.item_desc {
- min-width: 500px;
- height: 0px;
- display: block;
- border: none;
- padding: 0px;
- margin: 0px;
- -webkit-transition: height 0.2s ease-out;
-}
-
-#title {
- display: block;
- margin-left: auto;
-}
-
-.error {
- white-space: nowrap;
- color: red;
-}
-
-.more {
- display: block;
- text-align: right;
- padding-top: 20px;
- padding-right: 10px;
- color: #88C;
-}
-
-</style>
-<script id="iframe_script">
-function reportHeight() {
- var msg = JSON.stringify({type:"size", size:document.body.offsetHeight});
- parent.postMessage(msg, "*");
-}
-
-function frameLoaded() {
- var links = document.getElementsByTagName("A");
- for (i = 0; i < links.length; i++) {
- var class = links[i].className;
- if (class != "item_title" && class != "open_box") {
- links[i].addEventListener("click", showStory);
- }
- }
- window.addEventListener("message", messageHandler);
-}
-
-function showStory(event) {
- var href = event.currentTarget.href;
- parent.postMessage(JSON.stringify({type:"show", url:href}), "*");
- event.preventDefault();
-}
-
-function messageHandler(event) {
- reportHeight();
-}
-
-</script>
-<script>
-// Feed URL.
-var feedUrl = 'http://news.google.com/?output=rss';
-
-// The XMLHttpRequest object that tries to load and parse the feed.
-var req;
-
-function main() {
- req = new XMLHttpRequest();
- req.onload = handleResponse;
- req.onerror = handleError;
- req.open("GET", feedUrl, true);
- req.send(null);
-}
-
-// Handles feed parsing errors.
-function handleFeedParsingFailed(error) {
- var feed = document.getElementById("feed");
- feed.className = "error";
- feed.innerText = "Error: " + error;
-}
-
-// Handles errors during the XMLHttpRequest.
-function handleError() {
- handleFeedParsingFailed('Failed to fetch RSS feed.');
-}
-
-// Handles parsing the feed data we got back from XMLHttpRequest.
-function handleResponse() {
- var doc = req.responseXML;
- if (!doc) {
- handleFeedParsingFailed("Not a valid feed.");
- return;
- }
- buildPreview(doc);
-}
-
-// The maximum number of feed items to show in the preview.
-var maxFeedItems = 5;
-
-// Where the more stories link should navigate to.
-var moreStoriesUrl;
-
-function buildPreview(doc) {
- // Get the link to the feed source.
- var link = doc.getElementsByTagName("link");
- var parentTag = link[0].parentNode.tagName;
- if (parentTag != "item" && parentTag != "entry") {
- moreStoriesUrl = link[0].textContent;
- }
-
- // Setup the title image.
- var images = doc.getElementsByTagName("image");
- var titleImg;
- if (images.length != 0) {
- var urls = images[0].getElementsByTagName("url");
- if (urls.length != 0) {
- titleImg = urls[0].textContent;
- }
- }
- var img = document.getElementById("title");
- if (titleImg) {
- img.src = titleImg;
- if (moreStoriesUrl) {
- document.getElementById("title_a").addEventListener("click", moreStories);
- }
- } else {
- img.style.display = "none";
- }
-
- // Construct the iframe's HTML.
- var iframe_src = "<!doctype html><html><head><script>" +
- document.getElementById("iframe_script").textContent + "<" +
- "/script></head><body onload='frameLoaded();' " +
- "style='padding:0px;margin:0px;'>";
-
- var feed = document.getElementById("feed");
- var entries = doc.getElementsByTagName('entry');
- if (entries.length == 0) {
- entries = doc.getElementsByTagName('item');
- }
- var count = Math.min(entries.length, maxFeedItems);
- for (var i = 0; i < count; i++) {
- item = entries.item(i);
-
- // Grab the title for the feed item.
- var itemTitle = item.getElementsByTagName('title')[0];
- if (itemTitle) {
- itemTitle = itemTitle.textContent;
- } else {
- itemTitle = "Unknown title";
- }
-
- // Grab the description.
- var itemDesc = item.getElementsByTagName('description')[0];
- if (!itemDesc) {
- itemDesc = item.getElementsByTagName('summary')[0];
- if (!itemDesc) {
- itemDesc = item.getElementsByTagName('content')[0];
- }
- }
- if (itemDesc) {
- itemDesc = itemDesc.childNodes[0].nodeValue;
- } else {
- itemDesc = '';
- }
-
- var item = document.createElement("div");
- item.className = "item";
- var box = document.createElement("div");
- box.className = "open_box";
- box.addEventListener("click", showDesc);
- item.appendChild(box);
-
- var title = document.createElement("a");
- title.className = "item_title";
- title.innerText = itemTitle;
- title.addEventListener("click", showDesc);
- item.appendChild(title);
-
- var desc = document.createElement("iframe");
- desc.scrolling = "no";
- desc.className = "item_desc";
- item.appendChild(desc);
- feed.appendChild(item);
-
- // The story body is created as an iframe with a data: URL in order to
- // isolate it from this page and protect against XSS. As a data URL, it
- // has limited privileges and must communicate back using postMessage().
- desc.src="data:text/html," + iframe_src + itemDesc + "</body></html>";
- }
-
- if (moreStoriesUrl) {
- var more = document.createElement("a");
- more.className = "more";
- more.innerText = "More stories \u00BB";
- more.addEventListener("click", moreStories);
- feed.appendChild(more);
- }
-}
-
-// Show |url| in a new tab.
-function showUrl(url) {
- // Only allow http and https URLs.
- if (url.indexOf("http:") != 0 && url.indexOf("https:") != 0) {
- return;
- }
- chrome.tabs.create({url: url});
-}
-
-function moreStories(event) {
- showUrl(moreStoriesUrl);
-}
-
-function showDesc(event) {
- var item = event.currentTarget.parentNode;
- var items = document.getElementsByClassName("item");
- for (var i = 0; i < items.length; i++) {
- var iframe = items[i].getElementsByClassName("item_desc")[0];
- if (items[i] == item && items[i].className == "item") {
- items[i].className = "item opened";
- iframe.contentWindow.postMessage("reportHeight", "*");
- } else {
- items[i].className = "item";
- iframe.style.height = "0px";
- }
- }
-}
-
-function iframeMessageHandler(e) {
- // Only listen to messages from one of our own iframes.
- var iframes = document.getElementsByTagName("IFRAME");
- for (var i = 0; i < iframes.length; i++) {
- if (iframes[i].contentWindow == e.source) {
- var msg = JSON.parse(e.data);
- if (msg) {
- if (msg.type == "size") {
- iframes[i].style.height = msg.size + "px";
- } else if (msg.type == "show") {
- var url = msg.url;
- if (url.indexOf("http://news.google.com") == 0) {
- // If the URL is a redirect URL, strip of the destination and go to
- // that directly. This is necessary because the Google news
- // redirector blocks use of the redirects in this case.
- var index = url.indexOf("&url=");
- if (index >= 0) {
- url = url.substring(index + 5);
- index = url.indexOf("&");
- if (index >= 0)
- url = url.substring(0, index);
- }
- }
- showUrl(url);
- }
- }
- return;
- }
- }
-}
-
-window.addEventListener("message", iframeMessageHandler);
-</script>
-</head>
-<body onload="main();">
-<a id="title_a"><img id='title'></a>
-<div id="feed"></div>
-</body>
-</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/buzz.png b/chrome/common/extensions/docs/examples/extensions/news/images/buzz.png
new file mode 100644
index 0000000..c81c585
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/images/buzz.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/delete-icon.png b/chrome/common/extensions/docs/examples/extensions/news/images/delete-icon.png
new file mode 100644
index 0000000..732b36e
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/images/delete-icon.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/fb.png b/chrome/common/extensions/docs/examples/extensions/news/images/fb.png
new file mode 100644
index 0000000..b6cba93
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/images/fb.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/news.gif b/chrome/common/extensions/docs/examples/extensions/news/images/news.gif
new file mode 100644
index 0000000..2d8df79
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/images/news.gif
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/news_action.png b/chrome/common/extensions/docs/examples/extensions/news/images/news_action.png
index 24b0ca7..24b0ca7 100644
--- a/chrome/common/extensions/docs/examples/extensions/news/news_action.png
+++ b/chrome/common/extensions/docs/examples/extensions/news/images/news_action.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/news_icon.png b/chrome/common/extensions/docs/examples/extensions/news/images/news_icon.png
index 42da406..42da406 100644
--- a/chrome/common/extensions/docs/examples/extensions/news/news_icon.png
+++ b/chrome/common/extensions/docs/examples/extensions/news/images/news_icon.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/sprite_arrows.gif b/chrome/common/extensions/docs/examples/extensions/news/images/sprite_arrows.gif
index 4560faf..4560faf 100644
--- a/chrome/common/extensions/docs/examples/extensions/news/sprite_arrows.gif
+++ b/chrome/common/extensions/docs/examples/extensions/news/images/sprite_arrows.gif
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/images/twitter.png b/chrome/common/extensions/docs/examples/extensions/news/images/twitter.png
new file mode 100644
index 0000000..111f3f4
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/images/twitter.png
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news/javascript/feed.js b/chrome/common/extensions/docs/examples/extensions/news/javascript/feed.js
new file mode 100644
index 0000000..f4cc99a
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/javascript/feed.js
@@ -0,0 +1,388 @@
+/**
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+ */
+
+/**
+ * @fileoverview This file retrieves news feed and shows news in pop-up
+ * page according to country, topics and no. of stories selected in the
+ * option page.
+ */
+
+// Store value retrieved from locale.
+var moreStoriesLocale = chrome.i18n.getMessage('more_stories') + ' \u00BB ';
+var directionLocale = chrome.i18n.getMessage('direction');
+
+// Feed URL.
+var feedUrl = DEFAULT_NEWS_URL;
+
+//The XMLHttpRequest object that tries to load and parse the feed.
+var req;
+
+/**
+ * Sends request to Google News server
+ */
+function main() {
+ req = new XMLHttpRequest();
+ req.onload = handleResponse;
+ req.onerror = handleError;
+ req.open('GET', feedUrl, true);
+ req.send(null);
+}
+
+/**
+ * Handles feed parsing errors.
+ * @param {String} error The localized error message.
+ */
+function handleFeedParsingFailed(error) {
+ var feed = $('feed');
+ $('noStories').style.display = 'none';
+ feed.className = 'error';
+ feed.innerText = error;
+}
+
+/**
+ * Handles errors during the XMLHttpRequest.
+ */
+function handleError() {
+ handleFeedParsingFailed(chrome.i18n.getMessage('fetchError'));
+ $('topics').style.display = 'none';
+}
+
+/**
+ * Parses the feed response.
+ */
+function handleResponse() {
+ var doc = req.responseXML;
+ if (!doc) {
+ handleFeedParsingFailed(chrome.i18n.getMessage('wrongTopic'));
+ var img = $('title');
+ if(!img.src) {
+ img.src = "/images/news.gif";
+ }
+
+ document.querySelector('body').style.minHeight = 0;
+ return;
+ }
+ buildPreview(doc);
+}
+
+// Stores no. of stories selected in options page.
+var maxFeedItems = (window.localStorage.getItem('count')) ?
+ window.localStorage.getItem('count') : 5;
+
+// Where the more stories link should navigate to.
+var moreStoriesUrl;
+
+/**
+ * Generates news iframe in pop-up page by parsing retrieved feed.
+ * @param {HTMLDocument} doc HTML Document received in feed.
+ */
+function buildPreview(doc) {
+ // Get the link to the feed source.
+ var link = doc.querySelector('link');
+ var parentTag = link.parentNode.tagName;
+ if (parentTag != 'item' && parentTag != 'entry') {
+ moreStoriesUrl = link.textContent;
+ }
+
+ // Setup the title image.
+ var image = doc.querySelector('image');
+ var titleImg;
+
+ // Stores whether language script is Right to Left or not for setting style
+ // of share buttons(Facebook, Twitter and Google Buzz) in iframe.
+ var isRtl = 'lTR';
+
+ if (image) {
+ var url = image.querySelector('url');
+ if (url) {
+ titleImg = url.textContent;
+
+ // Stores URL of title image to be shown on pop-up page.
+ var titleImgUrl = titleImg;
+ var pattern = /ar_/gi;
+ var result = titleImgUrl.match(pattern);
+ if (result != null || titleImgUrl == ISRAEL_IMAGE_URL) {
+ isRtl = 'rTL';
+ }
+ }
+ }
+
+ var img = $('title');
+ if (titleImg) {
+ img.src = titleImg;
+ if (moreStoriesUrl) {
+ $('title_a').addEventListener('click', moreStories);
+ }
+ } else {
+ img.style.display = 'none';
+ }
+
+ // Construct the iframe's HTML.
+ var iframe_src = '<!doctype html><html><head><script>' +
+ $('iframe_script').textContent + '<' +
+ '/script><style> ' +
+ '.rTL {margin-right: 102px; text-align: right;} ' +
+ '.lTR {margin-left: 102px; text-align: left;} ' +
+ '</style></head><body onload="frameLoaded();" ' +
+ 'style="padding:0px;margin:0px;">';
+
+ var feed = $('feed');
+ feed.className = '';
+ var entries = doc.getElementsByTagName('entry');
+ if (entries.length == 0) {
+ entries = doc.getElementsByTagName('item');
+ }
+ var count = Math.min(entries.length, maxFeedItems);
+
+ // Stores required height by pop-up page.
+ var minHeight = 19;
+ minHeight = (minHeight * (count - 1)) + 100;
+ document.querySelector('body').style.minHeight = minHeight + 'px';
+ $('feed').innerHTML = '';
+
+ for (var i = 0; i < count; i++) {
+ item = entries.item(i);
+
+ // Grab the title for the feed item.
+ var itemTitle = item.querySelector('title');
+ if (itemTitle) {
+ itemTitle = itemTitle.textContent;
+ } else {
+ itemTitle = 'Unknown title';
+ }
+
+ // Grab the description.
+ var itemDesc = item.querySelector('description');
+ if (!itemDesc) {
+ itemDesc = item.querySelector('summary');
+ if (!itemDesc) {
+ itemDesc = item.querySelector('content');
+ }
+ }
+ if (itemDesc) {
+ itemDesc = itemDesc.childNodes[0].nodeValue;
+
+ } else {
+ itemDesc = '';
+ }
+ var itemLink = item.querySelector('link');
+ if (itemLink) {
+ itemLink = itemLink.textContent;
+ } else {
+ itemLink = 'Unknown itemLink';
+ }
+ var item = document.createElement('div');
+ item.className = 'item';
+ var box = document.createElement('div');
+ box.className = 'open_box';
+ box.addEventListener('click', showDesc);
+ item.appendChild(box);
+
+ var title = document.createElement('a');
+ title.className = 'item_title';
+ title.innerText = itemTitle;
+ title.addEventListener('click', showDesc);
+ item.appendChild(title);
+
+ var desc = document.createElement('iframe');
+ desc.scrolling = 'no';
+ desc.className = 'item_desc';
+ item.appendChild(desc);
+ feed.appendChild(item);
+
+ // Adds share buttons images(Facebook, Twitter and Google Buzz).
+ itemDesc += "<div class = '" + isRtl + "'>";
+ itemDesc += "<a style='cursor: pointer' id='fb' " +
+ "onclick='openNewsShareWindow(this.id,\"" + itemLink + "\")'>" +
+ "<img src='" + chrome.extension.getURL('/images/fb.png') + "'/></a>";
+ itemDesc += " <a style='cursor: pointer' id='twitter' " +
+ "onclick='openNewsShareWindow(this.id,\"" + itemLink + "\")'>" +
+ "<img src='" + chrome.extension.getURL('/images/twitter.png') + "'/></a>";
+ itemDesc += " <a style='cursor: pointer' id='buzz' " +
+ "onclick='openNewsShareWindow(this.id,\"" + itemLink + "\")'>" +
+ "<img src='" + chrome.extension.getURL('/images/buzz.png') + "'/></a>";
+ itemDesc += '</div>';
+
+ // The story body is created as an iframe with a data: URL in order to
+ // isolate it from this page and protect against XSS. As a data URL, it
+ // has limited privileges and must communicate back using postMessage().
+ desc.src = 'data:text/html;charset=utf-8,' + iframe_src + itemDesc +
+ '</body></html>';
+ }
+ if (moreStoriesUrl && entries.length != 0) {
+ var more = document.createElement('a');
+ more.className = 'more';
+ more.innerText = moreStoriesLocale;
+ more.addEventListener('click', moreStories);
+ feed.appendChild(more);
+ }
+ setStyleByLang(titleImgUrl);
+
+ // Checks whether feed retrieved has news story or not. If not, then shows
+ // error message accordingly.
+ if (entries.length == 0) {
+ $('noStories').innerText = chrome.i18n.getMessage('noStory');
+ $('noStories').style.display = 'block';
+ } else {
+ $('noStories').style.display = 'none';
+ }
+}
+
+/**
+ * Show |url| in a new tab.
+ * @param {String} url The news URL.
+ */
+function showUrl(url) {
+ // Only allow http and https URLs.
+ if (url.indexOf('http:') != 0 && url.indexOf('https:') != 0) {
+ return;
+ }
+ chrome.tabs.create({url: url});
+}
+
+/**
+ * Redirects to Google news site for more stories.
+ * @param {Object} event Onclick event.
+ */
+function moreStories(event) {
+ showUrl(moreStoriesUrl);
+}
+
+/**
+ * Shows description of the news when users clicks on news title.
+ * @param {Object} event Onclick event.
+ */
+function showDesc(event) {
+ var item_ = event.currentTarget.parentNode;
+ var items = document.getElementsByClassName('item');
+ for (var i = 0, item; item = items[i]; i++) {
+ var iframe = item.querySelector('.item_desc');
+ if (item == item_ && item.className == 'item') {
+ item.className = 'item opened';
+ iframe.contentWindow.postMessage('reportHeight', '*');
+ } else {
+ item.className = 'item';
+ iframe.style.height = '0px';
+ }
+ }
+}
+
+/**
+ * Handles messages between different iframes and sets the display of iframe.
+ * @param {Object} e Onmessage event.
+ */
+function iframeMessageHandler(e) {
+ var iframes = document.getElementsByTagName('IFRAME');
+ for (var i = 0, iframe; iframe = iframes[i]; i++) {
+ if (iframe.contentWindow == e.source) {
+ var msg = JSON.parse(e.data);
+ if (msg) {
+ if (msg.type == 'size') {
+ iframe.style.height = msg.size + 'px';
+ } else if (msg.type == 'show') {
+ var url = msg.url;
+ if (url.indexOf('http://news.google.com') == 0) {
+ // If the URL is a redirect URL, strip of the destination and go to
+ // that directly. This is necessary because the Google news
+ // redirector blocks use of the redirects in this case.
+ var index = url.indexOf('&url=');
+ if (index >= 0) {
+ url = url.substring(index + 5);
+ index = url.indexOf('&');
+ if (index >= 0)
+ url = url.substring(0, index);
+ }
+ }
+ showUrl(url);
+ }
+ }
+ return;
+ }
+ }
+}
+
+/**
+ * Saves last viewed topic by user in local storage on unload of pop-up page.
+ */
+function saveLastTopic() {
+ var topicVal = $('topics').value;
+ window.localStorage.setItem('lastTopic', topicVal);
+}
+
+/**
+ * Sets the URL according to selected topic(or default topic), then retrieves
+ * feed and sets pop-up page.
+ */
+function getNewsByTitle() {
+ var country = window.localStorage.getItem('country');
+ country = (country == 'noCountry' || !country) ? '' : country;
+
+ // Sets direction of topics showed under dropdown in pop-up page according
+ // to set language in browser.
+ $('topics').className = (directionLocale == 'rtl') ? 'topicsRTL' :
+ 'topicsLTR';
+
+ var topicVal = $('topics').value;
+
+ // Sets Feed URL in case of custom topic selected.
+ var keywords = JSON.parse(window.localStorage.getItem('keywords'));
+ var isFound = false;
+ if (keywords) {
+ for (i = 0; i < keywords.length; i++) {
+ if (topicVal == keywords[i]) {
+ isFound = true;
+ feedUrl = DEFAULT_NEWS_URL + '&cf=all&ned=' + country + '&q=' + topicVal +
+ '&hl=' + country;
+ break;
+ }
+ }
+ }
+ if (!isFound) {
+ feedUrl = DEFAULT_NEWS_URL + '&cf=all&ned=' + country +
+ '&topic=' + topicVal;
+ }
+ main();
+}
+
+/**
+ * Shows topic list retrieved from local storage(if any),else shows
+ * default topics list.
+ */
+function getTopics() {
+ var topics = JSON.parse(window.localStorage.getItem('topics'));
+ var keywords = JSON.parse(window.localStorage.getItem('keywords'));
+ var element = $('topics');
+
+ // Sets all topics as default list if no list is found from local storage.
+ if (!topics && !keywords) {
+ topics = [' ','n','w','b','t','e','s','m','po'];
+ }
+
+ if (topics) {
+ for (var i = 0; i < (topics.length); i++) {
+ var val = (topics[i] == ' ') ? '1' : topics[i];
+ element.options[element.options.length] = new Option(
+ chrome.i18n.getMessage(val), topics[i]);
+ }
+ }
+
+ // Shows custom topics in list(if any).
+ if (keywords) {
+ for (i = 0; i < (keywords.length); i++) {
+ element.options[element.options.length] = new Option(keywords[i],
+ keywords[i]);
+ }
+ }
+
+ $('option_link').innerText = chrome.i18n.getMessage('options');
+
+ var topicVal = window.localStorage.getItem('lastTopic');
+ if (topicVal) {
+ $('topics').value = topicVal;
+ }
+}
+
+window.addEventListener('message', iframeMessageHandler);
diff --git a/chrome/common/extensions/docs/examples/extensions/news/javascript/options.js b/chrome/common/extensions/docs/examples/extensions/news/javascript/options.js
new file mode 100644
index 0000000..5324a8b
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/javascript/options.js
@@ -0,0 +1,395 @@
+/**
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+ */
+
+/**
+ * @fileoverview Includes the country selection, topics selection and
+ * selection of no. of news stories to be shown. Include default settings also.
+ * @author navneetg@google.com (Navneet Goel).
+ */
+
+/**
+ * Stores number of selected topics on the options page.
+ */
+var checkCount = 0;
+
+/**
+ * Stores maximum count of custom topics.
+ */
+var MAX_CUS_TOPICS = 10;
+
+/**
+ * Stores temporary added custom topics which are not yet saved.
+ */
+var tempCusTopics = [];
+
+/**
+ * Checks whether ENTER key is pressed or not.
+ */
+function addCustomTopic() {
+ if (window.event.keyCode == 13) {
+ addCusTopic();
+ }
+}
+
+/**
+ * Retrieves and sets last saved country from local storage(if found),
+ * else sets country retrieved from feed.
+ */
+function setCountry() {
+ var country = window.localStorage.getItem('country');
+
+ // If country is not found in localstorage or default value is selected in
+ // drop down menu.
+ if ((!country) || country == 'noCountry') {
+ // XMLHttpRequest object that tries to load the feed for the purpose of
+ // retrieving the country value out of feed.
+ var req = new XMLHttpRequest();
+ req.onload = handleResponse;
+ req.onerror = handleError;
+ req.open('GET', DEFAULT_NEWS_URL, true);
+ req.send(null);
+
+ // Sets country to default Country in dropdown menu.
+ function handleError() {
+ $('countryList').value = 'noCountry';
+ };
+
+ // Handles parsing the feed data got back from XMLHttpRequest.
+ function handleResponse() {
+ // Feed document retrieved from URL.
+ var doc = req.responseXML;
+ if (!doc) {
+ handleError();
+ return;
+ }
+ var imageLink = doc.querySelector('image link');
+ if (imageLink) {
+ // Stores link to set value of country.
+ var newsUrl = imageLink.textContent;
+ }
+
+ // Stores country value
+ $('countryList').value = newsUrl.substring(newsUrl.indexOf('&ned=') + 5,
+ newsUrl.indexOf('&hl='));
+ };
+ } else {
+ $('countryList').value = country;
+ }
+}
+
+/**
+ * Displays various messages to user based on user input.
+ * @param {String} id Id of status element.
+ * @param {Number} timeOut Timeout value of message shown.
+ * @param {String} message Message to be shown.
+ */
+function showUserMessages(id, timeOut, message) {
+ $(id).style.setProperty('-webkit-transition',
+ 'opacity 0s ease-in');
+ $(id).style.opacity = 1;
+ $(id).innerText = chrome.i18n.getMessage(message);
+ window.setTimeout(function() {
+ $(id).style.setProperty(
+ '-webkit-transition', 'opacity' + timeOut + 's ease-in');
+ $(id).style.opacity = 0;
+ }, 1E3
+ );
+}
+
+/**
+ * Sets options page CSS according to the browser language(if found), else sets
+ * to default locale.
+ */
+function setOptionPageCSS() {
+ if (chrome.i18n.getMessage('direction') == 'rtl') {
+ document.querySelector('body').className = 'rtl';
+ }
+}
+
+/**
+ * Initializes the options page by retrieving country, topics and count of
+ * stories from local storage if present, else sets to default settings.
+ */
+function initialize() {
+ setOptionPageCSS();
+ setCountry();
+ setCountAndTopicList();
+ setLocalizedTopicList();
+
+ // Adds a custom topic on press of Enter key.
+ $('newKeyword').onkeypress = addCustomTopic;
+}
+
+/**
+ * Retrieves locale values from locale file.
+ */
+function setLocalizedTopicList() {
+ var getI18nMsg = chrome.i18n.getMessage;
+
+ $('top').innerText = getI18nMsg('1');
+ $('nation').innerText = getI18nMsg('n');
+ $('world').innerText = getI18nMsg('w');
+ $('business').innerText = getI18nMsg('b');
+ $('science').innerText = getI18nMsg('t');
+ $('entertainment').innerText = getI18nMsg('e');
+ $('sports').innerText = getI18nMsg('s');
+ $('health').innerText = getI18nMsg('m');
+ $('most').innerText = getI18nMsg('po');
+ $('select_country').innerText = getI18nMsg('country');
+ $('topic').innerText = getI18nMsg('topic');
+ $('save_button').innerText = getI18nMsg('save');
+ $('story_count').innerText = getI18nMsg('storyCount');
+ $('logo').innerHTML = $('logo').innerHTML + getI18nMsg('newsOption');
+ $('custom_text').innerHTML = getI18nMsg('customText') + '<br/>' +
+ getI18nMsg('maximumTopics',[MAX_CUS_TOPICS]);
+ $('submit_button').value = getI18nMsg('submitButton');
+}
+
+/**
+ * Sets topic list and number of stories retrieved from localstorage(if any)
+ * otherwise sets to default.
+ */
+function setCountAndTopicList() {
+ var topicLists = document.getElementsByClassName('checkBox');
+
+ // Retrieves topics list from localStorage.
+ var topics = JSON.parse(window.localStorage.getItem('topics'));
+
+ // Runs if retrieved topic list from local storage contains topics.
+ if (topics) {
+ for (var x = 0, topicList; topicList = topicLists[x]; x++) {
+
+ // Saves whether checkbox is checked or not.
+ var isPresent = false;
+ for (var y = 0; y < topics.length; y++) {
+ if (topics[y] == topicList.value) {
+ topicList.checked = true;
+ isPresent = true;
+ checkCount++;
+ break;
+ }
+ }
+ if (!isPresent) {
+ topicList.checked = false;
+ }
+ }
+ }
+
+ // Retrieves list of custom topics from localstorage(if any) and shows it
+ // in option page.
+ var keywords = JSON.parse(window.localStorage.getItem('keywords'));
+ if (keywords) {
+
+ // Template to store custom topics in a table.
+ var template = [];
+ var title = chrome.i18n.getMessage('deleteTitle');
+ for (var i = 0; i < keywords.length; i++) {
+ checkCount++;
+
+ template.push('<tr style = "height: 22px;">');
+ template.push('<td id = "keyword_value" class = "cusTopicsClass">');
+ template.push('<textarea class="noborder" readonly>');
+ template.push(keywords[i]);
+ template.push('</textarea>');
+ template.push('<td class = "suppr" onclick = "delCusTopic(this)" ');
+ template.push('title="');
+ template.push(title);
+ template.push('">');
+ template.push('</td>');
+ template.push('</tr>');
+ }
+ $('custom_topics').innerHTML = template.join('');
+ if (keywords.length == MAX_CUS_TOPICS) {
+ $('submit_button').disabled = true;
+ $('newKeyword').readOnly = 'readonly';
+ }
+ }
+ // Check all checkboxes(default settings) if no custom topic list and
+ // checkbox topic list from local storage is found.
+ if (!keywords && !topics) {
+ for (var x = 0, topicList; topicList = topicLists[x]; x++) {
+ topicList.checked = true;
+ checkCount++;
+ }
+ }
+
+ // Retrieves saved value of number of stories.
+ var count = window.localStorage.getItem('count');
+
+ // Sets number of stories in dropdown.
+ if (count) {
+ $('storyCount').value = count;
+ }
+}
+
+/**
+ * Saves checked topic list(if any), Custom topics(if any), number of
+ * stories and country value in local storage.
+ */
+function saveTopicsCountry() {
+ var country = $('countryList').value;
+ var topicLists = document.getElementsByClassName('checkBox');
+
+ // Contains selected number of stories.
+ var count = $('storyCount').value;
+
+ // Stores checked topics list.
+ var topicArr = [];
+ for (var i = 0, topicList; topicList = topicLists[i]; i++) {
+ if (topicList.checked) {
+ topicArr.push(topicList.value);
+ }
+ }
+ var keywords = JSON.parse(window.localStorage.getItem('keywords'));
+
+ // Saves custom topics to local storage(if any).
+ if (tempCusTopics.length > 0) {
+ if (keywords) {
+ keywords = keywords.concat(tempCusTopics);
+ window.localStorage.setItem('keywords', JSON.stringify(keywords));
+ } else {
+ window.localStorage.setItem('keywords', JSON.stringify(tempCusTopics));
+ }
+ tempCusTopics.splice(0, tempCusTopics.length);
+ }
+
+ // Saves checkbox topics(if any).
+ if (topicArr.length > 0) {
+ window.localStorage.setItem('topics', JSON.stringify(topicArr));
+ } else {
+ window.localStorage.removeItem('topics');
+ }
+
+ window.localStorage.setItem('count', count);
+ window.localStorage.setItem('country', country);
+
+ showUserMessages('save_status', 0.5, 'saveStatus');
+ $('save_button').disabled = true;
+}
+
+/**
+ * Disables the save button on options page if no topic is selected by the user.
+ * @param {String} id Id of checkbox checked or unchecked.
+ */
+function manageCheckCount(id) {
+ checkCount = ($(id).checked) ? (checkCount + 1) : (checkCount - 1);
+ $('save_button').disabled = (checkCount == 0) ? true : false;
+}
+
+/**
+ * Enables save button if at least one topic is selected.
+ */
+function enableSaveButton() {
+ if (checkCount != 0) {
+ $('save_button').disabled = false;
+ }
+}
+
+/**
+ * Adds new entered custom topic.
+ */
+function addCusTopic() {
+ // Retrieves custom topic list from local storage(if any), else create new
+ // array list.
+ var keywords = JSON.parse(window.localStorage.getItem('keywords') || "[]");
+
+ // Adds topic only if total number of added custom topics are less than 10.
+ if (keywords.length + tempCusTopics.length <= (MAX_CUS_TOPICS - 1)) {
+
+ // Stores new entered value in input textbox.
+ var val = $('newKeyword').value;
+ if (val) {
+ val = val.trim();
+ if (val.length > 0) {
+ var pattern = /,/g;
+
+ // Runs if comma(,) is not present in topic entered.
+ if (val.match(pattern) == null) {
+ checkCount++;
+ tempCusTopics.push(val);
+
+ // Template to store custom topics in a table.
+ var template = [];
+ var title = chrome.i18n.getMessage('deleteTitle');
+
+ template.push('<tr style = "height: 22px;">');
+ template.push('<td id = "keyword_value" class = "cusTopicsClass">');
+ template.push('<textarea class="noborder" readonly>');
+ template.push(val);
+ template.push('</textarea>');
+ template.push('<td class = "suppr" onclick = "delCusTopic(this)" ');
+ template.push('title="');
+ template.push(title);
+ template.push('">');
+ template.push('</td>');
+ template.push('</tr>');
+
+ $('custom_topics').innerHTML += template.join('');
+ enableSaveButton();
+ } else {
+ showUserMessages('invalid_status', 2.5, 'invalidChars');
+ }
+ }
+ $('newKeyword').value = '';
+ }
+ }
+
+ if ((keywords.length + tempCusTopics.length) == (MAX_CUS_TOPICS)) {
+ $('submit_button').disabled = true;
+ $('newKeyword').readOnly = 'readonly';
+ }
+}
+
+/**
+ * Delete custom topic whenever users click on delete icon.
+ * @param {HTMLTableColElement} obj HTML table column element to be deleted.
+ */
+function delCusTopic(obj) {
+ // Deletes only if total number of topics are greater than 1, else shows
+ // error message.
+ if (checkCount > 1) {
+ var value;
+
+ // Extract custom topic value.
+ value = obj.parentNode.querySelector('.cusTopicsClass textarea').value;
+
+ // Removes custom topic element from UI.
+ $('custom_topics').removeChild(obj.parentNode);
+
+ // Removes custom topic element either from temporary array(if topic is
+ // not yet saved) or from saved topic list and saves new list to
+ // local storage.
+ var flag = 0;
+ for (var i = 0; i < tempCusTopics.length; i++) {
+ if (tempCusTopics[i] == value) {
+ tempCusTopics.splice(i, 1);
+ flag = 1;
+ break;
+ }
+ }
+
+ if (flag == 0) {
+ var keywords = JSON.parse(window.localStorage.getItem('keywords'));
+ for (i = 0; i < keywords.length; i++) {
+ if (keywords[i] == value) {
+ keywords.splice(i, 1);
+ break;
+ }
+ }
+ if (keywords.length > 0) {
+ window.localStorage.setItem('keywords', JSON.stringify(keywords));
+ } else {
+ window.localStorage.removeItem('keywords');
+ }
+ }
+
+ checkCount--;
+ $('submit_button').disabled = false;
+ } else {
+ showUserMessages('save_status', 2.5, 'noTopic');
+ }
+ $('newKeyword').readOnly = false;
+}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/javascript/util.js b/chrome/common/extensions/docs/examples/extensions/news/javascript/util.js
new file mode 100644
index 0000000..f8e3880
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/javascript/util.js
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+ */
+
+/**
+ * @fileoverview Defines the constants and most commonly used functions.
+ * @author navneetg@google.com (Navneet Goel).
+ */
+
+/**
+ * Default feed news URL.
+ */
+var DEFAULT_NEWS_URL = 'http://news.google.com/news?output=rss';
+
+/**
+ * Image URL of Israel country.
+ */
+var ISRAEL_IMAGE_URL = 'http://www.gstatic.com/news/img/logo/iw_il/news.gif';
+
+/**
+ * Alias for getElementById.
+ * @param {String} elementId Element id of the HTML element to be fetched.
+ * @return {Element} Element corresponding to the element id.
+ */
+function $(elementId) {
+ return document.getElementById(elementId);
+}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/manifest.json b/chrome/common/extensions/docs/examples/extensions/news/manifest.json
index f0c7e0e..cff6f2e 100644
--- a/chrome/common/extensions/docs/examples/extensions/news/manifest.json
+++ b/chrome/common/extensions/docs/examples/extensions/news/manifest.json
@@ -1,15 +1,18 @@
{
- "name": "News Reader",
- "version": "1.1",
- "description": "Displays the first 5 items from the 'Google News - top news' RSS feed in a popup.",
- "icons": { "128": "news_icon.png" },
+ "name": "__MSG_extName__",
+ "version": "2.0",
+ "description": "__MSG_extDesc__",
+ "icons": { "128": "images/news_icon.png" },
+ "default_locale":"en",
"browser_action": {
- "default_title": "Google News",
- "default_icon": "news_action.png",
- "popup": "feed.html"
+ "default_title": "__MSG_ext_default_title__",
+ "default_icon": "images/news_action.png",
+ "popup": "views/feed.html"
},
"permissions": [
"tabs",
"http://news.google.com/*"
- ]
+ ],
+ "options_page": "views/options.html",
+ "background_page": "views/background.html"
}
diff --git a/chrome/common/extensions/docs/examples/extensions/news/views/background.html b/chrome/common/extensions/docs/examples/extensions/news/views/background.html
new file mode 100644
index 0000000..c97e977
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/views/background.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!--
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+-->
+
+<!--
+@fileoverview Contains script for running at the background to open up the
+options page when the extension is reloaded.
+-->
+
+<html>
+ <body>
+ <script>
+ //Retrieves value from local storage(if found).
+ var newsFlag = window.localStorage.getItem('newsFlag');
+
+ //Runs if extension installation is done.
+ if(!newsFlag) {
+ var optionsPageURL = chrome.extension.getURL('/views/options.html');
+ chrome.tabs.create({url: optionsPageURL});
+ window.localStorage.setItem('newsFlag','1');
+ }
+ </script>
+ </body>
+</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/news/views/feed.html b/chrome/common/extensions/docs/examples/extensions/news/views/feed.html
new file mode 100644
index 0000000..43d147b
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/views/feed.html
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<!--
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+-->
+
+<!--
+@fileoverview This file serves as the pop-up page for showing news
+according to the settings saved in options page otherwise shows default
+settings.
+@author navneetg@google.com (Navneet Goel).
+-->
+
+<html>
+<head>
+<script src = "/javascript/util.js"></script>
+<link rel = "stylesheet" href = "/css/feed.css"/>
+
+<script id = "iframe_script">
+
+/**
+ * Facebook share URL.
+ */
+var FB_SHARE_URL = "http://www.facebook.com/sharer.php?u=";
+
+/**
+ * Twitter share URL.
+ */
+var TWITTER_SHARE_URL = "http://twitter.com/share?&url=";
+
+/**
+ * Buzz share URL.
+ */
+var BUZZ_SHARE_URL = "http://www.google.com/buzz/post?&url=";
+
+/**
+ * Opens new window either of facebook, twitter or google buzz.
+ * @param {String} id Specifies whether to share news on Facebook, Google Buzz
+ * or Twitter.
+ * @param {String} url Contains URL of the News to be shared.
+ */
+function openNewsShareWindow(id, url) {
+ var newsUrl = url.substring(url.indexOf('&url=') + 5);
+ var openUrl;
+ switch (id) {
+ case 'fb':
+ openUrl = FB_SHARE_URL;
+ break;
+ case 'buzz':
+ openUrl = BUZZ_SHARE_URL;
+ break;
+ case 'twitter':
+ openUrl = TWITTER_SHARE_URL;
+ break;
+ }
+ window.open(openUrl + newsUrl, '_blank',
+ 'resizable=0,scrollbars=0,width=690,height=415');
+}
+
+/**
+ * Checks language in image url retrieved from feed and sets style of
+ * title and openbox in pop-up page(if url is found), otherwise sets
+ * to default styling.
+ */
+function setStyleByLang(titleImgUrl) {
+ var openBoxes = document.getElementsByClassName('open_box');
+ var itemTitles = document.getElementsByClassName('item_title');
+
+ if (titleImgUrl != 'NULL') {
+ var pattern = /ar_/gi;
+ var result = titleImgUrl.match(pattern);
+ if (result != null || titleImgUrl == ISRAEL_IMAGE_URL) {
+ document.querySelector('body').className = 'rtl';
+ }
+ }
+}
+
+/**
+ * Reports the height.
+ */
+function reportHeight() {
+ var msg = JSON.stringify({type:"size", size:document.body.offsetHeight});
+ parent.postMessage(msg, "*");
+}
+
+/**
+ * Initialize the iframe body.
+ */
+function frameLoaded() {
+ var links = document.getElementsByTagName("A");
+ for (var i = 0, link; link = links[i]; i++) {
+ var class = link.className;
+ if (class != "item_title" && class != "open_box") {
+ link.addEventListener("click", showStory);
+ }
+ }
+ window.addEventListener("message", messageHandler);
+}
+
+/**
+ * Redirects to Google news site according to clicked URL.
+ * @param {Object} event Onclick event.
+ */
+function showStory(event) {
+ var href = event.currentTarget.href;
+ parent.postMessage(JSON.stringify({type:"show", url:href}), "*");
+ event.preventDefault();
+}
+
+/**
+ * Handles message.
+ * @param {Object} event Onmessage event.
+ */
+function messageHandler(event) {
+ reportHeight();
+}
+</script>
+<script src = "/javascript/feed.js"></script>
+</head>
+
+<body onload = "getTopics();getNewsByTitle();" onunload = "saveLastTopic();">
+
+<div style = "margin-bottom: 15px;">
+ <div style = "float: right;">
+ <div style = "float: right; font-size: 11px">
+ <a id = "option_link" onclick = "chrome.tabs.create({url: '/views/options.html', selected: true})">
+ </a>
+ </div>
+ <div style = "margin-top: 27px">
+ <select id = "topics" onchange = "getNewsByTitle();" style = "display: inline;">
+ </select>
+ </div>
+ </div>
+ <a id = "title_a">
+ <img id = "title" style = "padding-top: 5px;">
+ </a>
+</div>
+
+<div id = "feed">
+</div>
+
+<div id = "noStories">
+</div>
+</body>
+</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/news/views/options.html b/chrome/common/extensions/docs/examples/extensions/news/views/options.html
new file mode 100644
index 0000000..6bf99b3
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/news/views/options.html
@@ -0,0 +1,166 @@
+<!DOCTYPE html>
+<!--
+ * Copyright (c) 2010 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+-->
+
+<!--
+@fileoverview This file serves as the option page of the extension for
+customizing the settings such as setting country, topics and number of
+news stories to be shown.
+@author navneetg@google.com (Navneet Goel).
+-->
+
+<html>
+ <head>
+ <script src = "/javascript/util.js"></script>
+ <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8">
+ <link rel = "stylesheet" href = "/css/options.css"/>
+ <script src = "/javascript/options.js"></script>
+ </head>
+ <body onload = "initialize();">
+ <div id = "all_content">
+ <div id = "logo">
+ <img id = "title_image" src = "/images/news.gif"/>
+ <br/>
+ </div>
+ <br/><br/>
+
+ <table class = "contentTable" style = "margin-left: 55px;" width = "96%">
+ <tr class = "all_rows">
+ <td class = "col1"><b id = "select_country"></b></td>
+ <td class = "col2">
+ <select id = "countryList" onchange = "enableSaveButton();">
+ <option value = "noCountry">-Select-</option>
+ <option value = "es_ar">Argentina</option>
+ <option value = "au">Australia</option>
+ <option value = "nl_be">België</option>
+ <option value = "fr_be">Belgique</option>
+ <option value = "en_bw">Botswana</option>
+ <option value = "pt-BR_br">Brasil</option>
+ <option value = "ca">Canada English</option>
+ <option value = "fr_ca">Canada Français</option>
+ <option value = "cs_cz">Česká republika</option>
+ <option value = "es_cl">Chile</option>
+ <option value = "es_co">Colombia</option>
+ <option value = "es_cu">Cuba</option>
+ <option value = "de">Deutschland</option>
+ <option value = "es">España</option>
+ <option value = "es_us">Estados Unidos</option>
+ <option value = "en_et">Ethiopia</option>
+ <option value = "fr">France</option>
+ <option value = "en_gh">Ghana</option>
+ <option value = "in">India</option>
+ <option value = "en_ie">Ireland</option>
+ <option value = "en_il">Israel English</option>
+ <option value = "it">Italia</option>
+ <option value = "en_ke">Kenya</option>
+ <option value = "hu_hu">Magyarország</option>
+ <option value = "en_my">Malaysia</option>
+ <option value = "es_mx">México</option>
+ <option value = "en_na">Namibia</option>
+ <option value = "nl_nl">Nederland</option>
+ <option value = "nz">New Zealand</option>
+ <option value = "en_ng">Nigeria</option>
+ <option value = "no_no">Norge</option>
+ <option value = "de_at">Österreich</option>
+ <option value = "en_pk">Pakistan</option>
+ <option value = "es_pe">Perú</option>
+ <option value = "en_ph">Philippines</option>
+ <option value = "pl_pl">Polska</option>
+ <option value = "pt-PT_pt">Portugal</option>
+ <option value = "de_ch">Schweiz</option>
+ <option value = "fr_sn">Sénégal</option>
+ <option value = "en_sg">Singapore</option>
+ <option value = "en_za">South Africa</option>
+ <option value = "fr_ch">Suisse</option>
+ <option value = "sv_se">Sverige</option>
+ <option value = "en_tz">Tanzania</option>
+ <option value = "tr_tr">Türkiye</option>
+ <option value = "uk">U.K.</option>
+ <option value = "us">U.S.</option>
+ <option value = "en_ug">Uganda</option>
+ <option value = "es_ve">Venezuela</option>
+ <option value = "vi_vn">Việt Nam (Vietnam)</option>
+ <option value = "en_zw">Zimbabwe</option>
+ <option value = "el_gr">Ελλάδα (Greece)</option>
+ <option value = "ru_ru">Россия (Russia)</option>
+ <option value = "ru_ua">Украина / русский (Ukraine)</option>
+ <option value = "uk_ua">Україна / українська (Ukraine)</option>
+ <option value = "iw_il">ישראל (Israel)</option>
+ <option value = "ar_ae">الإمارات (UAE)</option>
+ <option value = "ar_sa">السعودية (KSA)</option>
+ <option value = "ar_me">العالم العربي (Arabic)</option>
+ <option value = "ar_lb">لبنان (Lebanon)</option>
+ <option value = "ar_eg">مصر (Egypt)</option>
+ <option value = "hi_in">हिन्दी (India)</option>
+ <option value = "ta_in">தமிழ்(India)</option>
+ <option value = "te_in">తెలుగు (India)</option>
+ <option value = "ml_in">മലയാളം (India)</option>
+ <option value = "kr">한국 (Korea)</option>
+ <option value = "cn">中国版 (China)</option>
+ <option value = "tw">台灣版 (Taiwan)</option>
+ <option value = "jp">日本 (Japan)</option>
+ <option value = "hk">香港版 (Hong Kong)</option>
+ </select>
+ </td>
+ </tr>
+ <tr class = "all_rows">
+ <td class = "col1"><b id = "story_count"></b></td>
+ <td class = "col2">
+ <select id = "storyCount" style = "padding-left: 3px;" onchange = "enableSaveButton();">
+ <option value = "1">1</option>
+ <option value = "2">2</option>
+ <option value = "3">3</option>
+ <option value = "4">4</option>
+ <option value = "5" selected = "selected">5</option>
+ <option value = "6">6</option>
+ <option value = "7">7</option>
+ <option value = "8">8</option>
+ <option value = "9">9</option>
+ <option value = "10">10</option>
+ </select>
+ </td>
+ </tr>
+ <tr class = "all_rows">
+ <td class = "col1">
+ <div id = "topic" style = "font-weight: bold;"></div>
+ </td>
+ <td class = "col2">
+ <div>
+ <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = " " id = "check11" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "top"></div><br/></div>
+ <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "n" id = "check13" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "nation"></div><br/></div>
+ <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "w" id = "check14" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "world"></div><br/></div>
+ <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "b" id = "check15" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "business"></div><br/></div>
+ <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "t" id = "check16" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "science"></div><br/></div>
+ <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "e" id = "check17" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "entertainment"></div><br/></div>
+ <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "s" id = "check18" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "sports"></div><br/></div>
+ <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "m" id = "check19" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "health"></div><br/></div>
+ <div class = "boxAndTopic"><input class = "checkBox" type = "checkbox" value = "po" id = "check20" onchange = "manageCheckCount(this.id)"/><div class = "checkBoxTopic" id = "most"></div><br/></div>
+ </div>
+ </td>
+ </tr>
+ <tr class = "all_rows">
+ <td class = "col1">
+ <div id = "custom_text" style = "font-weight: bold;"></div>
+ </td>
+ <td class = "col2">
+ <input id = "newKeyword" type = "text" maxlength = "20" style = "width: 205px;">
+ <input id = "submit_button" type = "submit" onclick = "addCusTopic()" style = "width: 45px;">
+ <span id = "invalid_status"></span>
+ <table>
+ <tbody id = "custom_topics"></tbody>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <br/>
+ <div id = "save_div">
+ <button id = "save_button" type = "button" disabled = "disabled" onclick = "saveTopicsCountry()" style = "width: 80px;">
+ </button>
+ <span id = "save_status"></span>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/chrome/common/extensions/docs/examples/extensions/news_a11y.zip b/chrome/common/extensions/docs/examples/extensions/news_a11y.zip
index 77af95a..7a98522 100644
--- a/chrome/common/extensions/docs/examples/extensions/news_a11y.zip
+++ b/chrome/common/extensions/docs/examples/extensions/news_a11y.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/news_i18n.zip b/chrome/common/extensions/docs/examples/extensions/news_i18n.zip
index 899e6fc..212a07b 100644
--- a/chrome/common/extensions/docs/examples/extensions/news_i18n.zip
+++ b/chrome/common/extensions/docs/examples/extensions/news_i18n.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/oauth_contacts.zip b/chrome/common/extensions/docs/examples/extensions/oauth_contacts.zip
index 976cfbe..a8d23ea 100644
--- a/chrome/common/extensions/docs/examples/extensions/oauth_contacts.zip
+++ b/chrome/common/extensions/docs/examples/extensions/oauth_contacts.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/extensions/wave.zip b/chrome/common/extensions/docs/examples/extensions/wave.zip
index ad1e104..32f3231 100644
--- a/chrome/common/extensions/docs/examples/extensions/wave.zip
+++ b/chrome/common/extensions/docs/examples/extensions/wave.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/howto/contentscript_xhr.zip b/chrome/common/extensions/docs/examples/howto/contentscript_xhr.zip
index 13be5bd..d97c922 100644
--- a/chrome/common/extensions/docs/examples/howto/contentscript_xhr.zip
+++ b/chrome/common/extensions/docs/examples/howto/contentscript_xhr.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/analytics.zip b/chrome/common/extensions/docs/examples/tutorials/analytics.zip
index c4ae155..a001283 100644
--- a/chrome/common/extensions/docs/examples/tutorials/analytics.zip
+++ b/chrome/common/extensions/docs/examples/tutorials/analytics.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/examples/tutorials/getstarted.zip b/chrome/common/extensions/docs/examples/tutorials/getstarted.zip
index b5f5add..268cc5d 100644
--- a/chrome/common/extensions/docs/examples/tutorials/getstarted.zip
+++ b/chrome/common/extensions/docs/examples/tutorials/getstarted.zip
Binary files differ
diff --git a/chrome/common/extensions/docs/experimental.clipboard.html b/chrome/common/extensions/docs/experimental.clipboard.html
index dc9d20b..b54b3ba 100644
--- a/chrome/common/extensions/docs/experimental.clipboard.html
+++ b/chrome/common/extensions/docs/experimental.clipboard.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.contextMenus.html b/chrome/common/extensions/docs/experimental.contextMenus.html
index 5c11ce2..d709193 100644
--- a/chrome/common/extensions/docs/experimental.contextMenus.html
+++ b/chrome/common/extensions/docs/experimental.contextMenus.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.cookies.html b/chrome/common/extensions/docs/experimental.cookies.html
index b57ea7f..48e25ae 100644
--- a/chrome/common/extensions/docs/experimental.cookies.html
+++ b/chrome/common/extensions/docs/experimental.cookies.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.history.html b/chrome/common/extensions/docs/experimental.history.html
index 7a2deda..498667c 100644
--- a/chrome/common/extensions/docs/experimental.history.html
+++ b/chrome/common/extensions/docs/experimental.history.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.html b/chrome/common/extensions/docs/experimental.html
index 3fe2e15..6fec780 100644
--- a/chrome/common/extensions/docs/experimental.html
+++ b/chrome/common/extensions/docs/experimental.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
@@ -304,7 +312,6 @@ on the following experimental APIs:
<li>
<a href="experimental.clipboard.html">experimental.clipboard</a></li><li>
<a href="experimental.infobars.html">experimental.infobars</a></li><li>
- <a href="experimental.omnibox.html">experimental.omnibox</a></li><li>
<a href="experimental.processes.html">experimental.processes</a></li><li>
<a href="experimental.proxy.html">experimental.proxy</a></li><li>
<a href="experimental.sidebar.html">experimental.sidebar</a></li><li>
diff --git a/chrome/common/extensions/docs/experimental.idle.html b/chrome/common/extensions/docs/experimental.idle.html
index 7712706..58e0b9d 100644
--- a/chrome/common/extensions/docs/experimental.idle.html
+++ b/chrome/common/extensions/docs/experimental.idle.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.infobars.html b/chrome/common/extensions/docs/experimental.infobars.html
index 0c9295d..4a76122 100644
--- a/chrome/common/extensions/docs/experimental.infobars.html
+++ b/chrome/common/extensions/docs/experimental.infobars.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.omnibox.html b/chrome/common/extensions/docs/experimental.omnibox.html
index 1a668ed..69ad86e 100644
--- a/chrome/common/extensions/docs/experimental.omnibox.html
+++ b/chrome/common/extensions/docs/experimental.omnibox.html
@@ -16,7 +16,7 @@
<script type="text/javascript" src="js/api_page_generator.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<script type="text/javascript" src="js/sidebar.js"></script>
- <title>chrome.experimental.omnibox - Google Chrome Extensions - Google Code</title></head>
+ <title>Experimental.omnibox - Google Chrome Extensions - Google Code</title></head>
<body> <div id="gc-container" class="labs">
<div id="devModeWarning">
You are viewing extension docs in chrome via the 'file:' scheme: are you expecting to see local changes when you refresh? You'll need run chrome with --allow-file-access-from-files.
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
@@ -232,31 +240,24 @@
<div class="g-unit" id="gc-pagecontent">
<div id="pageTitle">
- <h1 class="page_title">chrome.experimental.omnibox</h1>
+ <h1 class="page_title">Experimental.omnibox</h1>
</div>
<!-- TABLE OF CONTENTS -->
- <div id="toc">
+ <div id="toc" style="display: none; ">
<h2>Contents</h2>
<ol>
<li>
- <a href="#manifest">Manifest</a>
- <ol>
- <li style="display: none; ">
- <a>h3Name</a>
- </li>
- </ol>
- </li><li>
- <a href="#examples">Examples</a>
+ <a>h2Name</a>
<ol>
- <li style="display: none; ">
+ <li>
<a>h3Name</a>
</li>
</ol>
</li>
<li>
- <a href="#apiReference">API reference: chrome.experimental.omnibox</a>
+ <a href="#apiReference">API reference</a>
<ol>
- <li style="display: none; ">
+ <li>
<a href="#properties">Properties</a>
<ol>
<li>
@@ -267,16 +268,8 @@
<li>
<a href="#methods">Methods</a>
<ol>
- <li style="display: none; ">
+ <li>
<a href="#method-anchor">methodName</a>
- </li><li>
- <a href="#method-styleDim">styleDim</a>
- </li><li>
- <a href="#method-styleMatch">styleMatch</a>
- </li><li>
- <a href="#method-styleNone">styleNone</a>
- </li><li>
- <a href="#method-styleUrl">styleUrl</a>
</li>
</ol>
</li>
@@ -284,13 +277,7 @@
<a href="#events">Events</a>
<ol>
<li>
- <a href="#event-onInputCancelled">onInputCancelled</a>
- </li><li>
- <a href="#event-onInputChanged">onInputChanged</a>
- </li><li>
- <a href="#event-onInputEntered">onInputEntered</a>
- </li><li>
- <a href="#event-onInputStarted">onInputStarted</a>
+ <a href="#event-anchor">eventName</a>
</li>
</ol>
</li>
@@ -298,7 +285,7 @@
<a href="#types">Types</a>
<ol>
<li>
- <a href="#type-SuggestResult">SuggestResult</a>
+ <a href="#id-anchor">id</a>
</li>
</ol>
</li>
@@ -309,7 +296,7 @@
<!-- /TABLE OF CONTENTS -->
<!-- Standard content lead-in for experimental API pages -->
- <p id="classSummary">
+ <p id="classSummary" style="display: none; ">
For information on how to use experimental APIs, see the <a href="experimental.html">chrome.experimental.* APIs</a> page.
</p>
@@ -388,12 +375,12 @@ You can find samples of this API on the
</p></div>
<!-- API PAGE -->
- <div class="apiPage">
+ <div class="apiPage" style="display: none; ">
<a name="apiReference"></a>
- <h2>API reference: chrome.experimental.omnibox</h2>
+ <h2>API reference: chrome.apiname </h2>
<!-- PROPERTIES -->
- <div class="apiGroup" style="display: none; ">
+ <div class="apiGroup">
<a name="properties"></a>
<h3 id="properties">Properties</h3>
@@ -416,7 +403,7 @@ You can find samples of this API on the
<h3>Methods</h3>
<!-- iterates over all functions -->
- <div class="apiItem" style="display: none; ">
+ <div class="apiItem">
<a></a> <!-- method-anchor -->
<h4>method name</h4>
@@ -482,490 +469,6 @@ You can find samples of this API on the
</p>
</div> <!-- /description -->
- </div><div class="apiItem">
- <a name="method-styleDim"></a> <!-- method-anchor -->
- <h4>styleDim</h4>
-
- <div class="summary"><span style="display: none; ">void</span>
- <!-- Note: intentionally longer 80 columns -->
- <span>chrome.experimental.omnibox.styleDim</span>(<span class="null"><span style="display: none; ">, </span><span>integer</span>
- <var><span>offset</span></var></span>)</div>
-
- <div class="description">
- <p class="todo" style="display: none; ">Undocumented.</p>
- <p>Constructor for the descriptionStyles parameter of the suggest callback. This style designates a region of dim helper text.</p>
-
- <!-- PARAMETERS -->
- <h4>Parameters</h4>
- <dl>
- <div>
- <div>
- <dt>
- <var>offset</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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 style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo">
- Undocumented.
- </dd>
- <dd style="display: none; ">
- Description of this parameter from the json schema.
- </dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div>
- </dl>
-
- <!-- RETURNS -->
- <h4 style="display: none; ">Returns</h4>
- <dl>
- <div style="display: none; ">
- <div>
- </div>
- </div>
- </dl>
-
- <!-- CALLBACK -->
- <div style="display: none; ">
- <div>
- <h4>Callback function</h4>
- <p>
- The callback <em>parameter</em> should specify a function
- that looks like this:
- </p>
- <p>
- If you specify the <em>callback</em> parameter, it should
- specify a function that looks like this:
- </p>
-
- <!-- Note: intentionally longer 80 columns -->
- <pre>function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>;</pre>
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </div>
- </div>
-
- <!-- MIN_VERSION -->
- <p style="display: none; ">
- This function was added in version <b><span></span></b>.
- If you require this function, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </p>
- </div> <!-- /description -->
-
- </div><div class="apiItem">
- <a name="method-styleMatch"></a> <!-- method-anchor -->
- <h4>styleMatch</h4>
-
- <div class="summary"><span style="display: none; ">void</span>
- <!-- Note: intentionally longer 80 columns -->
- <span>chrome.experimental.omnibox.styleMatch</span>(<span class="null"><span style="display: none; ">, </span><span>integer</span>
- <var><span>offset</span></var></span>)</div>
-
- <div class="description">
- <p class="todo" style="display: none; ">Undocumented.</p>
- <p>Constructor for the descriptionStyles parameter of the suggest callback. This style designates a region of text matching what the user typed.</p>
-
- <!-- PARAMETERS -->
- <h4>Parameters</h4>
- <dl>
- <div>
- <div>
- <dt>
- <var>offset</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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 style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo">
- Undocumented.
- </dd>
- <dd style="display: none; ">
- Description of this parameter from the json schema.
- </dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div>
- </dl>
-
- <!-- RETURNS -->
- <h4 style="display: none; ">Returns</h4>
- <dl>
- <div style="display: none; ">
- <div>
- </div>
- </div>
- </dl>
-
- <!-- CALLBACK -->
- <div style="display: none; ">
- <div>
- <h4>Callback function</h4>
- <p>
- The callback <em>parameter</em> should specify a function
- that looks like this:
- </p>
- <p>
- If you specify the <em>callback</em> parameter, it should
- specify a function that looks like this:
- </p>
-
- <!-- Note: intentionally longer 80 columns -->
- <pre>function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>;</pre>
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </div>
- </div>
-
- <!-- MIN_VERSION -->
- <p style="display: none; ">
- This function was added in version <b><span></span></b>.
- If you require this function, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </p>
- </div> <!-- /description -->
-
- </div><div class="apiItem">
- <a name="method-styleNone"></a> <!-- method-anchor -->
- <h4>styleNone</h4>
-
- <div class="summary"><span style="display: none; ">void</span>
- <!-- Note: intentionally longer 80 columns -->
- <span>chrome.experimental.omnibox.styleNone</span>(<span class="null"><span style="display: none; ">, </span><span>integer</span>
- <var><span>offset</span></var></span>)</div>
-
- <div class="description">
- <p class="todo" style="display: none; ">Undocumented.</p>
- <p>Constructor for the descriptionStyles parameter of the suggest callback.</p>
-
- <!-- PARAMETERS -->
- <h4>Parameters</h4>
- <dl>
- <div>
- <div>
- <dt>
- <var>offset</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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 style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo">
- Undocumented.
- </dd>
- <dd style="display: none; ">
- Description of this parameter from the json schema.
- </dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div>
- </dl>
-
- <!-- RETURNS -->
- <h4 style="display: none; ">Returns</h4>
- <dl>
- <div style="display: none; ">
- <div>
- </div>
- </div>
- </dl>
-
- <!-- CALLBACK -->
- <div style="display: none; ">
- <div>
- <h4>Callback function</h4>
- <p>
- The callback <em>parameter</em> should specify a function
- that looks like this:
- </p>
- <p>
- If you specify the <em>callback</em> parameter, it should
- specify a function that looks like this:
- </p>
-
- <!-- Note: intentionally longer 80 columns -->
- <pre>function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>;</pre>
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </div>
- </div>
-
- <!-- MIN_VERSION -->
- <p style="display: none; ">
- This function was added in version <b><span></span></b>.
- If you require this function, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </p>
- </div> <!-- /description -->
-
- </div><div class="apiItem">
- <a name="method-styleUrl"></a> <!-- method-anchor -->
- <h4>styleUrl</h4>
-
- <div class="summary"><span style="display: none; ">void</span>
- <!-- Note: intentionally longer 80 columns -->
- <span>chrome.experimental.omnibox.styleUrl</span>(<span class="null"><span style="display: none; ">, </span><span>integer</span>
- <var><span>offset</span></var></span>)</div>
-
- <div class="description">
- <p class="todo" style="display: none; ">Undocumented.</p>
- <p>Constructor for the descriptionStyles parameter of the suggest callback. This style designates a region of text matching a URL or filename.</p>
-
- <!-- PARAMETERS -->
- <h4>Parameters</h4>
- <dl>
- <div>
- <div>
- <dt>
- <var>offset</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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 style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo">
- Undocumented.
- </dd>
- <dd style="display: none; ">
- Description of this parameter from the json schema.
- </dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div>
- </dl>
-
- <!-- RETURNS -->
- <h4 style="display: none; ">Returns</h4>
- <dl>
- <div style="display: none; ">
- <div>
- </div>
- </div>
- </dl>
-
- <!-- CALLBACK -->
- <div style="display: none; ">
- <div>
- <h4>Callback function</h4>
- <p>
- The callback <em>parameter</em> should specify a function
- that looks like this:
- </p>
- <p>
- If you specify the <em>callback</em> parameter, it should
- specify a function that looks like this:
- </p>
-
- <!-- Note: intentionally longer 80 columns -->
- <pre>function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>;</pre>
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </div>
- </div>
-
- <!-- MIN_VERSION -->
- <p style="display: none; ">
- This function was added in version <b><span></span></b>.
- If you require this function, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </p>
- </div> <!-- /description -->
-
</div> <!-- /apiItem -->
</div> <!-- /apiGroup -->
@@ -977,401 +480,25 @@ You can find samples of this API on the
<!-- iterates over all events -->
<div class="apiItem">
- <a name="event-onInputCancelled"></a>
- <h4>onInputCancelled</h4>
-
- <div class="summary">
- <!-- Note: intentionally longer 80 columns -->
- <span class="subdued">chrome.experimental.omnibox.</span><span>onInputCancelled</span><span class="subdued">.addListener</span>(function(<span></span>) <span class="subdued">{...}</span>);
- </div>
-
- <div class="description">
- <p class="todo" style="display: none; ">Undocumented.</p>
- <p>User has ended the keyword input session without accepting the input.</p>
-
- <!-- PARAMETERS -->
- <h4>Parameters</h4>
- <dl>
- <div style="display: none; ">
- <div>
- </div>
- </div>
- </dl>
-
- </div> <!-- /decription -->
-
- </div><div class="apiItem">
- <a name="event-onInputChanged"></a>
- <h4>onInputChanged</h4>
-
- <div class="summary">
- <!-- Note: intentionally longer 80 columns -->
- <span class="subdued">chrome.experimental.omnibox.</span><span>onInputChanged</span><span class="subdued">.addListener</span>(function(<span>string text, function suggest</span>) <span class="subdued">{...}</span>);
- </div>
-
- <div class="description">
- <p class="todo" style="display: none; ">Undocumented.</p>
- <p>User has changed what is typed into the omnibox.</p>
-
- <!-- PARAMETERS -->
- <h4>Parameters</h4>
- <dl>
- <div>
- <div>
- <dt>
- <var>text</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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>string</span>
- <span style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo">
- Undocumented.
- </dd>
- <dd style="display: none; ">
- Description of this parameter from the json schema.
- </dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div><div>
- <div>
- <dt>
- <var>suggest</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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>function</span>
- <span style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo" style="display: none; ">
- Undocumented.
- </dd>
- <dd>A callback passed to the onInputChanged event used for sending suggestions back to the browser.</dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd>
- <div>
- <h5>Parameters</h5>
- <dl>
- <div>
- <div>
- <dt>
- <var>requestId</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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 style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo">
- Undocumented.
- </dd>
- <dd style="display: none; ">
- Description of this parameter from the json schema.
- </dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div><div>
- <div>
- <dt>
- <var style="display: none; ">paramName</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</span>
- <span id="typeTemplate">
- <span style="display: none; ">
- <a> Type</a>
- </span>
- <span>
- <span>
- array of <span><span>
- <span>
- <a href="experimental.omnibox.html#type-SuggestResult">SuggestResult</a>
- </span>
- <span style="display: none; ">
- <span>
- array of <span><span></span></span>
- </span>
- <span>paramType</span>
- <span></span>
- </span>
- </span></span>
- </span>
- <span style="display: none; ">paramType</span>
- <span style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo" style="display: none; ">
- Undocumented.
- </dd>
- <dd>Array of suggest results</dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div>
- </dl>
- </div>
- </dd>
-
- </div>
- </div>
- </dl>
-
- </div> <!-- /decription -->
-
- </div><div class="apiItem">
- <a name="event-onInputEntered"></a>
- <h4>onInputEntered</h4>
+ <a></a>
+ <h4>event name</h4>
<div class="summary">
<!-- Note: intentionally longer 80 columns -->
- <span class="subdued">chrome.experimental.omnibox.</span><span>onInputEntered</span><span class="subdued">.addListener</span>(function(<span>string text</span>) <span class="subdued">{...}</span>);
+ <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>);
</div>
<div class="description">
- <p class="todo" style="display: none; ">Undocumented.</p>
- <p>User has accepted what is typed into the omnibox.</p>
+ <p class="todo">Undocumented.</p>
+ <p>
+ A description from the json schema def of the event goes here.
+ </p>
<!-- PARAMETERS -->
<h4>Parameters</h4>
<dl>
<div>
<div>
- <dt>
- <var>text</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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>string</span>
- <span style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo">
- Undocumented.
- </dd>
- <dd style="display: none; ">
- Description of this parameter from the json schema.
- </dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div>
- </dl>
-
- </div> <!-- /decription -->
-
- </div><div class="apiItem">
- <a name="event-onInputStarted"></a>
- <h4>onInputStarted</h4>
-
- <div class="summary">
- <!-- Note: intentionally longer 80 columns -->
- <span class="subdued">chrome.experimental.omnibox.</span><span>onInputStarted</span><span class="subdued">.addListener</span>(function(<span></span>) <span class="subdued">{...}</span>);
- </div>
-
- <div class="description">
- <p class="todo" style="display: none; ">Undocumented.</p>
- <p>User has started a keyword input session by typing the extension's keyword. This is guaranteed to be sent exactly once per input session, and before any onInputChanged events.</p>
-
- <!-- PARAMETERS -->
- <h4>Parameters</h4>
- <dl>
- <div style="display: none; ">
- <div>
</div>
</div>
</dl>
@@ -1389,250 +516,11 @@ You can find samples of this API on the
<!-- iterates over all types -->
<div class="apiItem">
- <a name="type-SuggestResult"></a>
- <h4>SuggestResult</h4>
-
- <div>
- <dt>
- <var style="display: none; ">paramName</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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 style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo" style="display: none; ">
- Undocumented.
- </dd>
- <dd>A suggest result.</dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd>
- <dl>
- <div>
- <div>
- <dt>
- <var>content</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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>string</span>
- <span style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo" style="display: none; ">
- Undocumented.
- </dd>
- <dd>The text that is put into the URL bar, and that is sent to the extension when the user chooses this entry.</dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div><div>
- <div>
- <dt>
- <var>description</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional" style="display: none; ">optional</span>
- <span class="enum" style="display: none; ">enumerated</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>string</span>
- <span style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo" style="display: none; ">
- Undocumented.
- </dd>
- <dd>The text that is displayed in the URL dropdown. Can optionally be stylized by the descriptionStyles parameter.</dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
-
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
- <div>
- <div>
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div><div>
- <div>
- <dt>
- <var>descriptionStyles</var>
- <em>
-
- <!-- TYPE -->
- <div style="display:inline">
- (
- <span class="optional">optional</span>
- <span class="enum" style="display: none; ">enumerated</span>
- <span id="typeTemplate">
- <span style="display: none; ">
- <a> Type</a>
- </span>
- <span>
- <span>
- array of <span><span>
- <span style="display: none; ">
- <a> Type</a>
- </span>
- <span>
- <span style="display: none; ">
- array of <span><span></span></span>
- </span>
- <span>object</span>
- <span style="display: none; "></span>
- </span>
- </span></span>
- </span>
- <span style="display: none; ">paramType</span>
- <span style="display: none; "></span>
- </span>
- </span>
- )
- </div>
-
- </em>
- </dt>
- <dd class="todo">
- Undocumented.
- </dd>
- <dd style="display: none; ">
- Description of this parameter from the json schema.
- </dd>
- <dd style="display: none; ">
- This parameter was added in version
- <b><span></span></b>.
- You must omit this parameter in earlier versions,
- and you may omit it in any version. If you require this
- parameter, the manifest key
- <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
- can ensure that your extension won't be run in an earlier browser version.
- </dd>
+ <a></a>
+ <h4>type name</h4>
- <!-- OBJECT PROPERTIES -->
- <dd style="display: none; ">
- <dl>
<div>
- <div>
- </div>
</div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
- </div>
- </dl>
- </dd>
-
- <!-- FUNCTION PARAMETERS -->
- <dd style="display: none; ">
- <div></div>
- </dd>
-
- </div>
</div> <!-- /apiItem -->
diff --git a/chrome/common/extensions/docs/experimental.processes.html b/chrome/common/extensions/docs/experimental.processes.html
index a5e3b05..06997aa 100644
--- a/chrome/common/extensions/docs/experimental.processes.html
+++ b/chrome/common/extensions/docs/experimental.processes.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.proxy.html b/chrome/common/extensions/docs/experimental.proxy.html
index 3d27695..08eb220 100644
--- a/chrome/common/extensions/docs/experimental.proxy.html
+++ b/chrome/common/extensions/docs/experimental.proxy.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.sidebar.html b/chrome/common/extensions/docs/experimental.sidebar.html
index 35b757b..45d5f59 100644
--- a/chrome/common/extensions/docs/experimental.sidebar.html
+++ b/chrome/common/extensions/docs/experimental.sidebar.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.webNavigation.html b/chrome/common/extensions/docs/experimental.webNavigation.html
index aebd5ca..4d40227 100644
--- a/chrome/common/extensions/docs/experimental.webNavigation.html
+++ b/chrome/common/extensions/docs/experimental.webNavigation.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/experimental.webRequest.html b/chrome/common/extensions/docs/experimental.webRequest.html
index 0541584..8f2c52f 100644
--- a/chrome/common/extensions/docs/experimental.webRequest.html
+++ b/chrome/common/extensions/docs/experimental.webRequest.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/extension.html b/chrome/common/extensions/docs/extension.html
index 36c768f..dc5beda 100644
--- a/chrome/common/extensions/docs/extension.html
+++ b/chrome/common/extensions/docs/extension.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
@@ -276,6 +284,8 @@
<a href="#method-getViews">getViews</a>
</li><li>
<a href="#method-sendRequest">sendRequest</a>
+ </li><li>
+ <a href="#method-setUpdateUrlData">setUpdateUrlData</a>
</li>
</ol>
</li>
@@ -851,7 +861,7 @@ For details, see
<dd class="todo" style="display: none; ">
Undocumented.
</dd>
- <dd>Port through which messages can be sent and received with the extension.</dd>
+ <dd>Port through which messages can be sent and received with the extension. The port's <a href="extension.html#type-Port">onDisconnect</a> event is fired if extension does not exist. </dd>
<dd style="display: none; ">
This parameter was added in version
<b><span></span></b>.
@@ -1654,7 +1664,7 @@ For details, see
<div class="description">
<p class="todo" style="display: none; ">Undocumented.</p>
- <p>Sends a single request to other listeners within the extension. Similar to chrome.extension.connect, but only sends a single request with an optional response.</p>
+ <p>Sends a single request to other listeners within the extension. Similar to chrome.extension.connect, but only sends a single request with an optional response. The <a href="extension.html#event-onRequest">chrome.extension.onRequest</a> event is fired in each page of the extension.</p>
<!-- PARAMETERS -->
<h4>Parameters</h4>
@@ -1867,7 +1877,7 @@ For details, see
<dd class="todo" style="display: none; ">
Undocumented.
</dd>
- <dd>The JSON response object sent by the handler of the request.</dd>
+ <dd>The JSON response object sent by the handler of the request. If an error occurs while connecting to the extension, the callback will be called with no arguments and <a href="extension.html#property-lastError">chrome.extension.lastError</a> will be set to the error message.</dd>
<dd style="display: none; ">
This parameter was added in version
<b><span></span></b>.
@@ -1959,7 +1969,7 @@ For details, see
<dd class="todo" style="display: none; ">
Undocumented.
</dd>
- <dd>The JSON response object sent by the handler of the request.</dd>
+ <dd>The JSON response object sent by the handler of the request. If an error occurs while connecting to the extension, the callback will be called with no arguments and <a href="extension.html#property-lastError">chrome.extension.lastError</a> will be set to the error message.</dd>
<dd style="display: none; ">
This parameter was added in version
<b><span></span></b>.
@@ -2000,6 +2010,127 @@ For details, see
</p>
</div> <!-- /description -->
+ </div><div class="apiItem">
+ <a name="method-setUpdateUrlData"></a> <!-- method-anchor -->
+ <h4>setUpdateUrlData</h4>
+
+ <div class="summary"><span style="display: none; ">void</span>
+ <!-- Note: intentionally longer 80 columns -->
+ <span>chrome.extension.setUpdateUrlData</span>(<span class="null"><span style="display: none; ">, </span><span>string</span>
+ <var><span>data</span></var></span>)</div>
+
+ <div class="description">
+ <p class="todo" style="display: none; ">Undocumented.</p>
+ <p>Sets the value of the ap CGI parameter used in the extension's update URL. This value is ignored for extensions that are hosted in the Chrome Extension Gallery.</p>
+
+ <!-- PARAMETERS -->
+ <h4>Parameters</h4>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>data</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional" style="display: none; ">optional</span>
+ <span class="enum" style="display: none; ">enumerated</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>string</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo">
+ Undocumented.
+ </dd>
+ <dd style="display: none; ">
+ Description of this parameter from the json schema.
+ </dd>
+ <dd style="display: none; ">
+ This parameter was added in version
+ <b><span></span></b>.
+ You must omit this parameter in earlier versions,
+ and you may omit it in any version. If you require this
+ parameter, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd style="display: none; ">
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </dd>
+
+ <!-- FUNCTION PARAMETERS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ </div>
+ </div>
+ </dl>
+
+ <!-- RETURNS -->
+ <h4 style="display: none; ">Returns</h4>
+ <dl>
+ <div style="display: none; ">
+ <div>
+ </div>
+ </div>
+ </dl>
+
+ <!-- CALLBACK -->
+ <div style="display: none; ">
+ <div>
+ <h4>Callback function</h4>
+ <p>
+ The callback <em>parameter</em> should specify a function
+ that looks like this:
+ </p>
+ <p>
+ If you specify the <em>callback</em> parameter, it should
+ specify a function that looks like this:
+ </p>
+
+ <!-- Note: intentionally longer 80 columns -->
+ <pre>function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>;</pre>
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </div>
+ </div>
+
+ <!-- MIN_VERSION -->
+ <p style="display: none; ">
+ This function was added in version <b><span></span></b>.
+ If you require this function, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </p>
+ </div> <!-- /description -->
+
</div> <!-- /apiItem -->
</div> <!-- /apiGroup -->
diff --git a/chrome/common/extensions/docs/external_extensions.html b/chrome/common/extensions/docs/external_extensions.html
index d3f18ad..fb9dcab 100644
--- a/chrome/common/extensions/docs/external_extensions.html
+++ b/chrome/common/extensions/docs/external_extensions.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/faq.html b/chrome/common/extensions/docs/faq.html
index ea4af3a..5e0617b 100644
--- a/chrome/common/extensions/docs/faq.html
+++ b/chrome/common/extensions/docs/faq.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/getstarted.html b/chrome/common/extensions/docs/getstarted.html
index 5590e32..b8fc043 100644
--- a/chrome/common/extensions/docs/getstarted.html
+++ b/chrome/common/extensions/docs/getstarted.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/history.html b/chrome/common/extensions/docs/history.html
index 5fed0af..ebcfa6d 100644
--- a/chrome/common/extensions/docs/history.html
+++ b/chrome/common/extensions/docs/history.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/hosting.html b/chrome/common/extensions/docs/hosting.html
index 55c0178..19ccde8 100644
--- a/chrome/common/extensions/docs/hosting.html
+++ b/chrome/common/extensions/docs/hosting.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/i18n-messages.html b/chrome/common/extensions/docs/i18n-messages.html
index 823bfc3..ebb1432 100644
--- a/chrome/common/extensions/docs/i18n-messages.html
+++ b/chrome/common/extensions/docs/i18n-messages.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/i18n.html b/chrome/common/extensions/docs/i18n.html
index b33c856..cfdd957 100644
--- a/chrome/common/extensions/docs/i18n.html
+++ b/chrome/common/extensions/docs/i18n.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/idle.html b/chrome/common/extensions/docs/idle.html
index 0d6988c..a0e97d1 100644
--- a/chrome/common/extensions/docs/idle.html
+++ b/chrome/common/extensions/docs/idle.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/index.html b/chrome/common/extensions/docs/index.html
index 12e3114..6dfc1fb 100644
--- a/chrome/common/extensions/docs/index.html
+++ b/chrome/common/extensions/docs/index.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li class="leftNavSelected">Chrome Web Store</li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/management.html b/chrome/common/extensions/docs/management.html
index 2792019..2c4b4a8 100644
--- a/chrome/common/extensions/docs/management.html
+++ b/chrome/common/extensions/docs/management.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/manifest.html b/chrome/common/extensions/docs/manifest.html
index b593f31..be0dfbb 100644
--- a/chrome/common/extensions/docs/manifest.html
+++ b/chrome/common/extensions/docs/manifest.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/match_patterns.html b/chrome/common/extensions/docs/match_patterns.html
index 9a58c28..5ad8e75 100644
--- a/chrome/common/extensions/docs/match_patterns.html
+++ b/chrome/common/extensions/docs/match_patterns.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/messaging.html b/chrome/common/extensions/docs/messaging.html
index 343f987..2871fa0 100644
--- a/chrome/common/extensions/docs/messaging.html
+++ b/chrome/common/extensions/docs/messaging.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/notifications.html b/chrome/common/extensions/docs/notifications.html
index 6732897..e705b9d 100644
--- a/chrome/common/extensions/docs/notifications.html
+++ b/chrome/common/extensions/docs/notifications.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/npapi.html b/chrome/common/extensions/docs/npapi.html
index c622beb..8302ab3 100644
--- a/chrome/common/extensions/docs/npapi.html
+++ b/chrome/common/extensions/docs/npapi.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/options.html b/chrome/common/extensions/docs/options.html
index 9b469ff..cbfb4bd 100644
--- a/chrome/common/extensions/docs/options.html
+++ b/chrome/common/extensions/docs/options.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/override.html b/chrome/common/extensions/docs/override.html
index 0701ea0..0eec1ba 100644
--- a/chrome/common/extensions/docs/override.html
+++ b/chrome/common/extensions/docs/override.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/overview.html b/chrome/common/extensions/docs/overview.html
index 714aa26..1180ff9 100644
--- a/chrome/common/extensions/docs/overview.html
+++ b/chrome/common/extensions/docs/overview.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/packaging.html b/chrome/common/extensions/docs/packaging.html
index 6c20134..58b1a9b 100644
--- a/chrome/common/extensions/docs/packaging.html
+++ b/chrome/common/extensions/docs/packaging.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/pageAction.html b/chrome/common/extensions/docs/pageAction.html
index 302279c..17212b7 100644
--- a/chrome/common/extensions/docs/pageAction.html
+++ b/chrome/common/extensions/docs/pageAction.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/permission_warnings.html b/chrome/common/extensions/docs/permission_warnings.html
index 22370e0..1d77c36 100644
--- a/chrome/common/extensions/docs/permission_warnings.html
+++ b/chrome/common/extensions/docs/permission_warnings.html
@@ -95,7 +95,11 @@
<div>
</div>
</div>
+<<<<<<< HEAD
</dl>
+=======
+ </dl>
+>>>>>>> chromium.org at r66597
</div>
</div> <!-- /SUBTEMPLATES -->
@@ -223,7 +227,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/samples.html b/chrome/common/extensions/docs/samples.html
index 21ff76e..368c2c0 100644
--- a/chrome/common/extensions/docs/samples.html
+++ b/chrome/common/extensions/docs/samples.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
@@ -294,7 +302,7 @@
<!-- STATIC CONTENT PLACEHOLDER -->
<div id="static"><link rel="stylesheet" href="css/samples.css">
-<script>var search_data = {"0262260daf0c8f7b28feff2ef23b05e7abf9d1e0":"A BROWSER ACTION WHICH CHANGES ITS ICON WHEN CLICKED. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON","ea2894c41cb8e80a4433a3e6c5772dadce9be90d":"A BROWSER ACTION WITH A POPUP THAT CHANGES THE PAGE COLOR. BROWSER_ACTION POPUP TABS CHROME.TABS.EXECUTESCRIPT","ede3c47b7757245be42ec33fd5ca63df4b490066":"A BROWSER ACTION WITH NO ICON THAT MAKES THE PAGE RED BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.EXECUTESCRIPT","fbf0aa1a09a15ff8cc4fc7de4fd176d6c663d07a":"ACCEPTLANGUAGE RETURNS ACCEPT LANGUAGES OF THE BROWSER BROWSER_ACTION POPUP CHROME.I18N.GETACCEPTLANGUAGES CHROME.I18N.GETMESSAGE","9a6e4ec46997fb92b324974afa08a3d007e2537f":"ANIMATED PAGE ACTION THIS EXTENSION ADDS AN ANIMATED BROWSER ACTION TO THE TOOLBAR. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.ONCLICKED CHROME.PAGEACTION.SETICON CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED","9747e3d6a3eab39bc7c17f11a80573c62d44c7e5":"BLANK NEW TAB PAGE CHROME_URL_OVERRIDES","903e7277139e1e6caec123d3319cab295d8d1b3a":"CHROME SOUNDS ENJOY A MORE MAGICAL AND IMMERSIVE EXPERIENCE WHEN BROWSING THE WEB USING THE POWER OF SOUND. BACKGROUND_PAGE BOOKMARKS OPTIONS_PAGE TABS CHROME.BOOKMARKS.ONCREATED CHROME.BOOKMARKS.ONMOVED CHROME.BOOKMARKS.ONREMOVED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.TABS.GET CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED","0e790e035a4a00b6f1def5ef9a7d7be1bce95ab5":"CHROMIUM BUILDBOT MONITOR DISPLAYS THE STATUS OF THE CHROMIUM BUILDBOT IN THE TOOLBAR. CLICK TO SEE MORE DETAILED STATUS IN A POPUP. BACKGROUND_PAGE BROWSER_ACTION NOTIFICATIONS OPTIONS_PAGE POPUP CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.GETURL","ac31228200b41a87982e386cc90d3a6eee4ad885":"CHROMIUM SEARCH ADD SUPPORT TO THE OMNIBOX TO SEARCH THE CHROMIUM SOURCE CODE. BACKGROUND_PAGE EXPERIMENTAL TABS CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED CHROME.EXPERIMENTAL.OMNIBOX.STYLEMATCH CHROME.EXPERIMENTAL.OMNIBOX.STYLENONE CHROME.EXPERIMENTAL.OMNIBOX.STYLEURL CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE","7d5d6cf195bc25480256618e360aa38c6e6fba82":"CLD DISPLAYS THE LANGUAGE OF A TAB BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.DETECTLANGUAGE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED","5d81304a17cf7ac2887484f730fbd2b01e51e166":"CONTEXT MENUS SAMPLE SHOWS SOME OF THE FEATURES OF THE CONTEXT MENUS API BACKGROUND_PAGE CONTEXTMENUS CHROME.CONTEXTMENUS.CREATE","4daa6becd0899a54776d9cf7f09613ed1a9f4d77":"COOKIE API TEST EXTENSION TESTING COOKIE API BACKGROUND_PAGE BROWSER_ACTION COOKIES TABS CHROME.BROWSERACTION.ONCLICKED CHROME.COOKIES.GET CHROME.COOKIES.GETALL CHROME.COOKIES.ONCHANGED CHROME.COOKIES.REMOVE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL","6871d09f4a96bf9d4b6cc724d00e909cee0f3902":"CROSS-DOMAIN XMLHTTPREQUEST FROM A CONTENT SCRIPT DEMONSTRATES A METHOD TO MAKE A CROSS-DOMAIN XMLHTTPREQUEST FETCH FROM A CONTENT SCRIPT. THIS EXTENSION FETCHES THE CURRENT TRENDING TOPICS FROM TWITTER AND INSERTS THEM IN AN OVERLAY AT THE TOP OF GOOGLE NEWS. VISIT HTTP://NEWS.GOOGLE.COM TO TEST THIS EXTENSION. BACKGROUND_PAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST","028eb5364924344029bcbe1d527f132fc72b34e5":"EMAIL THIS PAGE (BY GOOGLE) THIS EXTENSION ADDS AN EMAIL BUTTON TO THE TOOLBAR WHICH ALLOWS YOU TO EMAIL THE PAGE LINK USING YOUR DEFAULT MAIL CLIENT OR GMAIL. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.CONNECT CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.UPDATE","763a08e9b06595d785568a8d392b95a2f3700258":"EVENT TRACKING WITH GOOGLE ANALYTICS A SAMPLE EXTENSION WHICH USES GOOGLE ANALYTICS TO TRACK USAGE. BACKGROUND_PAGE BROWSER_ACTION POPUP","e3df888a89e35bdeb9c8bc8d03be5e1851b97c68":"EXTENSION DOCS SEARCH SEARCH THE CHROME EXTENSIONS DOCUMENTATION. TO USE, TYPE CRDOC PLUS A SEARCH TERM INTO THE OMNIBOX. BACKGROUND_PAGE EXPERIMENTAL TABS CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED CHROME.EXPERIMENTAL.OMNIBOX.STYLEMATCH CHROME.EXPERIMENTAL.OMNIBOX.STYLENONE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.ONREMOVED CHROME.TABS.UPDATE","4e35caa9742fb82dbd628892d23a781614f6eff6":"GOOGLE DOCUMENT LIST VIEWER DEMONSTRATES HOW TO USE OAUTH TO CONNECT THE GOOGLE DOCUMENTS LIST DATA API. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","bb57f7a0132cbeb36ad7e7bb0ab75c21704234ca":"GOOGLE MAIL CHECKER DISPLAYS THE NUMBER OF UNREAD MESSAGES IN YOUR GOOGLE MAIL INBOX. YOU CAN ALSO CLICK THE BUTTON TO OPEN YOUR INBOX. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.ONUPDATED CHROME.TABS.UPDATE","1682e05ea9a1bde985123b04f6f8ac50a8a64033":"GOOGLE WAVE NOTIFIER FIND OUT WHEN YOU HAVE NEW WAVES AND PREVIEW THEM FAST. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","14b9651fda4e57b2a5914ba73a779812201b750a":"HELLO WORLD THE FIRST EXTENSION THAT I MADE. BROWSER_ACTION POPUP","2020d72f2577f53caf8e94e3dbac0fb849ceaa4d":"IDLE - SIMPLE EXAMPLE DEMONSTRATES THE IDLE API BACKGROUND_PAGE BROWSER_ACTION IDLE CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.IDLE.ONSTATECHANGED CHROME.IDLE.QUERYSTATE","0ea1588bd07b20338fc21f725de1542a5fdf9726":"IGOOGLE NEW TAB PAGE CHROME_URL_OVERRIDES","646325c25f572a1d15edc73d057f821d847a4fbe":"IMAGEINFO GET IMAGE INFO FOR IMAGES, INCLUDING EXIF DATA BACKGROUND_PAGE CONTEXTMENUS TABS CHROME.CONTEXTMENUS.CREATE CHROME.TABS.GET CHROME.TABS.GETCURRENT CHROME.WINDOWS.CREATE CHROME.WINDOWS.UPDATE","ec97ec20ca2f095d081e39f1565fc12af09ef067":"MAPPY FINDS ADDRESSES IN THE WEB PAGE YOURE ON AND POPS UP A MAP WINDOW. BACKGROUND_PAGE PAGE_ACTION POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.SENDREQUEST","b2f5f8a790e16f091a7e4e0a39b2d0a6d32e3a6d":"MERGE WINDOWS MERGES ALL OF THE BROWSERS WINDOWS INTO THE CURRENT WINDOW BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.MOVE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT","51a83d2ba3a32e3ff1bdb624d4e18ccec4c4038e":"MESSAGE TIMER TIMES HOW LONG IT TAKES TO SEND A MESSAGE TO A CONTENT SCRIPT AND BACK. BROWSER_ACTION POPUP TABS CHROME.EXTENSION.ONCONNECT CHROME.EXTENSION.ONREQUEST CHROME.TABS.CONNECT CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.SENDREQUEST","4f6785ec4f937add6728615682dd37c9a42d9548":"MY BOOKMARKS A BROWSER ACTION WITH A POPUP DUMP OF ALL BOOKMARKS, INCLUDING SEARCH, ADD, EDIT AND DELETE. BOOKMARKS BROWSER_ACTION POPUP TABS CHROME.BOOKMARKS.CREATE CHROME.BOOKMARKS.GET CHROME.BOOKMARKS.GETTREE CHROME.BOOKMARKS.REMOVE CHROME.BOOKMARKS.UPDATE CHROME.TABS.CREATE","3aea027164cb9b732ba4a8c51cb93708891726ef":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.TABS.CREATE","597015d3bcce3da693b02314afd607bec4f55291":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.TABS.CREATE","6444e5c8ae112a6a433909c5e770669cd16e2e5f":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE","f799e26ceef2367cf836f24bcb47df4398b0df58":"NOTIFICATION DEMO SHOWS OFF DESKTOP NOTIFICATIONS, WHICH ARE TOAST WINDOWS THAT POP UP ON THE DESKTOP. BACKGROUND_PAGE NOTIFICATIONS OPTIONS_PAGE TABS CHROME.TABS.CREATE","e787b322bddbc6289bb31b7d7550b1bf6456a80b":"OMNIBOX EXAMPLE TO USE, TYPE OMNIX PLUS A SEARCH TERM INTO THE OMNIBOX. BACKGROUND_PAGE EXPERIMENTAL CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED","8d0a50b57c26bb498be592e871001ffed91541b4":"PAGE ACTION BY CONTENT SHOWS A PAGE ACTION FOR HTML PAGES CONTAINING THE WORD SANDWICH BACKGROUND_PAGE PAGE_ACTION CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.PAGEACTION.SHOW","80b86ccc6e8520660fa591caa565826f0ed1b12c":"PAGE ACTION BY URL SHOWS A PAGE ACTION FOR URLS WHICH HAVE THE LETTER G IN THEM. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.SHOW CHROME.TABS.ONUPDATED","d74c3c18a1c1dd18b035149105a306f837c8823e":"PAGE BENCHMARKER CHROMIUM PAGE BENCHMARKER. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.CONNECT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETEXTENSIONTABS CHROME.EXTENSION.GETURL CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETCURRENT","e6ae17ab4ccfd7e059c8c01f25760ca5d894c7fd":"PRINT THIS PAGE ADDS A PRINT BUTTON TO THE BROWSER. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.UPDATE","beff6ecd9677dea0a7c648c5042165b48bb66f09":"PROCESS MONITOR ADDS A BROWSER ACTION THAT MONITORS RESOURCE USAGE OF ALL BROWSER PROCESSES. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.ONUPDATED","56a8d2ac24ca7bba78fd88ad57f43fc13c784497":"SAMPLE - OAUTH CONTACTS USES OAUTH TO CONNECT TO GOOGLES CONTACTS SERVICE AND DISPLAY A LIST OF YOUR CONTACTS. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","38f6e1e17756ede38b1364c7114a738ca717dcbb":"SANDWICHBAR SHOWS AN INFOBAR ON PAGES WHICH CONTAIN THE WORD SANDWICH BACKGROUND_PAGE EXPERIMENTAL CHROME.EXPERIMENTAL.INFOBARS.SHOW CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST","fc89b35755483af30b66cd72cefa34a43a3e8312":"SHOW TABS IN PROCESS ADDS A BROWSER ACTION SHOWING WHICH TABS SHARE THE CURRENT TABS PROCESS. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.GETPROCESSIDFORTAB CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.UPDATE","230463f2d5c3d4d0ca13c230e1f00f2aae0a8a64":"TAB INSPECTOR UTILITY FOR WORKING WITH THE EXTENSION TABS API BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.MOVE CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.CREATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.GETLASTFOCUSED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED CHROME.WINDOWS.REMOVE CHROME.WINDOWS.UPDATE","e1697cacebad05218798bf3e8a0f724517f0e8c3":"TEST SCREENSHOT EXTENSION DEMONSTRATE SCREENSHOT FUNCTIONALITY IN THE CHROME.TABS API. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.EXTENSION.GETVIEWS CHROME.TABS.CAPTUREVISIBLETAB CHROME.TABS.CREATE CHROME.TABS.ONUPDATED","b3de91ab04b7d7a2670ca7ee9d740eb42cead0b6":"TYPED URL HISTORY READS YOUR HISTORY, AND SHOWS THE TOP TEN PAGES YOU GO TO BY TYPING THE URL. BROWSER_ACTION HISTORY TABS CHROME.HISTORY.GETVISITS CHROME.HISTORY.SEARCH CHROME.TABS.CREATE"}</script>
+<script>var search_data = {"0262260daf0c8f7b28feff2ef23b05e7abf9d1e0":"A BROWSER ACTION WHICH CHANGES ITS ICON WHEN CLICKED. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON","ea2894c41cb8e80a4433a3e6c5772dadce9be90d":"A BROWSER ACTION WITH A POPUP THAT CHANGES THE PAGE COLOR. BROWSER_ACTION POPUP TABS CHROME.TABS.EXECUTESCRIPT","ede3c47b7757245be42ec33fd5ca63df4b490066":"A BROWSER ACTION WITH NO ICON THAT MAKES THE PAGE RED BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.EXECUTESCRIPT","fbf0aa1a09a15ff8cc4fc7de4fd176d6c663d07a":"ACCEPTLANGUAGE RETURNS ACCEPT LANGUAGES OF THE BROWSER BROWSER_ACTION POPUP CHROME.I18N.GETACCEPTLANGUAGES CHROME.I18N.GETMESSAGE","9a6e4ec46997fb92b324974afa08a3d007e2537f":"ANIMATED PAGE ACTION THIS EXTENSION ADDS AN ANIMATED BROWSER ACTION TO THE TOOLBAR. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.ONCLICKED CHROME.PAGEACTION.SETICON CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED","9747e3d6a3eab39bc7c17f11a80573c62d44c7e5":"BLANK NEW TAB PAGE CHROME_URL_OVERRIDES","903e7277139e1e6caec123d3319cab295d8d1b3a":"CHROME SOUNDS ENJOY A MORE MAGICAL AND IMMERSIVE EXPERIENCE WHEN BROWSING THE WEB USING THE POWER OF SOUND. BACKGROUND_PAGE BOOKMARKS OPTIONS_PAGE TABS CHROME.BOOKMARKS.ONCREATED CHROME.BOOKMARKS.ONMOVED CHROME.BOOKMARKS.ONREMOVED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.TABS.GET CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED","0e790e035a4a00b6f1def5ef9a7d7be1bce95ab5":"CHROMIUM BUILDBOT MONITOR DISPLAYS THE STATUS OF THE CHROMIUM BUILDBOT IN THE TOOLBAR. CLICK TO SEE MORE DETAILED STATUS IN A POPUP. BACKGROUND_PAGE BROWSER_ACTION NOTIFICATIONS OPTIONS_PAGE POPUP CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.GETURL","ac31228200b41a87982e386cc90d3a6eee4ad885":"CHROMIUM SEARCH ADD SUPPORT TO THE OMNIBOX TO SEARCH THE CHROMIUM SOURCE CODE. BACKGROUND_PAGE TABS CHROME.OMNIBOX.ONINPUTCHANGED CHROME.OMNIBOX.ONINPUTENTERED CHROME.OMNIBOX.STYLEMATCH CHROME.OMNIBOX.STYLEURL CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE","7d5d6cf195bc25480256618e360aa38c6e6fba82":"CLD DISPLAYS THE LANGUAGE OF A TAB BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.DETECTLANGUAGE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED","5d81304a17cf7ac2887484f730fbd2b01e51e166":"CONTEXT MENUS SAMPLE SHOWS SOME OF THE FEATURES OF THE CONTEXT MENUS API BACKGROUND_PAGE CONTEXTMENUS CHROME.CONTEXTMENUS.CREATE","4daa6becd0899a54776d9cf7f09613ed1a9f4d77":"COOKIE API TEST EXTENSION TESTING COOKIE API BACKGROUND_PAGE BROWSER_ACTION COOKIES TABS CHROME.BROWSERACTION.ONCLICKED CHROME.COOKIES.GET CHROME.COOKIES.GETALL CHROME.COOKIES.ONCHANGED CHROME.COOKIES.REMOVE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL","6871d09f4a96bf9d4b6cc724d00e909cee0f3902":"CROSS-DOMAIN XMLHTTPREQUEST FROM A CONTENT SCRIPT DEMONSTRATES A METHOD TO MAKE A CROSS-DOMAIN XMLHTTPREQUEST FETCH FROM A CONTENT SCRIPT. THIS EXTENSION FETCHES THE CURRENT TRENDING TOPICS FROM TWITTER AND INSERTS THEM IN AN OVERLAY AT THE TOP OF GOOGLE NEWS. VISIT HTTP://NEWS.GOOGLE.COM TO TEST THIS EXTENSION. BACKGROUND_PAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST","028eb5364924344029bcbe1d527f132fc72b34e5":"EMAIL THIS PAGE (BY GOOGLE) THIS EXTENSION ADDS AN EMAIL BUTTON TO THE TOOLBAR WHICH ALLOWS YOU TO EMAIL THE PAGE LINK USING YOUR DEFAULT MAIL CLIENT OR GMAIL. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.CONNECT CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.UPDATE","763a08e9b06595d785568a8d392b95a2f3700258":"EVENT TRACKING WITH GOOGLE ANALYTICS A SAMPLE EXTENSION WHICH USES GOOGLE ANALYTICS TO TRACK USAGE. BACKGROUND_PAGE BROWSER_ACTION POPUP","e3df888a89e35bdeb9c8bc8d03be5e1851b97c68":"EXTENSION DOCS SEARCH SEARCH THE CHROME EXTENSIONS DOCUMENTATION. TO USE, TYPE CRDOC PLUS A SEARCH TERM INTO THE OMNIBOX. BACKGROUND_PAGE TABS CHROME.OMNIBOX.ONINPUTCHANGED CHROME.OMNIBOX.ONINPUTENTERED CHROME.OMNIBOX.STYLEMATCH CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.ONREMOVED CHROME.TABS.UPDATE","8b0dd31216235941bdd8eb33fda915ef5cf79a82":"GOOGLE CALENDAR CHECKER (BY GOOGLE) QUICKLY SEE THE TIME UNTIL YOUR NEXT MEETING FROM ANY OF YOUR CALENDARS. CLICK ON THE BUTTON TO BE TAKEN TO YOUR CALENDAR. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETICON CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.ONUPDATED CHROME.TABS.UPDATE","4e35caa9742fb82dbd628892d23a781614f6eff6":"GOOGLE DOCUMENT LIST VIEWER DEMONSTRATES HOW TO USE OAUTH TO CONNECT THE GOOGLE DOCUMENTS LIST DATA API. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","bb57f7a0132cbeb36ad7e7bb0ab75c21704234ca":"GOOGLE MAIL CHECKER DISPLAYS THE NUMBER OF UNREAD MESSAGES IN YOUR GOOGLE MAIL INBOX. YOU CAN ALSO CLICK THE BUTTON TO OPEN YOUR INBOX. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.ONUPDATED CHROME.TABS.UPDATE","1682e05ea9a1bde985123b04f6f8ac50a8a64033":"GOOGLE WAVE NOTIFIER FIND OUT WHEN YOU HAVE NEW WAVES AND PREVIEW THEM FAST. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","14b9651fda4e57b2a5914ba73a779812201b750a":"HELLO WORLD THE FIRST EXTENSION THAT I MADE. BROWSER_ACTION POPUP","2020d72f2577f53caf8e94e3dbac0fb849ceaa4d":"IDLE - SIMPLE EXAMPLE DEMONSTRATES THE IDLE API BACKGROUND_PAGE BROWSER_ACTION IDLE CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.IDLE.ONSTATECHANGED CHROME.IDLE.QUERYSTATE","0ea1588bd07b20338fc21f725de1542a5fdf9726":"IGOOGLE NEW TAB PAGE CHROME_URL_OVERRIDES","646325c25f572a1d15edc73d057f821d847a4fbe":"IMAGEINFO GET IMAGE INFO FOR IMAGES, INCLUDING EXIF DATA BACKGROUND_PAGE CONTEXTMENUS TABS CHROME.CONTEXTMENUS.CREATE CHROME.TABS.GET CHROME.TABS.GETCURRENT CHROME.WINDOWS.CREATE CHROME.WINDOWS.UPDATE","ec97ec20ca2f095d081e39f1565fc12af09ef067":"MAPPY FINDS ADDRESSES IN THE WEB PAGE YOURE ON AND POPS UP A MAP WINDOW. BACKGROUND_PAGE PAGE_ACTION POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.SENDREQUEST","b2f5f8a790e16f091a7e4e0a39b2d0a6d32e3a6d":"MERGE WINDOWS MERGES ALL OF THE BROWSERS WINDOWS INTO THE CURRENT WINDOW BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.MOVE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT","51a83d2ba3a32e3ff1bdb624d4e18ccec4c4038e":"MESSAGE TIMER TIMES HOW LONG IT TAKES TO SEND A MESSAGE TO A CONTENT SCRIPT AND BACK. BROWSER_ACTION POPUP TABS CHROME.EXTENSION.ONCONNECT CHROME.EXTENSION.ONREQUEST CHROME.TABS.CONNECT CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.SENDREQUEST","4f6785ec4f937add6728615682dd37c9a42d9548":"MY BOOKMARKS A BROWSER ACTION WITH A POPUP DUMP OF ALL BOOKMARKS, INCLUDING SEARCH, ADD, EDIT AND DELETE. BOOKMARKS BROWSER_ACTION POPUP TABS CHROME.BOOKMARKS.CREATE CHROME.BOOKMARKS.GET CHROME.BOOKMARKS.GETTREE CHROME.BOOKMARKS.REMOVE CHROME.BOOKMARKS.UPDATE CHROME.TABS.CREATE","597015d3bcce3da693b02314afd607bec4f55291":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.TABS.CREATE","6444e5c8ae112a6a433909c5e770669cd16e2e5f":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE","3aea027164cb9b732ba4a8c51cb93708891726ef":"NEWS READER (BY GOOGLE) DISPLAYS THE LATEST STORIES FROM GOOGLE NEWS IN A POPUP. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.EXTENSION.GETURL CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE","f799e26ceef2367cf836f24bcb47df4398b0df58":"NOTIFICATION DEMO SHOWS OFF DESKTOP NOTIFICATIONS, WHICH ARE TOAST WINDOWS THAT POP UP ON THE DESKTOP. BACKGROUND_PAGE NOTIFICATIONS OPTIONS_PAGE TABS CHROME.TABS.CREATE","e787b322bddbc6289bb31b7d7550b1bf6456a80b":"OMNIBOX EXAMPLE TO USE, TYPE OMNIX PLUS A SEARCH TERM INTO THE OMNIBOX. BACKGROUND_PAGE CHROME.OMNIBOX.ONINPUTCHANGED CHROME.OMNIBOX.ONINPUTENTERED","8d0a50b57c26bb498be592e871001ffed91541b4":"PAGE ACTION BY CONTENT SHOWS A PAGE ACTION FOR HTML PAGES CONTAINING THE WORD SANDWICH BACKGROUND_PAGE PAGE_ACTION CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.PAGEACTION.SHOW","80b86ccc6e8520660fa591caa565826f0ed1b12c":"PAGE ACTION BY URL SHOWS A PAGE ACTION FOR URLS WHICH HAVE THE LETTER G IN THEM. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.SHOW CHROME.TABS.ONUPDATED","d74c3c18a1c1dd18b035149105a306f837c8823e":"PAGE BENCHMARKER CHROMIUM PAGE BENCHMARKER. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.CONNECT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETEXTENSIONTABS CHROME.EXTENSION.GETURL CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETCURRENT","e6ae17ab4ccfd7e059c8c01f25760ca5d894c7fd":"PRINT THIS PAGE ADDS A PRINT BUTTON TO THE BROWSER. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.UPDATE","beff6ecd9677dea0a7c648c5042165b48bb66f09":"PROCESS MONITOR ADDS A BROWSER ACTION THAT MONITORS RESOURCE USAGE OF ALL BROWSER PROCESSES. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.ONUPDATED","56a8d2ac24ca7bba78fd88ad57f43fc13c784497":"SAMPLE - OAUTH CONTACTS USES OAUTH TO CONNECT TO GOOGLES CONTACTS SERVICE AND DISPLAY A LIST OF YOUR CONTACTS. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","38f6e1e17756ede38b1364c7114a738ca717dcbb":"SANDWICHBAR SHOWS AN INFOBAR ON PAGES WHICH CONTAIN THE WORD SANDWICH BACKGROUND_PAGE EXPERIMENTAL CHROME.EXPERIMENTAL.INFOBARS.SHOW CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST","fc89b35755483af30b66cd72cefa34a43a3e8312":"SHOW TABS IN PROCESS ADDS A BROWSER ACTION SHOWING WHICH TABS SHARE THE CURRENT TABS PROCESS. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.GETPROCESSIDFORTAB CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.UPDATE","230463f2d5c3d4d0ca13c230e1f00f2aae0a8a64":"TAB INSPECTOR UTILITY FOR WORKING WITH THE EXTENSION TABS API BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.MOVE CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.CREATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.GETLASTFOCUSED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED CHROME.WINDOWS.REMOVE CHROME.WINDOWS.UPDATE","e1697cacebad05218798bf3e8a0f724517f0e8c3":"TEST SCREENSHOT EXTENSION DEMONSTRATE SCREENSHOT FUNCTIONALITY IN THE CHROME.TABS API. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.EXTENSION.GETVIEWS CHROME.TABS.CAPTUREVISIBLETAB CHROME.TABS.CREATE CHROME.TABS.ONUPDATED","b3de91ab04b7d7a2670ca7ee9d740eb42cead0b6":"TYPED URL HISTORY READS YOUR HISTORY, AND SHOWS THE TOP TEN PAGES YOU GO TO BY TYPING THE URL. BROWSER_ACTION HISTORY TABS CHROME.HISTORY.GETVISITS CHROME.HISTORY.SEARCH CHROME.TABS.CREATE"}</script>
<script src="js/sample_search.js"></script>
@@ -330,6 +338,8 @@
</span><span>
<a href="javascript:void(0);" onclick="setFilter('chrome.management', this)">chrome.management</a><span>, </span>
</span><span>
+ <a href="javascript:void(0);" onclick="setFilter('chrome.omnibox', this)">chrome.omnibox</a><span>, </span>
+ </span><span>
<a href="javascript:void(0);" onclick="setFilter('chrome.pageAction', this)">chrome.pageAction</a><span>, </span>
</span><span>
<a href="javascript:void(0);" onclick="setFilter('chrome.tabs', this)">chrome.tabs</a><span>, </span>
@@ -714,10 +724,7 @@
</h2>
<p class="metadata features">Uses
<span>
- <strong>background_page</strong><span>, </span>
- <span style="display: none; "> and</span>
- </span><span>
- <strong>experimental</strong><span style="display: none; ">, </span>
+ <strong>background_page</strong><span style="display: none; ">, </span>
<span> and</span>
</span><span>
<strong>tabs</strong><span style="display: none; ">, </span>
@@ -728,15 +735,13 @@
<div class="apicalls"><strong>Calls:</strong>
<ul>
<li>
- <code><a href="experimental.omnibox.html#event-onInputChanged">chrome.experimental.omnibox.onInputChanged</a></code>
+ <code><a href="omnibox.html#event-onInputChanged">chrome.omnibox.onInputChanged</a></code>
</li><li>
- <code><a href="experimental.omnibox.html#event-onInputEntered">chrome.experimental.omnibox.onInputEntered</a></code>
+ <code><a href="omnibox.html#event-onInputEntered">chrome.omnibox.onInputEntered</a></code>
</li><li>
- <code><a href="experimental.omnibox.html#method-styleMatch">chrome.experimental.omnibox.styleMatch</a></code>
+ <code><a href="omnibox.html#method-styleMatch">chrome.omnibox.styleMatch</a></code>
</li><li>
- <code><a href="experimental.omnibox.html#method-styleNone">chrome.experimental.omnibox.styleNone</a></code>
- </li><li>
- <code><a href="experimental.omnibox.html#method-styleUrl">chrome.experimental.omnibox.styleUrl</a></code>
+ <code><a href="omnibox.html#method-styleUrl">chrome.omnibox.styleUrl</a></code>
</li><li>
<code><a href="tabs.html#method-get">chrome.tabs.get</a></code>
</li><li>
@@ -1031,10 +1036,7 @@
</h2>
<p class="metadata features">Uses
<span>
- <strong>background_page</strong><span>, </span>
- <span style="display: none; "> and</span>
- </span><span>
- <strong>experimental</strong><span style="display: none; ">, </span>
+ <strong>background_page</strong><span style="display: none; ">, </span>
<span> and</span>
</span><span>
<strong>tabs</strong><span style="display: none; ">, </span>
@@ -1045,13 +1047,11 @@
<div class="apicalls"><strong>Calls:</strong>
<ul>
<li>
- <code><a href="experimental.omnibox.html#event-onInputChanged">chrome.experimental.omnibox.onInputChanged</a></code>
- </li><li>
- <code><a href="experimental.omnibox.html#event-onInputEntered">chrome.experimental.omnibox.onInputEntered</a></code>
+ <code><a href="omnibox.html#event-onInputChanged">chrome.omnibox.onInputChanged</a></code>
</li><li>
- <code><a href="experimental.omnibox.html#method-styleMatch">chrome.experimental.omnibox.styleMatch</a></code>
+ <code><a href="omnibox.html#event-onInputEntered">chrome.omnibox.onInputEntered</a></code>
</li><li>
- <code><a href="experimental.omnibox.html#method-styleNone">chrome.experimental.omnibox.styleNone</a></code>
+ <code><a href="omnibox.html#method-styleMatch">chrome.omnibox.styleMatch</a></code>
</li><li>
<code><a href="tabs.html#method-create">chrome.tabs.create</a></code>
</li><li>
@@ -1073,6 +1073,81 @@
</ul>
</div>
<div><a href="examples/api/omnibox/extension-docs.zip">Download .zip</a></div>
+</div><div class="sample" id="8b0dd31216235941bdd8eb33fda915ef5cf79a82">
+ <img class="icon" src="examples/extensions/calendar/images/icon-128.gif">
+ <img class="icon" src="images/sample-default-icon.png" style="display: none; ">
+ <h2 class="name">
+ <a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/calendar/">Google Calendar Checker (by Google)</a>
+ </h2>
+ <p class="metadata features">Uses
+ <span>
+ <strong>background_page</strong><span>, </span>
+ <span style="display: none; "> and</span>
+ </span><span>
+ <strong>browser_action</strong><span>, </span>
+ <span style="display: none; "> and</span>
+ </span><span>
+ <strong>options_page</strong><span style="display: none; ">, </span>
+ <span> and</span>
+ </span><span>
+ <strong>tabs</strong><span style="display: none; ">, </span>
+ <span style="display: none; "> and</span>
+ </span>
+ </p>
+ <p>Quickly see the time until your next meeting from any of your calendars. Click on the button to be taken to your calendar.</p>
+ <div class="apicalls"><strong>Calls:</strong>
+ <ul>
+ <li>
+ <code><a href="browserAction.html#event-onClicked">chrome.browserAction.onClicked</a></code>
+ </li><li>
+ <code><a href="browserAction.html#method-setBadgeBackgroundColor">chrome.browserAction.setBadgeBackgroundColor</a></code>
+ </li><li>
+ <code><a href="browserAction.html#method-setBadgeText">chrome.browserAction.setBadgeText</a></code>
+ </li><li>
+ <code><a href="browserAction.html#method-setIcon">chrome.browserAction.setIcon</a></code>
+ </li><li>
+ <code><a href="browserAction.html#method-setTitle">chrome.browserAction.setTitle</a></code>
+ </li><li>
+ <code><a href="extension.html#method-getBackgroundPage">chrome.extension.getBackgroundPage</a></code>
+ </li><li>
+ <code><a href="extension.html#event-onRequest">chrome.extension.onRequest</a></code>
+ </li><li>
+ <code><a href="extension.html#method-sendRequest">chrome.extension.sendRequest</a></code>
+ </li><li>
+ <code><a href="i18n.html#method-getMessage">chrome.i18n.getMessage</a></code>
+ </li><li>
+ <code><a href="tabs.html#method-create">chrome.tabs.create</a></code>
+ </li><li>
+ <code><a href="tabs.html#method-get">chrome.tabs.get</a></code>
+ </li><li>
+ <code><a href="tabs.html#method-getAllInWindow">chrome.tabs.getAllInWindow</a></code>
+ </li><li>
+ <code><a href="tabs.html#event-onUpdated">chrome.tabs.onUpdated</a></code>
+ </li><li>
+ <code><a href="tabs.html#method-update">chrome.tabs.update</a></code>
+ </li>
+ </ul>
+ </div>
+ <div class="sourcefiles"><strong>Source files:</strong>
+ <ul>
+ <li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/calendar/_locales/en/messages.json?content-type=text/plain">_locales/en/messages.json</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/calendar/javascript/background.js?content-type=text/plain">javascript/background.js</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/calendar/javascript/options.js?content-type=text/plain">javascript/options.js</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/calendar/javascript/util.js?content-type=text/plain">javascript/util.js</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/calendar/manifest.json?content-type=text/plain">manifest.json</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/calendar/views/background.html?content-type=text/plain">views/background.html</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/calendar/views/options.html?content-type=text/plain">views/options.html</a></code>
+ </li>
+ </ul>
+ </div>
+ <div><a href="examples/extensions/calendar.zip">Download .zip</a></div>
</div><div class="sample" id="4e35caa9742fb82dbd628892d23a781614f6eff6">
<img class="icon" src="examples/extensions/gdocs/img/docs_spreadsheets-128.gif">
<img class="icon" src="images/sample-default-icon.png" style="display: none; ">
@@ -1717,11 +1792,11 @@
</ul>
</div>
<div><a href="examples/api/bookmarks/basic.zip">Download .zip</a></div>
-</div><div class="sample" id="3aea027164cb9b732ba4a8c51cb93708891726ef">
- <img class="icon" src="examples/extensions/news/news_icon.png">
+</div><div class="sample" id="597015d3bcce3da693b02314afd607bec4f55291">
+ <img class="icon" src="examples/extensions/news_a11y/news_icon.png">
<img class="icon" src="images/sample-default-icon.png" style="display: none; ">
<h2 class="name">
- <a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/">News Reader</a>
+ <a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_a11y/">News Reader</a>
</h2>
<p class="metadata features">Uses
<span>
@@ -1746,18 +1821,18 @@
<div class="sourcefiles"><strong>Source files:</strong>
<ul>
<li>
- <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/feed.html?content-type=text/plain">feed.html</a></code>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html?content-type=text/plain">feed.html</a></code>
</li><li>
- <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/manifest.json?content-type=text/plain">manifest.json</a></code>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_a11y/manifest.json?content-type=text/plain">manifest.json</a></code>
</li>
</ul>
</div>
- <div><a href="examples/extensions/news.zip">Download .zip</a></div>
-</div><div class="sample" id="597015d3bcce3da693b02314afd607bec4f55291">
- <img class="icon" src="examples/extensions/news_a11y/news_icon.png">
+ <div><a href="examples/extensions/news_a11y.zip">Download .zip</a></div>
+</div><div class="sample" id="6444e5c8ae112a6a433909c5e770669cd16e2e5f">
+ <img class="icon" src="examples/extensions/news_i18n/news_icon.png">
<img class="icon" src="images/sample-default-icon.png" style="display: none; ">
<h2 class="name">
- <a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_a11y/">News Reader</a>
+ <a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/">News Reader</a>
</h2>
<p class="metadata features">Uses
<span>
@@ -1775,6 +1850,8 @@
<div class="apicalls"><strong>Calls:</strong>
<ul>
<li>
+ <code><a href="i18n.html#method-getMessage">chrome.i18n.getMessage</a></code>
+ </li><li>
<code><a href="tabs.html#method-create">chrome.tabs.create</a></code>
</li>
</ul>
@@ -1782,24 +1859,36 @@
<div class="sourcefiles"><strong>Source files:</strong>
<ul>
<li>
- <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_a11y/feed.html?content-type=text/plain">feed.html</a></code>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/en/messages.json?content-type=text/plain">_locales/en/messages.json</a></code>
</li><li>
- <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_a11y/manifest.json?content-type=text/plain">manifest.json</a></code>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/es/messages.json?content-type=text/plain">_locales/es/messages.json</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/sr/messages.json?content-type=text/plain">_locales/sr/messages.json</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/feed.html?content-type=text/plain">feed.html</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/manifest.json?content-type=text/plain">manifest.json</a></code>
</li>
</ul>
</div>
- <div><a href="examples/extensions/news_a11y.zip">Download .zip</a></div>
-</div><div class="sample" id="6444e5c8ae112a6a433909c5e770669cd16e2e5f">
- <img class="icon" src="examples/extensions/news_i18n/news_icon.png">
+ <div><a href="examples/extensions/news_i18n.zip">Download .zip</a></div>
+</div><div class="sample" id="3aea027164cb9b732ba4a8c51cb93708891726ef">
+ <img class="icon" src="examples/extensions/news/images/news_icon.png">
<img class="icon" src="images/sample-default-icon.png" style="display: none; ">
<h2 class="name">
- <a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/">News Reader</a>
+ <a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/">News Reader (by Google)</a>
</h2>
<p class="metadata features">Uses
<span>
+ <strong>background_page</strong><span>, </span>
+ <span style="display: none; "> and</span>
+ </span><span>
<strong>browser_action</strong><span>, </span>
<span style="display: none; "> and</span>
</span><span>
+ <strong>options_page</strong><span>, </span>
+ <span style="display: none; "> and</span>
+ </span><span>
<strong>popup</strong><span style="display: none; ">, </span>
<span> and</span>
</span><span>
@@ -1807,10 +1896,12 @@
<span style="display: none; "> and</span>
</span>
</p>
- <p>Displays the first 5 items from the 'Google News - top news' RSS feed in a popup.</p>
+ <p>Displays the latest stories from Google News in a popup.</p>
<div class="apicalls"><strong>Calls:</strong>
<ul>
<li>
+ <code><a href="extension.html#method-getURL">chrome.extension.getURL</a></code>
+ </li><li>
<code><a href="i18n.html#method-getMessage">chrome.i18n.getMessage</a></code>
</li><li>
<code><a href="tabs.html#method-create">chrome.tabs.create</a></code>
@@ -1820,19 +1911,29 @@
<div class="sourcefiles"><strong>Source files:</strong>
<ul>
<li>
- <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/en/messages.json?content-type=text/plain">_locales/en/messages.json</a></code>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/_locales/en/messages.json?content-type=text/plain">_locales/en/messages.json</a></code>
</li><li>
- <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/es/messages.json?content-type=text/plain">_locales/es/messages.json</a></code>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/css/feed.css?content-type=text/plain">css/feed.css</a></code>
</li><li>
- <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/_locales/sr/messages.json?content-type=text/plain">_locales/sr/messages.json</a></code>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/css/options.css?content-type=text/plain">css/options.css</a></code>
</li><li>
- <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/feed.html?content-type=text/plain">feed.html</a></code>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/javascript/feed.js?content-type=text/plain">javascript/feed.js</a></code>
</li><li>
- <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news_i18n/manifest.json?content-type=text/plain">manifest.json</a></code>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/javascript/options.js?content-type=text/plain">javascript/options.js</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/javascript/util.js?content-type=text/plain">javascript/util.js</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/manifest.json?content-type=text/plain">manifest.json</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/views/background.html?content-type=text/plain">views/background.html</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/views/feed.html?content-type=text/plain">views/feed.html</a></code>
+ </li><li>
+ <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/news/views/options.html?content-type=text/plain">views/options.html</a></code>
</li>
</ul>
</div>
- <div><a href="examples/extensions/news_i18n.zip">Download .zip</a></div>
+ <div><a href="examples/extensions/news.zip">Download .zip</a></div>
</div><div class="sample" id="f799e26ceef2367cf836f24bcb47df4398b0df58">
<img class="icon" src="examples/api/notifications/128.png">
<img class="icon" src="images/sample-default-icon.png" style="display: none; ">
@@ -1885,9 +1986,6 @@
<p class="metadata features">Uses
<span>
<strong>background_page</strong><span style="display: none; ">, </span>
- <span> and</span>
- </span><span>
- <strong>experimental</strong><span style="display: none; ">, </span>
<span style="display: none; "> and</span>
</span>
</p>
@@ -1895,9 +1993,9 @@
<div class="apicalls"><strong>Calls:</strong>
<ul>
<li>
- <code><a href="experimental.omnibox.html#event-onInputChanged">chrome.experimental.omnibox.onInputChanged</a></code>
+ <code><a href="omnibox.html#event-onInputChanged">chrome.omnibox.onInputChanged</a></code>
</li><li>
- <code><a href="experimental.omnibox.html#event-onInputEntered">chrome.experimental.omnibox.onInputEntered</a></code>
+ <code><a href="omnibox.html#event-onInputEntered">chrome.omnibox.onInputEntered</a></code>
</li>
</ul>
</div>
diff --git a/chrome/common/extensions/docs/samples.json b/chrome/common/extensions/docs/samples.json
index bc67080..edd54bc 100644
--- a/chrome/common/extensions/docs/samples.json
+++ b/chrome/common/extensions/docs/samples.json
@@ -1,266 +1,256 @@
{
"api": {
- "chrome.experimental.webRequest.onHeadersReceived": "experimental.webRequest.html#event-onHeadersReceived",
- "chrome.browserAction.onClicked": "browserAction.html#event-onClicked",
- "chrome.history.getVisits": "history.html#method-getVisits",
+ "chrome.bookmarks.create": "bookmarks.html#method-create",
+ "chrome.bookmarks.export": "bookmarks.html#method-export",
+ "chrome.bookmarks.get": "bookmarks.html#method-get",
+ "chrome.bookmarks.getChildren": "bookmarks.html#method-getChildren",
+ "chrome.bookmarks.getRecent": "bookmarks.html#method-getRecent",
+ "chrome.bookmarks.getTree": "bookmarks.html#method-getTree",
+ "chrome.bookmarks.import": "bookmarks.html#method-import",
+ "chrome.bookmarks.move": "bookmarks.html#method-move",
+ "chrome.bookmarks.onChanged": "bookmarks.html#event-onChanged",
+ "chrome.bookmarks.onChildrenReordered": "bookmarks.html#event-onChildrenReordered",
+ "chrome.bookmarks.onCreated": "bookmarks.html#event-onCreated",
+ "chrome.bookmarks.onImportBegan": "bookmarks.html#event-onImportBegan",
"chrome.bookmarks.onImportEnded": "bookmarks.html#event-onImportEnded",
- "chrome.history.search": "history.html#method-search",
- "chrome.experimental.omnibox.onInputCancelled": "experimental.omnibox.html#event-onInputCancelled",
- "chrome.bookmarks.remove": "bookmarks.html#method-remove",
- "chrome.experimental.webNavigation.onErrorOccurred": "experimental.webNavigation.html#event-onErrorOccurred",
- "chrome.history.deleteUrl": "history.html#method-deleteUrl",
- "chrome.experimental.omnibox.styleNone": "experimental.omnibox.html#method-styleNone",
"chrome.bookmarks.onMoved": "bookmarks.html#event-onMoved",
+ "chrome.bookmarks.onRemoved": "bookmarks.html#event-onRemoved",
+ "chrome.bookmarks.remove": "bookmarks.html#method-remove",
+ "chrome.bookmarks.removeTree": "bookmarks.html#method-removeTree",
+ "chrome.bookmarks.search": "bookmarks.html#method-search",
+ "chrome.bookmarks.update": "bookmarks.html#method-update",
+ "chrome.browserAction.onClicked": "browserAction.html#event-onClicked",
"chrome.browserAction.setBadgeBackgroundColor": "browserAction.html#method-setBadgeBackgroundColor",
- "chrome.pageAction.setTitle": "pageAction.html#method-setTitle",
- "chrome.bookmarks.onImportBegan": "bookmarks.html#event-onImportBegan",
- "chrome.experimental.omnibox.styleDim": "experimental.omnibox.html#method-styleDim",
- "chrome.bookmarks.getTree": "bookmarks.html#method-getTree",
+ "chrome.browserAction.setBadgeText": "browserAction.html#method-setBadgeText",
+ "chrome.browserAction.setIcon": "browserAction.html#method-setIcon",
+ "chrome.browserAction.setPopup": "browserAction.html#method-setPopup",
+ "chrome.browserAction.setTitle": "browserAction.html#method-setTitle",
+ "chrome.contextMenus.create": "contextMenus.html#method-create",
+ "chrome.contextMenus.remove": "contextMenus.html#method-remove",
+ "chrome.contextMenus.removeAll": "contextMenus.html#method-removeAll",
+ "chrome.contextMenus.update": "contextMenus.html#method-update",
+ "chrome.cookies.get": "cookies.html#method-get",
+ "chrome.cookies.getAll": "cookies.html#method-getAll",
+ "chrome.cookies.getAllCookieStores": "cookies.html#method-getAllCookieStores",
+ "chrome.cookies.onChanged": "cookies.html#event-onChanged",
+ "chrome.cookies.remove": "cookies.html#method-remove",
+ "chrome.cookies.set": "cookies.html#method-set",
+ "chrome.experimental.clipboard.executeCopy": "experimental.clipboard.html#method-executeCopy",
+ "chrome.experimental.clipboard.executeCut": "experimental.clipboard.html#method-executeCut",
+ "chrome.experimental.clipboard.executePaste": "experimental.clipboard.html#method-executePaste",
"chrome.experimental.infobars.show": "experimental.infobars.html#method-show",
- "chrome.windows.get": "windows.html#method-get",
- "chrome.extension.sendRequest": "extension.html#method-sendRequest",
- "chrome.windows.getAll": "windows.html#method-getAll",
- "chrome.tabs.captureVisibleTab": "tabs.html#method-captureVisibleTab",
- "chrome.idle.onStateChanged": "idle.html#event-onStateChanged",
- "chrome.i18n.getMessage": "i18n.html#method-getMessage",
- "chrome.bookmarks.import": "bookmarks.html#method-import",
- "chrome.extension.onConnect": "extension.html#event-onConnect",
- "chrome.bookmarks.removeTree": "bookmarks.html#method-removeTree",
- "chrome.bookmarks.get": "bookmarks.html#method-get",
+ "chrome.experimental.processes.getProcessIdForTab": "experimental.processes.html#method-getProcessIdForTab",
"chrome.experimental.processes.onUpdated": "experimental.processes.html#event-onUpdated",
- "chrome.bookmarks.getRecent": "bookmarks.html#method-getRecent",
- "chrome.history.onVisitRemoved": "history.html#event-onVisitRemoved",
- "chrome.experimental.sidebar.navigate": "experimental.sidebar.html#method-navigate",
- "chrome.windows.getCurrent": "windows.html#method-getCurrent",
- "chrome.bookmarks.onChanged": "bookmarks.html#event-onChanged",
- "chrome.tabs.detectLanguage": "tabs.html#method-detectLanguage",
- "chrome.windows.onRemoved": "windows.html#event-onRemoved",
+ "chrome.experimental.proxy.useCustomProxySettings": "experimental.proxy.html#method-useCustomProxySettings",
+ "chrome.experimental.sidebar.collapse": "experimental.sidebar.html#method-collapse",
+ "chrome.experimental.sidebar.expand": "experimental.sidebar.html#method-expand",
+ "chrome.experimental.sidebar.getState": "experimental.sidebar.html#method-getState",
"chrome.experimental.sidebar.hide": "experimental.sidebar.html#method-hide",
- "chrome.management.uninstall": "management.html#method-uninstall",
- "chrome.experimental.clipboard.executePaste": "experimental.clipboard.html#method-executePaste",
- "chrome.experimental.webNavigation.onCompleted": "experimental.webNavigation.html#event-onCompleted",
- "chrome.management.setEnabled": "management.html#method-setEnabled",
- "chrome.tabs.update": "tabs.html#method-update",
- "chrome.history.deleteRange": "history.html#method-deleteRange",
- "chrome.tabs.connect": "tabs.html#method-connect",
- "chrome.management.onEnabled": "management.html#event-onEnabled",
- "chrome.cookies.set": "cookies.html#method-set",
+ "chrome.experimental.sidebar.navigate": "experimental.sidebar.html#method-navigate",
+ "chrome.experimental.sidebar.onStateChanged": "experimental.sidebar.html#event-onStateChanged",
"chrome.experimental.sidebar.setBadgeText": "experimental.sidebar.html#method-setBadgeText",
+ "chrome.experimental.sidebar.setIcon": "experimental.sidebar.html#method-setIcon",
+ "chrome.experimental.sidebar.setTitle": "experimental.sidebar.html#method-setTitle",
+ "chrome.experimental.sidebar.show": "experimental.sidebar.html#method-show",
"chrome.experimental.webNavigation.onBeforeNavigate": "experimental.webNavigation.html#event-onBeforeNavigate",
- "chrome.pageAction.setIcon": "pageAction.html#method-setIcon",
- "chrome.experimental.clipboard.executeCopy": "experimental.clipboard.html#method-executeCopy",
- "chrome.bookmarks.move": "bookmarks.html#method-move",
- "chrome.experimental.webRequest.onBeforeRedirect": "experimental.webRequest.html#event-onBeforeRedirect",
- "chrome.management.get": "management.html#method-get",
- "chrome.tabs.getCurrent": "tabs.html#method-getCurrent",
- "chrome.experimental.sidebar.getState": "experimental.sidebar.html#method-getState",
- "chrome.management.launchApp": "management.html#method-launchApp",
- "chrome.browserAction.setTitle": "browserAction.html#method-setTitle",
- "chrome.contextMenus.remove": "contextMenus.html#method-remove",
- "chrome.experimental.omnibox.onInputStarted": "experimental.omnibox.html#event-onInputStarted",
"chrome.experimental.webNavigation.onBeforeRetarget": "experimental.webNavigation.html#event-onBeforeRetarget",
- "chrome.tabs.create": "tabs.html#method-create",
- "chrome.cookies.get": "cookies.html#method-get",
- "chrome.experimental.webRequest.onBeforeRequest": "experimental.webRequest.html#event-onBeforeRequest",
- "chrome.management.onDisabled": "management.html#event-onDisabled",
- "chrome.windows.onCreated": "windows.html#event-onCreated",
"chrome.experimental.webNavigation.onCommitted": "experimental.webNavigation.html#event-onCommitted",
- "chrome.bookmarks.create": "bookmarks.html#method-create",
- "chrome.tabs.onCreated": "tabs.html#event-onCreated",
- "chrome.cookies.getAllCookieStores": "cookies.html#method-getAllCookieStores",
- "chrome.tabs.get": "tabs.html#method-get",
- "chrome.extension.getViews": "extension.html#method-getViews",
- "chrome.i18n.getAcceptLanguages": "i18n.html#method-getAcceptLanguages",
- "chrome.experimental.omnibox.styleUrl": "experimental.omnibox.html#method-styleUrl",
+ "chrome.experimental.webNavigation.onCompleted": "experimental.webNavigation.html#event-onCompleted",
+ "chrome.experimental.webNavigation.onDOMContentLoaded": "experimental.webNavigation.html#event-onDOMContentLoaded",
+ "chrome.experimental.webNavigation.onErrorOccurred": "experimental.webNavigation.html#event-onErrorOccurred",
+ "chrome.experimental.webRequest.onBeforeRedirect": "experimental.webRequest.html#event-onBeforeRedirect",
+ "chrome.experimental.webRequest.onBeforeRequest": "experimental.webRequest.html#event-onBeforeRequest",
"chrome.experimental.webRequest.onCompleted": "experimental.webRequest.html#event-onCompleted",
- "chrome.bookmarks.onCreated": "bookmarks.html#event-onCreated",
- "chrome.pageAction.show": "pageAction.html#method-show",
- "chrome.management.onInstalled": "management.html#event-onInstalled",
- "chrome.bookmarks.search": "bookmarks.html#method-search",
- "chrome.extension.onRequest": "extension.html#event-onRequest",
+ "chrome.experimental.webRequest.onErrorOccurred": "experimental.webRequest.html#event-onErrorOccurred",
+ "chrome.experimental.webRequest.onHeadersReceived": "experimental.webRequest.html#event-onHeadersReceived",
+ "chrome.experimental.webRequest.onRequestSent": "experimental.webRequest.html#event-onRequestSent",
+ "chrome.extension.connect": "extension.html#method-connect",
"chrome.extension.getBackgroundPage": "extension.html#method-getBackgroundPage",
- "chrome.pageAction.hide": "pageAction.html#method-hide",
- "chrome.experimental.omnibox.styleMatch": "experimental.omnibox.html#method-styleMatch",
- "chrome.experimental.sidebar.expand": "experimental.sidebar.html#method-expand",
- "chrome.experimental.sidebar.onStateChanged": "experimental.sidebar.html#event-onStateChanged",
- "chrome.tabs.executeScript": "tabs.html#method-executeScript",
- "chrome.cookies.remove": "cookies.html#method-remove",
"chrome.extension.getExtensionTabs": "extension.html#method-getExtensionTabs",
- "chrome.tabs.onRemoved": "tabs.html#event-onRemoved",
- "chrome.tabs.insertCSS": "tabs.html#method-insertCSS",
- "chrome.bookmarks.getChildren": "bookmarks.html#method-getChildren",
- "chrome.pageAction.onClicked": "pageAction.html#event-onClicked",
- "chrome.windows.create": "windows.html#method-create",
+ "chrome.extension.getToolstrips": "extension.html#method-getToolstrips",
+ "chrome.extension.getURL": "extension.html#method-getURL",
+ "chrome.extension.getViews": "extension.html#method-getViews",
+ "chrome.extension.onConnect": "extension.html#event-onConnect",
"chrome.extension.onConnectExternal": "extension.html#event-onConnectExternal",
- "chrome.cookies.getAll": "cookies.html#method-getAll",
+ "chrome.extension.onRequest": "extension.html#event-onRequest",
"chrome.extension.onRequestExternal": "extension.html#event-onRequestExternal",
- "chrome.bookmarks.onRemoved": "bookmarks.html#event-onRemoved",
- "chrome.contextMenus.update": "contextMenus.html#method-update",
- "chrome.experimental.sidebar.setTitle": "experimental.sidebar.html#method-setTitle",
- "chrome.bookmarks.export": "bookmarks.html#method-export",
- "chrome.experimental.clipboard.executeCut": "experimental.clipboard.html#method-executeCut",
- "chrome.windows.getLastFocused": "windows.html#method-getLastFocused",
- "chrome.experimental.sidebar.show": "experimental.sidebar.html#method-show",
- "chrome.tabs.onSelectionChanged": "tabs.html#event-onSelectionChanged",
- "chrome.cookies.onChanged": "cookies.html#event-onChanged",
+ "chrome.extension.sendRequest": "extension.html#method-sendRequest",
+ "chrome.extension.setUpdateUrlData": "extension.html#method-setUpdateUrlData",
+ "chrome.history.addUrl": "history.html#method-addUrl",
+ "chrome.history.deleteAll": "history.html#method-deleteAll",
+ "chrome.history.deleteRange": "history.html#method-deleteRange",
+ "chrome.history.deleteUrl": "history.html#method-deleteUrl",
+ "chrome.history.getVisits": "history.html#method-getVisits",
+ "chrome.history.onVisitRemoved": "history.html#event-onVisitRemoved",
+ "chrome.history.onVisited": "history.html#event-onVisited",
+ "chrome.history.search": "history.html#method-search",
+ "chrome.i18n.getAcceptLanguages": "i18n.html#method-getAcceptLanguages",
+ "chrome.i18n.getMessage": "i18n.html#method-getMessage",
+ "chrome.idle.onStateChanged": "idle.html#event-onStateChanged",
+ "chrome.idle.queryState": "idle.html#method-queryState",
+ "chrome.management.get": "management.html#method-get",
"chrome.management.getAll": "management.html#method-getAll",
+ "chrome.management.launchApp": "management.html#method-launchApp",
+ "chrome.management.onDisabled": "management.html#event-onDisabled",
+ "chrome.management.onEnabled": "management.html#event-onEnabled",
+ "chrome.management.onInstalled": "management.html#event-onInstalled",
"chrome.management.onUninstalled": "management.html#event-onUninstalled",
- "chrome.windows.update": "windows.html#method-update",
- "chrome.extension.getURL": "extension.html#method-getURL",
- "chrome.idle.queryState": "idle.html#method-queryState",
- "chrome.experimental.sidebar.setIcon": "experimental.sidebar.html#method-setIcon",
- "chrome.experimental.omnibox.onInputChanged": "experimental.omnibox.html#event-onInputChanged",
- "chrome.experimental.webRequest.onErrorOccurred": "experimental.webRequest.html#event-onErrorOccurred",
- "chrome.tabs.onMoved": "tabs.html#event-onMoved",
- "chrome.experimental.omnibox.sendSuggestions": "experimental.omnibox.html#method-sendSuggestions",
- "chrome.bookmarks.update": "bookmarks.html#method-update",
- "chrome.contextMenus.removeAll": "contextMenus.html#method-removeAll",
- "chrome.windows.remove": "windows.html#method-remove",
- "chrome.tabs.sendRequest": "tabs.html#method-sendRequest",
- "chrome.browserAction.setBadgeText": "browserAction.html#method-setBadgeText",
- "chrome.experimental.sidebar.collapse": "experimental.sidebar.html#method-collapse",
- "chrome.browserAction.setIcon": "browserAction.html#method-setIcon",
- "chrome.experimental.omnibox.onInputEntered": "experimental.omnibox.html#event-onInputEntered",
- "chrome.experimental.proxy.useCustomProxySettings": "experimental.proxy.html#method-useCustomProxySettings",
- "chrome.browserAction.setPopup": "browserAction.html#method-setPopup",
- "chrome.bookmarks.onChildrenReordered": "bookmarks.html#event-onChildrenReordered",
- "chrome.experimental.webRequest.onRequestSent": "experimental.webRequest.html#event-onRequestSent",
- "chrome.extension.getToolstrips": "extension.html#method-getToolstrips",
- "chrome.history.onVisited": "history.html#event-onVisited",
- "chrome.tabs.onUpdated": "tabs.html#event-onUpdated",
- "chrome.history.deleteAll": "history.html#method-deleteAll",
- "chrome.experimental.webNavigation.onDOMContentLoaded": "experimental.webNavigation.html#event-onDOMContentLoaded",
+ "chrome.management.setEnabled": "management.html#method-setEnabled",
+ "chrome.management.uninstall": "management.html#method-uninstall",
+ "chrome.omnibox.onInputCancelled": "omnibox.html#event-onInputCancelled",
+ "chrome.omnibox.onInputChanged": "omnibox.html#event-onInputChanged",
+ "chrome.omnibox.onInputEntered": "omnibox.html#event-onInputEntered",
+ "chrome.omnibox.onInputStarted": "omnibox.html#event-onInputStarted",
+ "chrome.omnibox.sendSuggestions": "omnibox.html#method-sendSuggestions",
+ "chrome.omnibox.styleDim": "omnibox.html#method-styleDim",
+ "chrome.omnibox.styleMatch": "omnibox.html#method-styleMatch",
+ "chrome.omnibox.styleUrl": "omnibox.html#method-styleUrl",
+ "chrome.pageAction.hide": "pageAction.html#method-hide",
+ "chrome.pageAction.onClicked": "pageAction.html#event-onClicked",
+ "chrome.pageAction.setIcon": "pageAction.html#method-setIcon",
+ "chrome.pageAction.setPopup": "pageAction.html#method-setPopup",
+ "chrome.pageAction.setTitle": "pageAction.html#method-setTitle",
+ "chrome.pageAction.show": "pageAction.html#method-show",
+ "chrome.tabs.captureVisibleTab": "tabs.html#method-captureVisibleTab",
+ "chrome.tabs.connect": "tabs.html#method-connect",
+ "chrome.tabs.create": "tabs.html#method-create",
+ "chrome.tabs.detectLanguage": "tabs.html#method-detectLanguage",
+ "chrome.tabs.executeScript": "tabs.html#method-executeScript",
+ "chrome.tabs.get": "tabs.html#method-get",
"chrome.tabs.getAllInWindow": "tabs.html#method-getAllInWindow",
- "chrome.contextMenus.create": "contextMenus.html#method-create",
+ "chrome.tabs.getCurrent": "tabs.html#method-getCurrent",
"chrome.tabs.getSelected": "tabs.html#method-getSelected",
+ "chrome.tabs.insertCSS": "tabs.html#method-insertCSS",
+ "chrome.tabs.move": "tabs.html#method-move",
"chrome.tabs.onAttached": "tabs.html#event-onAttached",
- "chrome.tabs.remove": "tabs.html#method-remove",
+ "chrome.tabs.onCreated": "tabs.html#event-onCreated",
"chrome.tabs.onDetached": "tabs.html#event-onDetached",
- "chrome.extension.connect": "extension.html#method-connect",
- "chrome.tabs.move": "tabs.html#method-move",
+ "chrome.tabs.onMoved": "tabs.html#event-onMoved",
+ "chrome.tabs.onRemoved": "tabs.html#event-onRemoved",
+ "chrome.tabs.onSelectionChanged": "tabs.html#event-onSelectionChanged",
+ "chrome.tabs.onUpdated": "tabs.html#event-onUpdated",
+ "chrome.tabs.remove": "tabs.html#method-remove",
+ "chrome.tabs.sendRequest": "tabs.html#method-sendRequest",
+ "chrome.tabs.update": "tabs.html#method-update",
+ "chrome.windows.create": "windows.html#method-create",
+ "chrome.windows.get": "windows.html#method-get",
+ "chrome.windows.getAll": "windows.html#method-getAll",
+ "chrome.windows.getCurrent": "windows.html#method-getCurrent",
+ "chrome.windows.getLastFocused": "windows.html#method-getLastFocused",
+ "chrome.windows.onCreated": "windows.html#event-onCreated",
"chrome.windows.onFocusChanged": "windows.html#event-onFocusChanged",
- "chrome.pageAction.setPopup": "pageAction.html#method-setPopup",
- "chrome.experimental.processes.getProcessIdForTab": "experimental.processes.html#method-getProcessIdForTab",
- "chrome.history.addUrl": "history.html#method-addUrl"
+ "chrome.windows.onRemoved": "windows.html#event-onRemoved",
+ "chrome.windows.remove": "windows.html#method-remove",
+ "chrome.windows.update": "windows.html#method-update"
},
"samples": [
{
+ "api_calls": [
+ "chrome.browserAction.onClicked",
+ "chrome.browserAction.setIcon"
+ ],
+ "description": "",
"features": [
"background_page",
"browser_action",
"tabs"
],
"icon": null,
- "description": "",
+ "id": "0262260daf0c8f7b28feff2ef23b05e7abf9d1e0",
+ "name": "A browser action which changes its icon when clicked.",
+ "path": "examples\/api\/browserAction\/set_icon_path\/",
+ "protocols": [
+ "http:\/\/"
+ ],
"search_string": "A BROWSER ACTION WHICH CHANGES ITS ICON WHEN CLICKED. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON",
"source_files": [
"background.html",
"manifest.json"
],
- "zip_path": "examples/api/browserAction/set_icon_path.zip",
- "path": "examples/api/browserAction/set_icon_path/",
- "api_calls": [
- "chrome.browserAction.onClicked",
- "chrome.browserAction.setIcon"
- ],
- "id": "0262260daf0c8f7b28feff2ef23b05e7abf9d1e0",
- "protocols": [
- "http://"
- ],
- "name": "A browser action which changes its icon when clicked."
+ "source_hash": "c5752555642e89340c57657b48440b0dcd74ee99",
+ "zip_path": "examples\/api\/browserAction\/set_icon_path.zip"
},
{
+ "api_calls": [
+ "chrome.tabs.executeScript"
+ ],
+ "description": "",
"features": [
"browser_action",
"popup",
"tabs"
],
"icon": null,
- "description": "",
+ "id": "ea2894c41cb8e80a4433a3e6c5772dadce9be90d",
+ "name": "A browser action with a popup that changes the page color.",
+ "path": "examples\/api\/browserAction\/set_page_color\/",
+ "protocols": [
+ "http:\/\/",
+ "https:\/\/"
+ ],
"search_string": "A BROWSER ACTION WITH A POPUP THAT CHANGES THE PAGE COLOR. BROWSER_ACTION POPUP TABS CHROME.TABS.EXECUTESCRIPT",
"source_files": [
"manifest.json",
"popup.html"
],
- "zip_path": "examples/api/browserAction/set_page_color.zip",
- "path": "examples/api/browserAction/set_page_color/",
+ "source_hash": "c8d14b6893e75a62f3bd150d5d2cc5bb785bc411",
+ "zip_path": "examples\/api\/browserAction\/set_page_color.zip"
+ },
+ {
"api_calls": [
+ "chrome.browserAction.onClicked",
+ "chrome.browserAction.setBadgeBackgroundColor",
+ "chrome.browserAction.setBadgeText",
"chrome.tabs.executeScript"
],
- "id": "ea2894c41cb8e80a4433a3e6c5772dadce9be90d",
- "protocols": [
- "http://",
- "https://"
- ],
- "name": "A browser action with a popup that changes the page color."
- },
- {
+ "description": "",
"features": [
"background_page",
"browser_action",
"tabs"
],
"icon": null,
- "description": "",
+ "id": "ede3c47b7757245be42ec33fd5ca63df4b490066",
+ "name": "A browser action with no icon that makes the page red",
+ "path": "examples\/api\/browserAction\/make_page_red\/",
+ "protocols": [
+ "http:\/\/"
+ ],
"search_string": "A BROWSER ACTION WITH NO ICON THAT MAKES THE PAGE RED BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.EXECUTESCRIPT",
"source_files": [
"background.html",
"manifest.json"
],
- "zip_path": "examples/api/browserAction/make_page_red.zip",
- "path": "examples/api/browserAction/make_page_red/",
- "api_calls": [
- "chrome.browserAction.onClicked",
- "chrome.browserAction.setBadgeBackgroundColor",
- "chrome.browserAction.setBadgeText",
- "chrome.tabs.executeScript"
- ],
- "id": "ede3c47b7757245be42ec33fd5ca63df4b490066",
- "protocols": [
- "http://"
- ],
- "name": "A browser action with no icon that makes the page red"
+ "source_hash": "dfbb05ead54a0228a6d2f591ce1038d5c625249a",
+ "zip_path": "examples\/api\/browserAction\/make_page_red.zip"
},
{
+ "api_calls": [
+ "chrome.i18n.getAcceptLanguages",
+ "chrome.i18n.getMessage"
+ ],
+ "description": "Returns accept languages of the browser",
"features": [
"browser_action",
"popup"
],
"icon": null,
- "description": "Returns accept languages of the browser",
+ "id": "fbf0aa1a09a15ff8cc4fc7de4fd176d6c663d07a",
+ "name": "AcceptLanguage",
+ "path": "examples\/api\/i18n\/getMessage\/",
+ "protocols": [],
"search_string": "ACCEPTLANGUAGE RETURNS ACCEPT LANGUAGES OF THE BROWSER BROWSER_ACTION POPUP CHROME.I18N.GETACCEPTLANGUAGES CHROME.I18N.GETMESSAGE",
"source_files": [
- "_locales/en_US/messages.json",
- "_locales/es/messages.json",
- "_locales/sr/messages.json",
+ "_locales\/en_US\/messages.json",
+ "_locales\/es\/messages.json",
+ "_locales\/sr\/messages.json",
"manifest.json",
"popup.html"
],
- "zip_path": "examples/api/i18n/getMessage.zip",
- "path": "examples/api/i18n/getMessage/",
- "api_calls": [
- "chrome.i18n.getAcceptLanguages",
- "chrome.i18n.getMessage"
- ],
- "id": "fbf0aa1a09a15ff8cc4fc7de4fd176d6c663d07a",
- "protocols": [],
- "name": "AcceptLanguage"
+ "source_hash": "67f203e2773eebf401d0aa0a9709d961e506d875",
+ "zip_path": "examples\/api\/i18n\/getMessage.zip"
},
{
- "features": [
- "background_page",
- "page_action",
- "tabs"
- ],
- "icon": null,
- "description": "This extension adds an animated browser action to the toolbar.",
- "search_string": "ANIMATED PAGE ACTION THIS EXTENSION ADDS AN ANIMATED BROWSER ACTION TO THE TOOLBAR. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.ONCLICKED CHROME.PAGEACTION.SETICON CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED",
- "source_files": [
- "background.html",
- "manifest.json"
- ],
- "zip_path": "examples/api/pageAction/set_icon.zip",
- "path": "examples/api/pageAction/set_icon/",
"api_calls": [
"chrome.pageAction.hide",
"chrome.pageAction.onClicked",
@@ -271,47 +261,45 @@
"chrome.tabs.getSelected",
"chrome.tabs.onSelectionChanged"
],
+ "description": "This extension adds an animated browser action to the toolbar.",
+ "features": [
+ "background_page",
+ "page_action",
+ "tabs"
+ ],
+ "icon": null,
"id": "9a6e4ec46997fb92b324974afa08a3d007e2537f",
+ "name": "Animated Page Action",
+ "path": "examples\/api\/pageAction\/set_icon\/",
"protocols": [],
- "name": "Animated Page Action"
+ "search_string": "ANIMATED PAGE ACTION THIS EXTENSION ADDS AN ANIMATED BROWSER ACTION TO THE TOOLBAR. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.ONCLICKED CHROME.PAGEACTION.SETICON CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED",
+ "source_files": [
+ "background.html",
+ "manifest.json"
+ ],
+ "source_hash": "9d5e9f8fd525c6d02fe03e1843041f5b0f94f690",
+ "zip_path": "examples\/api\/pageAction\/set_icon.zip"
},
{
+ "api_calls": [],
+ "description": "",
"features": [
"chrome_url_overrides"
],
"icon": null,
- "description": "",
+ "id": "9747e3d6a3eab39bc7c17f11a80573c62d44c7e5",
+ "name": "Blank new tab page",
+ "path": "examples\/api\/override\/blank_ntp\/",
+ "protocols": [],
"search_string": "BLANK NEW TAB PAGE CHROME_URL_OVERRIDES",
"source_files": [
"blank.html",
"manifest.json"
],
- "zip_path": "examples/api/override/blank_ntp.zip",
- "path": "examples/api/override/blank_ntp/",
- "api_calls": [],
- "id": "9747e3d6a3eab39bc7c17f11a80573c62d44c7e5",
- "protocols": [],
- "name": "Blank new tab page"
+ "source_hash": "477acf6d15e3fa252e6307e156707538b61c86db",
+ "zip_path": "examples\/api\/override\/blank_ntp.zip"
},
{
- "features": [
- "background_page",
- "bookmarks",
- "options_page",
- "tabs"
- ],
- "icon": "icon.png",
- "description": "Enjoy a more magical and immersive experience when browsing the web using the power of sound.",
- "search_string": "CHROME SOUNDS ENJOY A MORE MAGICAL AND IMMERSIVE EXPERIENCE WHEN BROWSING THE WEB USING THE POWER OF SOUND. BACKGROUND_PAGE BOOKMARKS OPTIONS_PAGE TABS CHROME.BOOKMARKS.ONCREATED CHROME.BOOKMARKS.ONMOVED CHROME.BOOKMARKS.ONREMOVED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.TABS.GET CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED",
- "source_files": [
- "bg.html",
- "bg.js",
- "content.js",
- "manifest.json",
- "options.html"
- ],
- "zip_path": "examples/extensions/fx.zip",
- "path": "examples/extensions/fx/",
"api_calls": [
"chrome.bookmarks.onCreated",
"chrome.bookmarks.onMoved",
@@ -331,14 +319,40 @@
"chrome.windows.onFocusChanged",
"chrome.windows.onRemoved"
],
+ "description": "Enjoy a more magical and immersive experience when browsing the web using the power of sound.",
+ "features": [
+ "background_page",
+ "bookmarks",
+ "options_page",
+ "tabs"
+ ],
+ "icon": "icon.png",
"id": "903e7277139e1e6caec123d3319cab295d8d1b3a",
+ "name": "Chrome Sounds",
+ "path": "examples\/extensions\/fx\/",
"protocols": [
- "http://",
- "https://"
+ "http:\/\/",
+ "https:\/\/"
+ ],
+ "search_string": "CHROME SOUNDS ENJOY A MORE MAGICAL AND IMMERSIVE EXPERIENCE WHEN BROWSING THE WEB USING THE POWER OF SOUND. BACKGROUND_PAGE BOOKMARKS OPTIONS_PAGE TABS CHROME.BOOKMARKS.ONCREATED CHROME.BOOKMARKS.ONMOVED CHROME.BOOKMARKS.ONREMOVED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.TABS.GET CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED",
+ "source_files": [
+ "bg.html",
+ "bg.js",
+ "content.js",
+ "manifest.json",
+ "options.html"
],
- "name": "Chrome Sounds"
+ "source_hash": "4155e4e6ba7d523ba7bc3b75da352c22e534c3c3",
+ "zip_path": "examples\/extensions\/fx.zip"
},
{
+ "api_calls": [
+ "chrome.browserAction.setBadgeBackgroundColor",
+ "chrome.browserAction.setBadgeText",
+ "chrome.browserAction.setTitle",
+ "chrome.extension.getURL"
+ ],
+ "description": "Displays the status of the Chromium buildbot in the toolbar. Click to see more detailed status in a popup.",
"features": [
"background_page",
"browser_action",
@@ -347,7 +361,13 @@
"popup"
],
"icon": "icon.png",
- "description": "Displays the status of the Chromium buildbot in the toolbar. Click to see more detailed status in a popup.",
+ "id": "0e790e035a4a00b6f1def5ef9a7d7be1bce95ab5",
+ "name": "Chromium Buildbot Monitor",
+ "path": "examples\/extensions\/buildbot\/",
+ "protocols": [
+ "http:\/\/",
+ "http:\/\/"
+ ],
"search_string": "CHROMIUM BUILDBOT MONITOR DISPLAYS THE STATUS OF THE CHROMIUM BUILDBOT IN THE TOOLBAR. CLICK TO SEE MORE DETAILED STATUS IN A POPUP. BACKGROUND_PAGE BROWSER_ACTION NOTIFICATIONS OPTIONS_PAGE POPUP CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.GETURL",
"source_files": [
"bg.html",
@@ -355,67 +375,40 @@
"options.html",
"popup.html"
],
- "zip_path": "examples/extensions/buildbot.zip",
- "path": "examples/extensions/buildbot/",
- "api_calls": [
- "chrome.browserAction.setBadgeBackgroundColor",
- "chrome.browserAction.setBadgeText",
- "chrome.browserAction.setTitle",
- "chrome.extension.getURL"
- ],
- "id": "0e790e035a4a00b6f1def5ef9a7d7be1bce95ab5",
- "protocols": [
- "http://",
- "http://"
- ],
- "name": "Chromium Buildbot Monitor"
+ "source_hash": "bbd36a3d1d5580b477929d081f5a3a467ad32c63",
+ "zip_path": "examples\/extensions\/buildbot.zip"
},
{
- "features": [
- "background_page",
- "experimental",
- "tabs"
- ],
- "icon": null,
- "description": "Add support to the omnibox to search the Chromium source code.",
- "search_string": "CHROMIUM SEARCH ADD SUPPORT TO THE OMNIBOX TO SEARCH THE CHROMIUM SOURCE CODE. BACKGROUND_PAGE EXPERIMENTAL TABS CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED CHROME.EXPERIMENTAL.OMNIBOX.STYLEMATCH CHROME.EXPERIMENTAL.OMNIBOX.STYLENONE CHROME.EXPERIMENTAL.OMNIBOX.STYLEURL CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE",
- "source_files": [
- "background.html",
- "manifest.json"
- ],
- "zip_path": "examples/extensions/chrome_search.zip",
- "path": "examples/extensions/chrome_search/",
"api_calls": [
- "chrome.experimental.omnibox.onInputChanged",
- "chrome.experimental.omnibox.onInputEntered",
- "chrome.experimental.omnibox.styleMatch",
- "chrome.experimental.omnibox.styleNone",
- "chrome.experimental.omnibox.styleUrl",
+ "chrome.omnibox.onInputChanged",
+ "chrome.omnibox.onInputEntered",
+ "chrome.omnibox.styleMatch",
+ "chrome.omnibox.styleUrl",
"chrome.tabs.get",
"chrome.tabs.getSelected",
"chrome.tabs.update"
],
- "id": "ac31228200b41a87982e386cc90d3a6eee4ad885",
- "protocols": [
- "http://"
- ],
- "name": "Chromium Search"
- },
- {
+ "description": "Add support to the omnibox to search the Chromium source code.",
"features": [
"background_page",
- "browser_action",
"tabs"
],
"icon": null,
- "description": "Displays the language of a tab",
- "search_string": "CLD DISPLAYS THE LANGUAGE OF A TAB BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.DETECTLANGUAGE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED",
+ "id": "ac31228200b41a87982e386cc90d3a6eee4ad885",
+ "name": "Chromium Search",
+ "path": "examples\/extensions\/chrome_search\/",
+ "protocols": [
+ "http:\/\/"
+ ],
+ "search_string": "CHROMIUM SEARCH ADD SUPPORT TO THE OMNIBOX TO SEARCH THE CHROMIUM SOURCE CODE. BACKGROUND_PAGE TABS CHROME.OMNIBOX.ONINPUTCHANGED CHROME.OMNIBOX.ONINPUTENTERED CHROME.OMNIBOX.STYLEMATCH CHROME.OMNIBOX.STYLEURL CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE",
"source_files": [
"background.html",
"manifest.json"
],
- "zip_path": "examples/api/i18n/cld.zip",
- "path": "examples/api/i18n/cld/",
+ "source_hash": "e8fce958ebb0661a38bf8f75b71fa66559ad8877",
+ "zip_path": "examples\/extensions\/chrome_search.zip"
+ },
+ {
"api_calls": [
"chrome.browserAction.setBadgeText",
"chrome.tabs.detectLanguage",
@@ -424,49 +417,49 @@
"chrome.tabs.onSelectionChanged",
"chrome.tabs.onUpdated"
],
+ "description": "Displays the language of a tab",
+ "features": [
+ "background_page",
+ "browser_action",
+ "tabs"
+ ],
+ "icon": null,
"id": "7d5d6cf195bc25480256618e360aa38c6e6fba82",
+ "name": "CLD",
+ "path": "examples\/api\/i18n\/cld\/",
"protocols": [],
- "name": "CLD"
+ "search_string": "CLD DISPLAYS THE LANGUAGE OF A TAB BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.DETECTLANGUAGE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED",
+ "source_files": [
+ "background.html",
+ "manifest.json"
+ ],
+ "source_hash": "913694d89e0b081f1ea5ad6f07b60b0141e82394",
+ "zip_path": "examples\/api\/i18n\/cld.zip"
},
{
+ "api_calls": [
+ "chrome.contextMenus.create"
+ ],
+ "description": "Shows some of the features of the Context Menus API",
"features": [
"background_page",
"contextMenus"
],
"icon": null,
- "description": "Shows some of the features of the Context Menus API",
+ "id": "5d81304a17cf7ac2887484f730fbd2b01e51e166",
+ "name": "Context Menus Sample",
+ "path": "examples\/api\/contextMenus\/basic\/",
+ "protocols": [],
"search_string": "CONTEXT MENUS SAMPLE SHOWS SOME OF THE FEATURES OF THE CONTEXT MENUS API BACKGROUND_PAGE CONTEXTMENUS CHROME.CONTEXTMENUS.CREATE",
"source_files": [
"background.html",
"manifest.json",
"sample.js"
],
- "zip_path": "examples/api/contextMenus/basic.zip",
- "path": "examples/api/contextMenus/basic/",
- "api_calls": [
- "chrome.contextMenus.create"
- ],
- "id": "5d81304a17cf7ac2887484f730fbd2b01e51e166",
- "protocols": [],
- "name": "Context Menus Sample"
+ "source_hash": "0e35ce268b3b2cf3d9830e6411c85c5dfef2ffdf",
+ "zip_path": "examples\/api\/contextMenus\/basic.zip"
},
{
- "features": [
- "background_page",
- "browser_action",
- "cookies",
- "tabs"
- ],
- "icon": "cookie.png",
- "description": "Testing Cookie API",
- "search_string": "COOKIE API TEST EXTENSION TESTING COOKIE API BACKGROUND_PAGE BROWSER_ACTION COOKIES TABS CHROME.BROWSERACTION.ONCLICKED CHROME.COOKIES.GET CHROME.COOKIES.GETALL CHROME.COOKIES.ONCHANGED CHROME.COOKIES.REMOVE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL",
- "source_files": [
- "background.html",
- "manager.html",
- "manifest.json"
- ],
- "zip_path": "examples/api/cookies.zip",
- "path": "examples/api/cookies/",
"api_calls": [
"chrome.browserAction.onClicked",
"chrome.cookies.get",
@@ -479,38 +472,65 @@
"chrome.windows.get",
"chrome.windows.getAll"
],
+ "description": "Testing Cookie API",
+ "features": [
+ "background_page",
+ "browser_action",
+ "cookies",
+ "tabs"
+ ],
+ "icon": "cookie.png",
"id": "4daa6becd0899a54776d9cf7f09613ed1a9f4d77",
+ "name": "Cookie API Test Extension",
+ "path": "examples\/api\/cookies\/",
"protocols": [
- "http://",
- "https://"
- ],
- "name": "Cookie API Test Extension"
- },
- {
- "features": [
- "background_page"
+ "http:\/\/",
+ "https:\/\/"
],
- "icon": "sample-128.png",
- "description": "Demonstrates a method to make a cross-domain XMLHttpRequest fetch from a content script. This extension fetches the current trending topics from Twitter and inserts them in an overlay at the top of Google News. Visit http://news.google.com to test this extension.",
- "search_string": "CROSS-DOMAIN XMLHTTPREQUEST FROM A CONTENT SCRIPT DEMONSTRATES A METHOD TO MAKE A CROSS-DOMAIN XMLHTTPREQUEST FETCH FROM A CONTENT SCRIPT. THIS EXTENSION FETCHES THE CURRENT TRENDING TOPICS FROM TWITTER AND INSERTS THEM IN AN OVERLAY AT THE TOP OF GOOGLE NEWS. VISIT HTTP://NEWS.GOOGLE.COM TO TEST THIS EXTENSION. BACKGROUND_PAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST",
+ "search_string": "COOKIE API TEST EXTENSION TESTING COOKIE API BACKGROUND_PAGE BROWSER_ACTION COOKIES TABS CHROME.BROWSERACTION.ONCLICKED CHROME.COOKIES.GET CHROME.COOKIES.GETALL CHROME.COOKIES.ONCHANGED CHROME.COOKIES.REMOVE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL",
"source_files": [
"background.html",
- "contentscript.js",
+ "manager.html",
"manifest.json"
],
- "zip_path": "examples/howto/contentscript_xhr.zip",
- "path": "examples/howto/contentscript_xhr/",
+ "source_hash": "d0741a5ff0ce9ac38a1be3e6abc46065d74cb498",
+ "zip_path": "examples\/api\/cookies.zip"
+ },
+ {
"api_calls": [
"chrome.extension.onRequest",
"chrome.extension.sendRequest"
],
+ "description": "Demonstrates a method to make a cross-domain XMLHttpRequest fetch from a content script. This extension fetches the current trending topics from Twitter and inserts them in an overlay at the top of Google News. Visit http:\/\/news.google.com to test this extension.",
+ "features": [
+ "background_page"
+ ],
+ "icon": "sample-128.png",
"id": "6871d09f4a96bf9d4b6cc724d00e909cee0f3902",
+ "name": "Cross-domain XMLHttpRequest from a content script",
+ "path": "examples\/howto\/contentscript_xhr\/",
"protocols": [
- "http://"
+ "http:\/\/"
+ ],
+ "search_string": "CROSS-DOMAIN XMLHTTPREQUEST FROM A CONTENT SCRIPT DEMONSTRATES A METHOD TO MAKE A CROSS-DOMAIN XMLHTTPREQUEST FETCH FROM A CONTENT SCRIPT. THIS EXTENSION FETCHES THE CURRENT TRENDING TOPICS FROM TWITTER AND INSERTS THEM IN AN OVERLAY AT THE TOP OF GOOGLE NEWS. VISIT HTTP:\/\/NEWS.GOOGLE.COM TO TEST THIS EXTENSION. BACKGROUND_PAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST",
+ "source_files": [
+ "background.html",
+ "contentscript.js",
+ "manifest.json"
],
- "name": "Cross-domain XMLHttpRequest from a content script"
+ "source_hash": "0fe56cea50dc18b7e5e31d47c383356a85d8b896",
+ "zip_path": "examples\/howto\/contentscript_xhr.zip"
},
{
+ "api_calls": [
+ "chrome.browserAction.onClicked",
+ "chrome.extension.connect",
+ "chrome.extension.onConnect",
+ "chrome.tabs.create",
+ "chrome.tabs.executeScript",
+ "chrome.tabs.update"
+ ],
+ "description": "This extension adds an email button to the toolbar which allows you to email the page link using your default mail client or Gmail.",
"features": [
"background_page",
"browser_action",
@@ -518,7 +538,13 @@
"tabs"
],
"icon": "mail_128x128.png",
- "description": "This extension adds an email button to the toolbar which allows you to email the page link using your default mail client or Gmail.",
+ "id": "028eb5364924344029bcbe1d527f132fc72b34e5",
+ "name": "Email this page (by Google)",
+ "path": "examples\/extensions\/email_this_page\/",
+ "protocols": [
+ "http:\/\/",
+ "https:\/\/"
+ ],
"search_string": "EMAIL THIS PAGE (BY GOOGLE) THIS EXTENSION ADDS AN EMAIL BUTTON TO THE TOOLBAR WHICH ALLOWS YOU TO EMAIL THE PAGE LINK USING YOUR DEFAULT MAIL CLIENT OR GMAIL. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.CONNECT CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.UPDATE",
"source_files": [
"background.html",
@@ -526,31 +552,22 @@
"manifest.json",
"options.html"
],
- "zip_path": "examples/extensions/email_this_page.zip",
- "path": "examples/extensions/email_this_page/",
- "api_calls": [
- "chrome.browserAction.onClicked",
- "chrome.extension.connect",
- "chrome.extension.onConnect",
- "chrome.tabs.create",
- "chrome.tabs.executeScript",
- "chrome.tabs.update"
- ],
- "id": "028eb5364924344029bcbe1d527f132fc72b34e5",
- "protocols": [
- "http://",
- "https://"
- ],
- "name": "Email this page (by Google)"
+ "source_hash": "54b5469031ddcb2097f39dbaae1bcd81ae650154",
+ "zip_path": "examples\/extensions\/email_this_page.zip"
},
{
+ "api_calls": [],
+ "description": "A sample extension which uses Google Analytics to track usage.",
"features": [
"background_page",
"browser_action",
"popup"
],
"icon": "analytics-extension-icon-128.png",
- "description": "A sample extension which uses Google Analytics to track usage.",
+ "id": "763a08e9b06595d785568a8d392b95a2f3700258",
+ "name": "Event Tracking with Google Analytics",
+ "path": "examples\/tutorials\/analytics\/",
+ "protocols": [],
"search_string": "EVENT TRACKING WITH GOOGLE ANALYTICS A SAMPLE EXTENSION WHICH USES GOOGLE ANALYTICS TO TRACK USAGE. BACKGROUND_PAGE BROWSER_ACTION POPUP",
"source_files": [
"analytics.js",
@@ -558,67 +575,85 @@
"manifest.json",
"popup.html"
],
- "zip_path": "examples/tutorials/analytics.zip",
- "path": "examples/tutorials/analytics/",
- "api_calls": [],
- "id": "763a08e9b06595d785568a8d392b95a2f3700258",
- "protocols": [],
- "name": "Event Tracking with Google Analytics"
+ "source_hash": "b02f040a3eb56f8a0e780549954f69172d62dcd3",
+ "zip_path": "examples\/tutorials\/analytics.zip"
},
{
+ "api_calls": [
+ "chrome.omnibox.onInputChanged",
+ "chrome.omnibox.onInputEntered",
+ "chrome.omnibox.styleMatch",
+ "chrome.tabs.create",
+ "chrome.tabs.get",
+ "chrome.tabs.onRemoved",
+ "chrome.tabs.update"
+ ],
+ "description": "Search the Chrome Extensions documentation. To use, type 'crdoc' plus a search term into the Omnibox.",
"features": [
"background_page",
- "experimental",
"tabs"
],
"icon": "icon-128.png",
- "description": "Search the Chrome Extensions documentation. To use, type 'crdoc' plus a search term into the Omnibox.",
- "search_string": "EXTENSION DOCS SEARCH SEARCH THE CHROME EXTENSIONS DOCUMENTATION. TO USE, TYPE CRDOC PLUS A SEARCH TERM INTO THE OMNIBOX. BACKGROUND_PAGE EXPERIMENTAL TABS CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED CHROME.EXPERIMENTAL.OMNIBOX.STYLEMATCH CHROME.EXPERIMENTAL.OMNIBOX.STYLENONE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.ONREMOVED CHROME.TABS.UPDATE",
+ "id": "e3df888a89e35bdeb9c8bc8d03be5e1851b97c68",
+ "name": "Extension Docs Search",
+ "path": "examples\/api\/omnibox\/extension-docs\/",
+ "protocols": [
+ "http:\/\/"
+ ],
+ "search_string": "EXTENSION DOCS SEARCH SEARCH THE CHROME EXTENSIONS DOCUMENTATION. TO USE, TYPE CRDOC PLUS A SEARCH TERM INTO THE OMNIBOX. BACKGROUND_PAGE TABS CHROME.OMNIBOX.ONINPUTCHANGED CHROME.OMNIBOX.ONINPUTENTERED CHROME.OMNIBOX.STYLEMATCH CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.ONREMOVED CHROME.TABS.UPDATE",
"source_files": [
"background.html",
"manifest.json"
],
- "zip_path": "examples/api/omnibox/extension-docs.zip",
- "path": "examples/api/omnibox/extension-docs/",
+ "source_hash": "041b3aeae42eefd5eba6458bc6e3e051590716b7",
+ "zip_path": "examples\/api\/omnibox\/extension-docs.zip"
+ },
+ {
"api_calls": [
- "chrome.experimental.omnibox.onInputChanged",
- "chrome.experimental.omnibox.onInputEntered",
- "chrome.experimental.omnibox.styleMatch",
- "chrome.experimental.omnibox.styleNone",
+ "chrome.browserAction.onClicked",
+ "chrome.browserAction.setBadgeBackgroundColor",
+ "chrome.browserAction.setBadgeText",
+ "chrome.browserAction.setIcon",
+ "chrome.browserAction.setTitle",
+ "chrome.extension.getBackgroundPage",
+ "chrome.extension.onRequest",
+ "chrome.extension.sendRequest",
+ "chrome.i18n.getMessage",
"chrome.tabs.create",
"chrome.tabs.get",
- "chrome.tabs.onRemoved",
+ "chrome.tabs.getAllInWindow",
+ "chrome.tabs.onUpdated",
"chrome.tabs.update"
],
- "id": "e3df888a89e35bdeb9c8bc8d03be5e1851b97c68",
- "protocols": [
- "http://"
- ],
- "name": "Extension Docs Search"
- },
- {
+ "description": "Quickly see the time until your next meeting from any of your calendars. Click on the button to be taken to your calendar.",
"features": [
"background_page",
"browser_action",
"options_page",
- "popup",
"tabs"
],
- "icon": "img/docs_spreadsheets-128.gif",
- "description": "Demonstrates how to use OAuth to connect the Google Documents List Data API.",
- "search_string": "GOOGLE DOCUMENT LIST VIEWER DEMONSTRATES HOW TO USE OAUTH TO CONNECT THE GOOGLE DOCUMENTS LIST DATA API. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE",
+ "icon": "images\/icon-128.gif",
+ "id": "8b0dd31216235941bdd8eb33fda915ef5cf79a82",
+ "name": "Google Calendar Checker (by Google)",
+ "path": "examples\/extensions\/calendar\/",
+ "protocols": [
+ "http:\/\/",
+ "https:\/\/"
+ ],
+ "search_string": "GOOGLE CALENDAR CHECKER (BY GOOGLE) QUICKLY SEE THE TIME UNTIL YOUR NEXT MEETING FROM ANY OF YOUR CALENDARS. CLICK ON THE BUTTON TO BE TAKEN TO YOUR CALENDAR. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETICON CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.ONUPDATED CHROME.TABS.UPDATE",
"source_files": [
- "background.html",
- "chrome_ex_oauth.html",
- "chrome_ex_oauth.js",
- "chrome_ex_oauthsimple.js",
- "js/jquery-1.4.1.min.js",
+ "_locales\/en\/messages.json",
+ "javascript\/background.js",
+ "javascript\/options.js",
+ "javascript\/util.js",
"manifest.json",
- "options.html",
- "popup.html"
+ "views\/background.html",
+ "views\/options.html"
],
- "zip_path": "examples/extensions/gdocs.zip",
- "path": "examples/extensions/gdocs/",
+ "source_hash": "3d9782a3e8315bbbca36c63297db2c8926df4521",
+ "zip_path": "examples\/extensions\/calendar.zip"
+ },
+ {
"api_calls": [
"chrome.browserAction.setBadgeText",
"chrome.extension.getBackgroundPage",
@@ -629,74 +664,39 @@
"chrome.tabs.onUpdated",
"chrome.tabs.remove"
],
- "id": "4e35caa9742fb82dbd628892d23a781614f6eff6",
- "protocols": [
- "https://",
- "https://",
- "https://",
- "https://"
- ],
- "name": "Google Document List Viewer"
- },
- {
+ "description": "Demonstrates how to use OAuth to connect the Google Documents List Data API.",
"features": [
"background_page",
"browser_action",
"options_page",
+ "popup",
"tabs"
],
- "icon": "icon_128.png",
- "description": "Displays the number of unread messages in your Google Mail inbox. You can also click the button to open your inbox.",
- "search_string": "GOOGLE MAIL CHECKER DISPLAYS THE NUMBER OF UNREAD MESSAGES IN YOUR GOOGLE MAIL INBOX. YOU CAN ALSO CLICK THE BUTTON TO OPEN YOUR INBOX. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.ONUPDATED CHROME.TABS.UPDATE",
+ "icon": "img\/docs_spreadsheets-128.gif",
+ "id": "4e35caa9742fb82dbd628892d23a781614f6eff6",
+ "name": "Google Document List Viewer",
+ "path": "examples\/extensions\/gdocs\/",
+ "protocols": [
+ "https:\/\/",
+ "https:\/\/",
+ "https:\/\/",
+ "https:\/\/"
+ ],
+ "search_string": "GOOGLE DOCUMENT LIST VIEWER DEMONSTRATES HOW TO USE OAUTH TO CONNECT THE GOOGLE DOCUMENTS LIST DATA API. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE",
"source_files": [
- "_locales/ar/messages.json",
- "_locales/bg/messages.json",
- "_locales/ca/messages.json",
- "_locales/cs/messages.json",
- "_locales/da/messages.json",
- "_locales/de/messages.json",
- "_locales/el/messages.json",
- "_locales/en/messages.json",
- "_locales/en_GB/messages.json",
- "_locales/es/messages.json",
- "_locales/es_419/messages.json",
- "_locales/et/messages.json",
- "_locales/fi/messages.json",
- "_locales/fil/messages.json",
- "_locales/fr/messages.json",
- "_locales/he/messages.json",
- "_locales/hi/messages.json",
- "_locales/hr/messages.json",
- "_locales/hu/messages.json",
- "_locales/id/messages.json",
- "_locales/it/messages.json",
- "_locales/ja/messages.json",
- "_locales/ko/messages.json",
- "_locales/lt/messages.json",
- "_locales/lv/messages.json",
- "_locales/nb/messages.json",
- "_locales/nl/messages.json",
- "_locales/pl/messages.json",
- "_locales/pt_BR/messages.json",
- "_locales/pt_PT/messages.json",
- "_locales/ro/messages.json",
- "_locales/ru/messages.json",
- "_locales/sk/messages.json",
- "_locales/sl/messages.json",
- "_locales/sr/messages.json",
- "_locales/sv/messages.json",
- "_locales/th/messages.json",
- "_locales/tr/messages.json",
- "_locales/uk/messages.json",
- "_locales/vi/messages.json",
- "_locales/zh_CN/messages.json",
- "_locales/zh_TW/messages.json",
"background.html",
+ "chrome_ex_oauth.html",
+ "chrome_ex_oauth.js",
+ "chrome_ex_oauthsimple.js",
+ "js\/jquery-1.4.1.min.js",
"manifest.json",
- "options.html"
+ "options.html",
+ "popup.html"
],
- "zip_path": "examples/extensions/gmail.zip",
- "path": "examples/extensions/gmail/",
+ "source_hash": "284e44d603a62348dd1b7e98e593f3f4b877b124",
+ "zip_path": "examples\/extensions\/gdocs.zip"
+ },
+ {
"api_calls": [
"chrome.browserAction.onClicked",
"chrome.browserAction.setBadgeBackgroundColor",
@@ -710,14 +710,83 @@
"chrome.tabs.onUpdated",
"chrome.tabs.update"
],
+ "description": "Displays the number of unread messages in your Google Mail inbox. You can also click the button to open your inbox.",
+ "features": [
+ "background_page",
+ "browser_action",
+ "options_page",
+ "tabs"
+ ],
+ "icon": "icon_128.png",
"id": "bb57f7a0132cbeb36ad7e7bb0ab75c21704234ca",
+ "name": "Google Mail Checker",
+ "path": "examples\/extensions\/gmail\/",
"protocols": [
- "http://",
- "https://"
+ "http:\/\/",
+ "https:\/\/"
+ ],
+ "search_string": "GOOGLE MAIL CHECKER DISPLAYS THE NUMBER OF UNREAD MESSAGES IN YOUR GOOGLE MAIL INBOX. YOU CAN ALSO CLICK THE BUTTON TO OPEN YOUR INBOX. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.ONUPDATED CHROME.TABS.UPDATE",
+ "source_files": [
+ "_locales\/ar\/messages.json",
+ "_locales\/bg\/messages.json",
+ "_locales\/ca\/messages.json",
+ "_locales\/cs\/messages.json",
+ "_locales\/da\/messages.json",
+ "_locales\/de\/messages.json",
+ "_locales\/el\/messages.json",
+ "_locales\/en\/messages.json",
+ "_locales\/en_GB\/messages.json",
+ "_locales\/es\/messages.json",
+ "_locales\/es_419\/messages.json",
+ "_locales\/et\/messages.json",
+ "_locales\/fi\/messages.json",
+ "_locales\/fil\/messages.json",
+ "_locales\/fr\/messages.json",
+ "_locales\/he\/messages.json",
+ "_locales\/hi\/messages.json",
+ "_locales\/hr\/messages.json",
+ "_locales\/hu\/messages.json",
+ "_locales\/id\/messages.json",
+ "_locales\/it\/messages.json",
+ "_locales\/ja\/messages.json",
+ "_locales\/ko\/messages.json",
+ "_locales\/lt\/messages.json",
+ "_locales\/lv\/messages.json",
+ "_locales\/nb\/messages.json",
+ "_locales\/nl\/messages.json",
+ "_locales\/pl\/messages.json",
+ "_locales\/pt_BR\/messages.json",
+ "_locales\/pt_PT\/messages.json",
+ "_locales\/ro\/messages.json",
+ "_locales\/ru\/messages.json",
+ "_locales\/sk\/messages.json",
+ "_locales\/sl\/messages.json",
+ "_locales\/sr\/messages.json",
+ "_locales\/sv\/messages.json",
+ "_locales\/th\/messages.json",
+ "_locales\/tr\/messages.json",
+ "_locales\/uk\/messages.json",
+ "_locales\/vi\/messages.json",
+ "_locales\/zh_CN\/messages.json",
+ "_locales\/zh_TW\/messages.json",
+ "background.html",
+ "manifest.json",
+ "options.html"
],
- "name": "Google Mail Checker"
+ "source_hash": "030b77992ed5bbbbc18f1b717bc330b965b26aaf",
+ "zip_path": "examples\/extensions\/gmail.zip"
},
{
+ "api_calls": [
+ "chrome.extension.getBackgroundPage",
+ "chrome.extension.getURL",
+ "chrome.tabs.create",
+ "chrome.tabs.get",
+ "chrome.tabs.getSelected",
+ "chrome.tabs.onUpdated",
+ "chrome.tabs.remove"
+ ],
+ "description": "Find out when you have new waves and preview them fast.",
"features": [
"background_page",
"browser_action",
@@ -726,7 +795,13 @@
"tabs"
],
"icon": "128.png",
- "description": "Find out when you have new waves and preview them fast.",
+ "id": "1682e05ea9a1bde985123b04f6f8ac50a8a64033",
+ "name": "Google Wave Notifier",
+ "path": "examples\/extensions\/wave\/",
+ "protocols": [
+ "https:\/\/",
+ "http:\/\/"
+ ],
"search_string": "GOOGLE WAVE NOTIFIER FIND OUT WHEN YOU HAVE NEW WAVES AND PREVIEW THEM FAST. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE",
"source_files": [
"background.html",
@@ -738,108 +813,78 @@
"popup.html",
"prettyload.js"
],
- "zip_path": "examples/extensions/wave.zip",
- "path": "examples/extensions/wave/",
- "api_calls": [
- "chrome.extension.getBackgroundPage",
- "chrome.extension.getURL",
- "chrome.tabs.create",
- "chrome.tabs.get",
- "chrome.tabs.getSelected",
- "chrome.tabs.onUpdated",
- "chrome.tabs.remove"
- ],
- "id": "1682e05ea9a1bde985123b04f6f8ac50a8a64033",
- "protocols": [
- "https://",
- "http://"
- ],
- "name": "Google Wave Notifier"
+ "source_hash": "9f360bf8772e8a23862d854ea088e0bec867ba02",
+ "zip_path": "examples\/extensions\/wave.zip"
},
{
+ "api_calls": [],
+ "description": "The first extension that I made.",
"features": [
"browser_action",
"popup"
],
"icon": null,
- "description": "The first extension that I made.",
+ "id": "14b9651fda4e57b2a5914ba73a779812201b750a",
+ "name": "Hello World",
+ "path": "examples\/tutorials\/getstarted\/",
+ "protocols": [
+ "http:\/\/"
+ ],
"search_string": "HELLO WORLD THE FIRST EXTENSION THAT I MADE. BROWSER_ACTION POPUP",
"source_files": [
"manifest.json",
"popup.html"
],
- "zip_path": "examples/tutorials/getstarted.zip",
- "path": "examples/tutorials/getstarted/",
- "api_calls": [],
- "id": "14b9651fda4e57b2a5914ba73a779812201b750a",
- "protocols": [
- "http://"
- ],
- "name": "Hello World"
+ "source_hash": "1a3139dcb7f3e3499023703643e7056c61235123",
+ "zip_path": "examples\/tutorials\/getstarted.zip"
},
{
+ "api_calls": [
+ "chrome.browserAction.onClicked",
+ "chrome.extension.getBackgroundPage",
+ "chrome.idle.onStateChanged",
+ "chrome.idle.queryState"
+ ],
+ "description": "Demonstrates the Idle API",
"features": [
"background_page",
"browser_action",
"idle"
],
"icon": "sample-128.png",
- "description": "Demonstrates the Idle API",
+ "id": "2020d72f2577f53caf8e94e3dbac0fb849ceaa4d",
+ "name": "Idle - Simple Example",
+ "path": "examples\/api\/idle\/idle_simple\/",
+ "protocols": [],
"search_string": "IDLE - SIMPLE EXAMPLE DEMONSTRATES THE IDLE API BACKGROUND_PAGE BROWSER_ACTION IDLE CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.IDLE.ONSTATECHANGED CHROME.IDLE.QUERYSTATE",
"source_files": [
"background.html",
"history.html",
"manifest.json"
],
- "zip_path": "examples/api/idle/idle_simple.zip",
- "path": "examples/api/idle/idle_simple/",
- "api_calls": [
- "chrome.browserAction.onClicked",
- "chrome.extension.getBackgroundPage",
- "chrome.idle.onStateChanged",
- "chrome.idle.queryState"
- ],
- "id": "2020d72f2577f53caf8e94e3dbac0fb849ceaa4d",
- "protocols": [],
- "name": "Idle - Simple Example"
+ "source_hash": "1378042fee96e115d7b8003588eca369b43f772b",
+ "zip_path": "examples\/api\/idle\/idle_simple.zip"
},
{
+ "api_calls": [],
+ "description": "",
"features": [
"chrome_url_overrides"
],
"icon": null,
- "description": "",
+ "id": "0ea1588bd07b20338fc21f725de1542a5fdf9726",
+ "name": "iGoogle new tab page",
+ "path": "examples\/api\/override\/override_igoogle\/",
+ "protocols": [],
"search_string": "IGOOGLE NEW TAB PAGE CHROME_URL_OVERRIDES",
"source_files": [
"manifest.json",
"redirect.html"
],
- "zip_path": "examples/api/override/override_igoogle.zip",
- "path": "examples/api/override/override_igoogle/",
- "api_calls": [],
- "id": "0ea1588bd07b20338fc21f725de1542a5fdf9726",
- "protocols": [],
- "name": "iGoogle new tab page"
+ "source_hash": "8ee76608adbf87c3260f9905e6cb1c8a45bd8e0c",
+ "zip_path": "examples\/api\/override\/override_igoogle.zip"
},
{
- "features": [
- "background_page",
- "contextMenus",
- "tabs"
- ],
- "icon": "imageinfo-128.png",
- "description": "Get image info for images, including EXIF data",
- "search_string": "IMAGEINFO GET IMAGE INFO FOR IMAGES, INCLUDING EXIF DATA BACKGROUND_PAGE CONTEXTMENUS TABS CHROME.CONTEXTMENUS.CREATE CHROME.TABS.GET CHROME.TABS.GETCURRENT CHROME.WINDOWS.CREATE CHROME.WINDOWS.UPDATE",
- "source_files": [
- "background.html",
- "imageinfo/binaryajax.js",
- "imageinfo/exif.js",
- "imageinfo/imageinfo.js",
- "info.html",
- "manifest.json"
- ],
- "zip_path": "examples/extensions/imageinfo.zip",
- "path": "examples/extensions/imageinfo/",
"api_calls": [
"chrome.contextMenus.create",
"chrome.tabs.get",
@@ -847,31 +892,33 @@
"chrome.windows.create",
"chrome.windows.update"
],
- "id": "646325c25f572a1d15edc73d057f821d847a4fbe",
- "protocols": [
- "http://",
- "https://"
- ],
- "name": "Imageinfo"
- },
- {
+ "description": "Get image info for images, including EXIF data",
"features": [
"background_page",
- "page_action",
- "popup",
+ "contextMenus",
"tabs"
],
- "icon": "icon.png",
- "description": "Finds addresses in the web page you're on and pops up a map window.",
- "search_string": "MAPPY FINDS ADDRESSES IN THE WEB PAGE YOURE ON AND POPS UP A MAP WINDOW. BACKGROUND_PAGE PAGE_ACTION POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.SENDREQUEST",
+ "icon": "imageinfo-128.png",
+ "id": "646325c25f572a1d15edc73d057f821d847a4fbe",
+ "name": "Imageinfo",
+ "path": "examples\/extensions\/imageinfo\/",
+ "protocols": [
+ "http:\/\/",
+ "https:\/\/"
+ ],
+ "search_string": "IMAGEINFO GET IMAGE INFO FOR IMAGES, INCLUDING EXIF DATA BACKGROUND_PAGE CONTEXTMENUS TABS CHROME.CONTEXTMENUS.CREATE CHROME.TABS.GET CHROME.TABS.GETCURRENT CHROME.WINDOWS.CREATE CHROME.WINDOWS.UPDATE",
"source_files": [
"background.html",
- "manifest.json",
- "mappy_content_script.js",
- "popup.html"
+ "imageinfo\/binaryajax.js",
+ "imageinfo\/exif.js",
+ "imageinfo\/imageinfo.js",
+ "info.html",
+ "manifest.json"
],
- "zip_path": "examples/extensions/mappy.zip",
- "path": "examples/extensions/mappy/",
+ "source_hash": "c746d9114348f4b414c1ec05e988e2807feb963a",
+ "zip_path": "examples\/extensions\/imageinfo.zip"
+ },
+ {
"api_calls": [
"chrome.extension.getBackgroundPage",
"chrome.extension.onRequest",
@@ -884,27 +931,31 @@
"chrome.tabs.onUpdated",
"chrome.tabs.sendRequest"
],
- "id": "ec97ec20ca2f095d081e39f1565fc12af09ef067",
- "protocols": [
- "http://"
- ],
- "name": "Mappy"
- },
- {
+ "description": "Finds addresses in the web page you're on and pops up a map window.",
"features": [
"background_page",
- "browser_action",
+ "page_action",
+ "popup",
"tabs"
],
- "icon": "merge_windows_128.png",
- "description": "Merges all of the browser's windows into the current window",
- "search_string": "MERGE WINDOWS MERGES ALL OF THE BROWSERS WINDOWS INTO THE CURRENT WINDOW BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.MOVE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT",
+ "icon": "icon.png",
+ "id": "ec97ec20ca2f095d081e39f1565fc12af09ef067",
+ "name": "Mappy",
+ "path": "examples\/extensions\/mappy\/",
+ "protocols": [
+ "http:\/\/"
+ ],
+ "search_string": "MAPPY FINDS ADDRESSES IN THE WEB PAGE YOURE ON AND POPS UP A MAP WINDOW. BACKGROUND_PAGE PAGE_ACTION POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.SENDREQUEST",
"source_files": [
"background.html",
- "manifest.json"
+ "manifest.json",
+ "mappy_content_script.js",
+ "popup.html"
],
- "zip_path": "examples/api/windows/merge_windows.zip",
- "path": "examples/api/windows/merge_windows/",
+ "source_hash": "81cf2d3975d7df8b58e5226c5b2b6df026446511",
+ "zip_path": "examples\/extensions\/mappy.zip"
+ },
+ {
"api_calls": [
"chrome.browserAction.onClicked",
"chrome.tabs.get",
@@ -914,26 +965,26 @@
"chrome.windows.getAll",
"chrome.windows.getCurrent"
],
- "id": "b2f5f8a790e16f091a7e4e0a39b2d0a6d32e3a6d",
- "protocols": [],
- "name": "Merge Windows"
- },
- {
+ "description": "Merges all of the browser's windows into the current window",
"features": [
+ "background_page",
"browser_action",
- "popup",
"tabs"
],
- "icon": null,
- "description": "Times how long it takes to send a message to a content script and back.",
- "search_string": "MESSAGE TIMER TIMES HOW LONG IT TAKES TO SEND A MESSAGE TO A CONTENT SCRIPT AND BACK. BROWSER_ACTION POPUP TABS CHROME.EXTENSION.ONCONNECT CHROME.EXTENSION.ONREQUEST CHROME.TABS.CONNECT CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.SENDREQUEST",
+ "icon": "merge_windows_128.png",
+ "id": "b2f5f8a790e16f091a7e4e0a39b2d0a6d32e3a6d",
+ "name": "Merge Windows",
+ "path": "examples\/api\/windows\/merge_windows\/",
+ "protocols": [],
+ "search_string": "MERGE WINDOWS MERGES ALL OF THE BROWSERS WINDOWS INTO THE CURRENT WINDOW BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.MOVE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT",
"source_files": [
- "manifest.json",
- "page.js",
- "popup.html"
+ "background.html",
+ "manifest.json"
],
- "zip_path": "examples/api/messaging/timer.zip",
- "path": "examples/api/messaging/timer/",
+ "source_hash": "4b5fe52788e0bef2f3871b36105eb53cc760c454",
+ "zip_path": "examples\/api\/windows\/merge_windows.zip"
+ },
+ {
"api_calls": [
"chrome.extension.onConnect",
"chrome.extension.onRequest",
@@ -942,26 +993,27 @@
"chrome.tabs.getSelected",
"chrome.tabs.sendRequest"
],
- "id": "51a83d2ba3a32e3ff1bdb624d4e18ccec4c4038e",
- "protocols": [],
- "name": "Message Timer"
- },
- {
+ "description": "Times how long it takes to send a message to a content script and back.",
"features": [
- "bookmarks",
"browser_action",
"popup",
"tabs"
],
"icon": null,
- "description": "A browser action with a popup dump of all bookmarks, including search, add, edit and delete.",
- "search_string": "MY BOOKMARKS A BROWSER ACTION WITH A POPUP DUMP OF ALL BOOKMARKS, INCLUDING SEARCH, ADD, EDIT AND DELETE. BOOKMARKS BROWSER_ACTION POPUP TABS CHROME.BOOKMARKS.CREATE CHROME.BOOKMARKS.GET CHROME.BOOKMARKS.GETTREE CHROME.BOOKMARKS.REMOVE CHROME.BOOKMARKS.UPDATE CHROME.TABS.CREATE",
+ "id": "51a83d2ba3a32e3ff1bdb624d4e18ccec4c4038e",
+ "name": "Message Timer",
+ "path": "examples\/api\/messaging\/timer\/",
+ "protocols": [],
+ "search_string": "MESSAGE TIMER TIMES HOW LONG IT TAKES TO SEND A MESSAGE TO A CONTENT SCRIPT AND BACK. BROWSER_ACTION POPUP TABS CHROME.EXTENSION.ONCONNECT CHROME.EXTENSION.ONREQUEST CHROME.TABS.CONNECT CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.SENDREQUEST",
"source_files": [
"manifest.json",
+ "page.js",
"popup.html"
],
- "zip_path": "examples/api/bookmarks/basic.zip",
- "path": "examples/api/bookmarks/basic/",
+ "source_hash": "927cf398a95a665beb64f56a4bfb791b98a8ee96",
+ "zip_path": "examples\/api\/messaging\/timer.zip"
+ },
+ {
"api_calls": [
"chrome.bookmarks.create",
"chrome.bookmarks.get",
@@ -970,88 +1022,123 @@
"chrome.bookmarks.update",
"chrome.tabs.create"
],
- "id": "4f6785ec4f937add6728615682dd37c9a42d9548",
- "protocols": [],
- "name": "My Bookmarks"
- },
- {
+ "description": "A browser action with a popup dump of all bookmarks, including search, add, edit and delete.",
"features": [
+ "bookmarks",
"browser_action",
"popup",
"tabs"
],
- "icon": "news_icon.png",
- "description": "Displays the first 5 items from the 'Google News - top news' RSS feed in a popup.",
- "search_string": "NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.TABS.CREATE",
+ "icon": null,
+ "id": "4f6785ec4f937add6728615682dd37c9a42d9548",
+ "name": "My Bookmarks",
+ "path": "examples\/api\/bookmarks\/basic\/",
+ "protocols": [],
+ "search_string": "MY BOOKMARKS A BROWSER ACTION WITH A POPUP DUMP OF ALL BOOKMARKS, INCLUDING SEARCH, ADD, EDIT AND DELETE. BOOKMARKS BROWSER_ACTION POPUP TABS CHROME.BOOKMARKS.CREATE CHROME.BOOKMARKS.GET CHROME.BOOKMARKS.GETTREE CHROME.BOOKMARKS.REMOVE CHROME.BOOKMARKS.UPDATE CHROME.TABS.CREATE",
"source_files": [
- "feed.html",
- "manifest.json"
+ "manifest.json",
+ "popup.html"
],
- "zip_path": "examples/extensions/news.zip",
- "path": "examples/extensions/news/",
+ "source_hash": "4f7509c56c2943cf8aedf1ee0b4b4a7d1e49f7d3",
+ "zip_path": "examples\/api\/bookmarks\/basic.zip"
+ },
+ {
"api_calls": [
"chrome.tabs.create"
],
- "id": "3aea027164cb9b732ba4a8c51cb93708891726ef",
- "protocols": [
- "http://"
- ],
- "name": "News Reader"
- },
- {
+ "description": "Displays the first 5 items from the 'Google News - top news' RSS feed in a popup.",
"features": [
"browser_action",
"popup",
"tabs"
],
"icon": "news_icon.png",
- "description": "Displays the first 5 items from the 'Google News - top news' RSS feed in a popup.",
+ "id": "597015d3bcce3da693b02314afd607bec4f55291",
+ "name": "News Reader",
+ "path": "examples\/extensions\/news_a11y\/",
+ "protocols": [
+ "http:\/\/"
+ ],
"search_string": "NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.TABS.CREATE",
"source_files": [
"feed.html",
"manifest.json"
],
- "zip_path": "examples/extensions/news_a11y.zip",
- "path": "examples/extensions/news_a11y/",
+ "source_hash": "af7474bf0d3ef1a407f27ae0900167a1408ead35",
+ "zip_path": "examples\/extensions\/news_a11y.zip"
+ },
+ {
"api_calls": [
+ "chrome.i18n.getMessage",
"chrome.tabs.create"
],
- "id": "597015d3bcce3da693b02314afd607bec4f55291",
- "protocols": [
- "http://"
- ],
- "name": "News Reader"
- },
- {
+ "description": "Displays the first 5 items from the 'Google News - top news' RSS feed in a popup.",
"features": [
"browser_action",
"popup",
"tabs"
],
"icon": "news_icon.png",
- "description": "Displays the first 5 items from the 'Google News - top news' RSS feed in a popup.",
+ "id": "6444e5c8ae112a6a433909c5e770669cd16e2e5f",
+ "name": "News Reader",
+ "path": "examples\/extensions\/news_i18n\/",
+ "protocols": [
+ "http:\/\/",
+ "http:\/\/"
+ ],
"search_string": "NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE",
"source_files": [
- "_locales/en/messages.json",
- "_locales/es/messages.json",
- "_locales/sr/messages.json",
+ "_locales\/en\/messages.json",
+ "_locales\/es\/messages.json",
+ "_locales\/sr\/messages.json",
"feed.html",
"manifest.json"
],
- "zip_path": "examples/extensions/news_i18n.zip",
- "path": "examples/extensions/news_i18n/",
+ "source_hash": "381268f1183beaeba8d6596e736dc2c00a55fd21",
+ "zip_path": "examples\/extensions\/news_i18n.zip"
+ },
+ {
"api_calls": [
+ "chrome.extension.getURL",
"chrome.i18n.getMessage",
"chrome.tabs.create"
],
- "id": "6444e5c8ae112a6a433909c5e770669cd16e2e5f",
+ "description": "Displays the latest stories from Google News in a popup.",
+ "features": [
+ "background_page",
+ "browser_action",
+ "options_page",
+ "popup",
+ "tabs"
+ ],
+ "icon": "images\/news_icon.png",
+ "id": "3aea027164cb9b732ba4a8c51cb93708891726ef",
+ "name": "News Reader (by Google)",
+ "path": "examples\/extensions\/news\/",
"protocols": [
- "http://",
- "http://"
+ "http:\/\/"
+ ],
+ "search_string": "NEWS READER (BY GOOGLE) DISPLAYS THE LATEST STORIES FROM GOOGLE NEWS IN A POPUP. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.EXTENSION.GETURL CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE",
+ "source_files": [
+ "_locales\/en\/messages.json",
+ "css\/feed.css",
+ "css\/options.css",
+ "javascript\/feed.js",
+ "javascript\/options.js",
+ "javascript\/util.js",
+ "manifest.json",
+ "views\/background.html",
+ "views\/feed.html",
+ "views\/options.html"
],
- "name": "News Reader"
+ "source_hash": "cc21920e101dd4d4c535f4842e3f0ab4be285166",
+ "zip_path": "examples\/extensions\/news.zip"
},
{
+ "api_calls": [
+ "chrome.tabs.create"
+ ],
+ "description": "Shows off desktop notifications, which are \"toast\" windows that pop up on the desktop.",
"features": [
"background_page",
"notifications",
@@ -1059,7 +1146,10 @@
"tabs"
],
"icon": "128.png",
- "description": "Shows off desktop notifications, which are \"toast\" windows that pop up on the desktop.",
+ "id": "f799e26ceef2367cf836f24bcb47df4398b0df58",
+ "name": "Notification Demo",
+ "path": "examples\/api\/notifications\/",
+ "protocols": [],
"search_string": "NOTIFICATION DEMO SHOWS OFF DESKTOP NOTIFICATIONS, WHICH ARE TOAST WINDOWS THAT POP UP ON THE DESKTOP. BACKGROUND_PAGE NOTIFICATIONS OPTIONS_PAGE TABS CHROME.TABS.CREATE",
"source_files": [
"background.html",
@@ -1067,116 +1157,81 @@
"manifest.json",
"options.html"
],
- "zip_path": "examples/api/notifications.zip",
- "path": "examples/api/notifications/",
- "api_calls": [
- "chrome.tabs.create"
- ],
- "id": "f799e26ceef2367cf836f24bcb47df4398b0df58",
- "protocols": [],
- "name": "Notification Demo"
+ "source_hash": "bc2985ef75d717779cb6e1e523a3e063067c3494",
+ "zip_path": "examples\/api\/notifications.zip"
},
{
+ "api_calls": [
+ "chrome.omnibox.onInputChanged",
+ "chrome.omnibox.onInputEntered"
+ ],
+ "description": "To use, type 'omnix' plus a search term into the Omnibox.",
"features": [
- "background_page",
- "experimental"
+ "background_page"
],
"icon": null,
- "description": "To use, type 'omnix' plus a search term into the Omnibox.",
- "search_string": "OMNIBOX EXAMPLE TO USE, TYPE OMNIX PLUS A SEARCH TERM INTO THE OMNIBOX. BACKGROUND_PAGE EXPERIMENTAL CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED",
+ "id": "e787b322bddbc6289bb31b7d7550b1bf6456a80b",
+ "name": "Omnibox Example",
+ "path": "examples\/api\/omnibox\/simple-example\/",
+ "protocols": [],
+ "search_string": "OMNIBOX EXAMPLE TO USE, TYPE OMNIX PLUS A SEARCH TERM INTO THE OMNIBOX. BACKGROUND_PAGE CHROME.OMNIBOX.ONINPUTCHANGED CHROME.OMNIBOX.ONINPUTENTERED",
"source_files": [
"background.html",
"manifest.json"
],
- "zip_path": "examples/api/omnibox/simple-example.zip",
- "path": "examples/api/omnibox/simple-example/",
- "api_calls": [
- "chrome.experimental.omnibox.onInputChanged",
- "chrome.experimental.omnibox.onInputEntered"
- ],
- "id": "e787b322bddbc6289bb31b7d7550b1bf6456a80b",
- "protocols": [],
- "name": "Omnibox Example"
+ "source_hash": "60a9ea6b33c157ac1f8026fa7e834668716b0dcb",
+ "zip_path": "examples\/api\/omnibox\/simple-example.zip"
},
{
+ "api_calls": [
+ "chrome.extension.onRequest",
+ "chrome.extension.sendRequest",
+ "chrome.pageAction.show"
+ ],
+ "description": "Shows a page action for HTML pages containing the word 'sandwich'",
"features": [
"background_page",
"page_action"
],
"icon": "sandwich-128.png",
- "description": "Shows a page action for HTML pages containing the word 'sandwich'",
+ "id": "8d0a50b57c26bb498be592e871001ffed91541b4",
+ "name": "Page action by content",
+ "path": "examples\/api\/pageAction\/pageaction_by_content\/",
+ "protocols": [],
"search_string": "PAGE ACTION BY CONTENT SHOWS A PAGE ACTION FOR HTML PAGES CONTAINING THE WORD SANDWICH BACKGROUND_PAGE PAGE_ACTION CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.PAGEACTION.SHOW",
"source_files": [
"background.html",
"contentscript.js",
"manifest.json"
],
- "zip_path": "examples/api/pageAction/pageaction_by_content.zip",
- "path": "examples/api/pageAction/pageaction_by_content/",
- "api_calls": [
- "chrome.extension.onRequest",
- "chrome.extension.sendRequest",
- "chrome.pageAction.show"
- ],
- "id": "8d0a50b57c26bb498be592e871001ffed91541b4",
- "protocols": [],
- "name": "Page action by content"
+ "source_hash": "0f4b881b1bc2e2fd6098fd219ca061b72a9654b7",
+ "zip_path": "examples\/api\/pageAction\/pageaction_by_content.zip"
},
{
+ "api_calls": [
+ "chrome.pageAction.show",
+ "chrome.tabs.onUpdated"
+ ],
+ "description": "Shows a page action for urls which have the letter 'g' in them.",
"features": [
"background_page",
"page_action",
"tabs"
],
"icon": "icon-128.png",
- "description": "Shows a page action for urls which have the letter 'g' in them.",
+ "id": "80b86ccc6e8520660fa591caa565826f0ed1b12c",
+ "name": "Page action by URL",
+ "path": "examples\/api\/pageAction\/pageaction_by_url\/",
+ "protocols": [],
"search_string": "PAGE ACTION BY URL SHOWS A PAGE ACTION FOR URLS WHICH HAVE THE LETTER G IN THEM. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.SHOW CHROME.TABS.ONUPDATED",
"source_files": [
"background.html",
"manifest.json"
],
- "zip_path": "examples/api/pageAction/pageaction_by_url.zip",
- "path": "examples/api/pageAction/pageaction_by_url/",
- "api_calls": [
- "chrome.pageAction.show",
- "chrome.tabs.onUpdated"
- ],
- "id": "80b86ccc6e8520660fa591caa565826f0ed1b12c",
- "protocols": [],
- "name": "Page action by URL"
+ "source_hash": "732ef0951e1d6ff4afedb884b0e63cb342bb1499",
+ "zip_path": "examples\/api\/pageAction\/pageaction_by_url.zip"
},
{
- "features": [
- "background_page",
- "browser_action",
- "options_page",
- "tabs"
- ],
- "icon": null,
- "description": "Chromium Page Benchmarker.",
- "search_string": "PAGE BENCHMARKER CHROMIUM PAGE BENCHMARKER. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.CONNECT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETEXTENSIONTABS CHROME.EXTENSION.GETURL CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETCURRENT",
- "source_files": [
- "background.html",
- "jquery/jquery-1.4.2.min.js",
- "jquery/jquery-ui-1.8.4.custom.min.js",
- "jquery/jquery.client.js",
- "jquery/jquery.flot.dashes.js",
- "jquery/jquery.flot.js",
- "jquery/jquery.flot.min.js",
- "jquery/jquery.flot.navigate.js",
- "jquery/jquery.flot.valuelabels.js",
- "jst/jsevalcontext.js",
- "jst/jstemplate.js",
- "jst/jstemplate_test.js",
- "jst/util.js",
- "manifest.json",
- "options.html",
- "script.js",
- "util/sorttable.js",
- "util/table2CSV.js"
- ],
- "zip_path": "examples/extensions/benchmark.zip",
- "path": "examples/extensions/benchmark/",
"api_calls": [
"chrome.browserAction.onClicked",
"chrome.browserAction.setBadgeBackgroundColor",
@@ -1197,40 +1252,77 @@
"chrome.windows.get",
"chrome.windows.getCurrent"
],
- "id": "d74c3c18a1c1dd18b035149105a306f837c8823e",
- "protocols": [
- "https://",
- "http://"
- ],
- "name": "Page Benchmarker"
- },
- {
+ "description": "Chromium Page Benchmarker.",
"features": [
"background_page",
"browser_action",
+ "options_page",
"tabs"
],
"icon": null,
- "description": "Adds a print button to the browser.",
- "search_string": "PRINT THIS PAGE ADDS A PRINT BUTTON TO THE BROWSER. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.UPDATE",
+ "id": "d74c3c18a1c1dd18b035149105a306f837c8823e",
+ "name": "Page Benchmarker",
+ "path": "examples\/extensions\/benchmark\/",
+ "protocols": [
+ "https:\/\/",
+ "http:\/\/"
+ ],
+ "search_string": "PAGE BENCHMARKER CHROMIUM PAGE BENCHMARKER. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.CONNECT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETEXTENSIONTABS CHROME.EXTENSION.GETURL CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETCURRENT",
"source_files": [
"background.html",
- "manifest.json"
+ "jquery\/jquery-1.4.2.min.js",
+ "jquery\/jquery-ui-1.8.4.custom.min.js",
+ "jquery\/jquery.client.js",
+ "jquery\/jquery.flot.dashes.js",
+ "jquery\/jquery.flot.js",
+ "jquery\/jquery.flot.min.js",
+ "jquery\/jquery.flot.navigate.js",
+ "jquery\/jquery.flot.valuelabels.js",
+ "jst\/jsevalcontext.js",
+ "jst\/jstemplate.js",
+ "jst\/jstemplate_test.js",
+ "jst\/util.js",
+ "manifest.json",
+ "options.html",
+ "script.js",
+ "util\/sorttable.js",
+ "util\/table2CSV.js"
],
- "zip_path": "examples/api/browserAction/print.zip",
- "path": "examples/api/browserAction/print/",
+ "source_hash": "7b6fde63c8dd0e626d176e8ce34ad43649746436",
+ "zip_path": "examples\/extensions\/benchmark.zip"
+ },
+ {
"api_calls": [
"chrome.browserAction.onClicked",
"chrome.tabs.update"
],
+ "description": "Adds a print button to the browser.",
+ "features": [
+ "background_page",
+ "browser_action",
+ "tabs"
+ ],
+ "icon": null,
"id": "e6ae17ab4ccfd7e059c8c01f25760ca5d894c7fd",
+ "name": "Print this page",
+ "path": "examples\/api\/browserAction\/print\/",
"protocols": [
- "http://",
- "https://"
+ "http:\/\/",
+ "https:\/\/"
+ ],
+ "search_string": "PRINT THIS PAGE ADDS A PRINT BUTTON TO THE BROWSER. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.UPDATE",
+ "source_files": [
+ "background.html",
+ "manifest.json"
],
- "name": "Print this page"
+ "source_hash": "be980117222f6b041bb012c5a0793040cef747b6",
+ "zip_path": "examples\/api\/browserAction\/print.zip"
},
{
+ "api_calls": [
+ "chrome.experimental.processes.onUpdated"
+ ],
+ "description": "Adds a browser action that monitors resource usage of all browser processes.",
"features": [
"browser_action",
"experimental",
@@ -1238,40 +1330,19 @@
"tabs"
],
"icon": null,
- "description": "Adds a browser action that monitors resource usage of all browser processes.",
+ "id": "beff6ecd9677dea0a7c648c5042165b48bb66f09",
+ "name": "Process Monitor",
+ "path": "examples\/api\/processes\/process_monitor\/",
+ "protocols": [],
"search_string": "PROCESS MONITOR ADDS A BROWSER ACTION THAT MONITORS RESOURCE USAGE OF ALL BROWSER PROCESSES. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.ONUPDATED",
"source_files": [
"manifest.json",
"popup.html"
],
- "zip_path": "examples/api/processes/process_monitor.zip",
- "path": "examples/api/processes/process_monitor/",
- "api_calls": [
- "chrome.experimental.processes.onUpdated"
- ],
- "id": "beff6ecd9677dea0a7c648c5042165b48bb66f09",
- "protocols": [],
- "name": "Process Monitor"
+ "source_hash": "a4d002a65d5ec54ef4495f8b5552a260119df739",
+ "zip_path": "examples\/api\/processes\/process_monitor.zip"
},
{
- "features": [
- "background_page",
- "browser_action",
- "tabs"
- ],
- "icon": "img/icon-128.png",
- "description": "Uses OAuth to connect to Google's contacts service and display a list of your contacts.",
- "search_string": "SAMPLE - OAUTH CONTACTS USES OAUTH TO CONNECT TO GOOGLES CONTACTS SERVICE AND DISPLAY A LIST OF YOUR CONTACTS. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE",
- "source_files": [
- "background.html",
- "chrome_ex_oauth.html",
- "chrome_ex_oauth.js",
- "chrome_ex_oauthsimple.js",
- "contacts.html",
- "manifest.json"
- ],
- "zip_path": "examples/extensions/oauth_contacts.zip",
- "path": "examples/extensions/oauth_contacts/",
"api_calls": [
"chrome.browserAction.onClicked",
"chrome.browserAction.setIcon",
@@ -1283,22 +1354,50 @@
"chrome.tabs.onUpdated",
"chrome.tabs.remove"
],
+ "description": "Uses OAuth to connect to Google's contacts service and display a list of your contacts.",
+ "features": [
+ "background_page",
+ "browser_action",
+ "tabs"
+ ],
+ "icon": "img\/icon-128.png",
"id": "56a8d2ac24ca7bba78fd88ad57f43fc13c784497",
+ "name": "Sample - OAuth Contacts",
+ "path": "examples\/extensions\/oauth_contacts\/",
"protocols": [
- "http://",
- "https://",
- "https://",
- "https://"
+ "http:\/\/",
+ "https:\/\/",
+ "https:\/\/",
+ "https:\/\/"
+ ],
+ "search_string": "SAMPLE - OAUTH CONTACTS USES OAUTH TO CONNECT TO GOOGLES CONTACTS SERVICE AND DISPLAY A LIST OF YOUR CONTACTS. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE",
+ "source_files": [
+ "background.html",
+ "chrome_ex_oauth.html",
+ "chrome_ex_oauth.js",
+ "chrome_ex_oauthsimple.js",
+ "contacts.html",
+ "manifest.json"
],
- "name": "Sample - OAuth Contacts"
+ "source_hash": "e9afbd588b1593c9d3e9b9612ac242c781871f34",
+ "zip_path": "examples\/extensions\/oauth_contacts.zip"
},
{
+ "api_calls": [
+ "chrome.experimental.infobars.show",
+ "chrome.extension.onRequest",
+ "chrome.extension.sendRequest"
+ ],
+ "description": "Shows an infobar on pages which contain the word 'sandwich'",
"features": [
"background_page",
"experimental"
],
"icon": "sandwich-128.png",
- "description": "Shows an infobar on pages which contain the word 'sandwich'",
+ "id": "38f6e1e17756ede38b1364c7114a738ca717dcbb",
+ "name": "SandwichBar",
+ "path": "examples\/api\/infobars\/sandwichbar\/",
+ "protocols": [],
"search_string": "SANDWICHBAR SHOWS AN INFOBAR ON PAGES WHICH CONTAIN THE WORD SANDWICH BACKGROUND_PAGE EXPERIMENTAL CHROME.EXPERIMENTAL.INFOBARS.SHOW CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST",
"source_files": [
"background.html",
@@ -1306,33 +1405,10 @@
"infobar.html",
"manifest.json"
],
- "zip_path": "examples/api/infobars/sandwichbar.zip",
- "path": "examples/api/infobars/sandwichbar/",
- "api_calls": [
- "chrome.experimental.infobars.show",
- "chrome.extension.onRequest",
- "chrome.extension.sendRequest"
- ],
- "id": "38f6e1e17756ede38b1364c7114a738ca717dcbb",
- "protocols": [],
- "name": "SandwichBar"
+ "source_hash": "890d698634e5228ef7da8ffca3008f843b9a7cab",
+ "zip_path": "examples\/api\/infobars\/sandwichbar.zip"
},
{
- "features": [
- "browser_action",
- "experimental",
- "popup",
- "tabs"
- ],
- "icon": null,
- "description": "Adds a browser action showing which tabs share the current tab's process.",
- "search_string": "SHOW TABS IN PROCESS ADDS A BROWSER ACTION SHOWING WHICH TABS SHARE THE CURRENT TABS PROCESS. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.GETPROCESSIDFORTAB CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.UPDATE",
- "source_files": [
- "manifest.json",
- "popup.html"
- ],
- "zip_path": "examples/api/processes/show_tabs.zip",
- "path": "examples/api/processes/show_tabs/",
"api_calls": [
"chrome.experimental.processes.getProcessIdForTab",
"chrome.tabs.get",
@@ -1343,27 +1419,27 @@
"chrome.windows.getCurrent",
"chrome.windows.update"
],
- "id": "fc89b35755483af30b66cd72cefa34a43a3e8312",
- "protocols": [],
- "name": "Show Tabs in Process"
- },
- {
+ "description": "Adds a browser action showing which tabs share the current tab's process.",
"features": [
- "background_page",
"browser_action",
+ "experimental",
+ "popup",
"tabs"
],
"icon": null,
- "description": "Utility for working with the extension tabs api",
- "search_string": "TAB INSPECTOR UTILITY FOR WORKING WITH THE EXTENSION TABS API BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.MOVE CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.CREATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.GETLASTFOCUSED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED CHROME.WINDOWS.REMOVE CHROME.WINDOWS.UPDATE",
+ "id": "fc89b35755483af30b66cd72cefa34a43a3e8312",
+ "name": "Show Tabs in Process",
+ "path": "examples\/api\/processes\/show_tabs\/",
+ "protocols": [],
+ "search_string": "SHOW TABS IN PROCESS ADDS A BROWSER ACTION SHOWING WHICH TABS SHARE THE CURRENT TABS PROCESS. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.GETPROCESSIDFORTAB CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.UPDATE",
"source_files": [
- "background.html",
- "jstemplate_compiled.js",
"manifest.json",
- "tabs_api.html"
+ "popup.html"
],
- "zip_path": "examples/api/tabs/inspector.zip",
- "path": "examples/api/tabs/inspector/",
+ "source_hash": "c9818c3c4c2e4fae0a7cc29588514e050356fd52",
+ "zip_path": "examples\/api\/processes\/show_tabs.zip"
+ },
+ {
"api_calls": [
"chrome.browserAction.onClicked",
"chrome.extension.getURL",
@@ -1392,27 +1468,28 @@
"chrome.windows.remove",
"chrome.windows.update"
],
- "id": "230463f2d5c3d4d0ca13c230e1f00f2aae0a8a64",
- "protocols": [],
- "name": "Tab Inspector"
- },
- {
+ "description": "Utility for working with the extension tabs api",
"features": [
"background_page",
"browser_action",
"tabs"
],
"icon": null,
- "description": "Demonstrate screenshot functionality in the chrome.tabs api.",
- "search_string": "TEST SCREENSHOT EXTENSION DEMONSTRATE SCREENSHOT FUNCTIONALITY IN THE CHROME.TABS API. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.EXTENSION.GETVIEWS CHROME.TABS.CAPTUREVISIBLETAB CHROME.TABS.CREATE CHROME.TABS.ONUPDATED",
+ "id": "230463f2d5c3d4d0ca13c230e1f00f2aae0a8a64",
+ "name": "Tab Inspector",
+ "path": "examples\/api\/tabs\/inspector\/",
+ "protocols": [],
+ "search_string": "TAB INSPECTOR UTILITY FOR WORKING WITH THE EXTENSION TABS API BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.MOVE CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.CREATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.GETLASTFOCUSED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED CHROME.WINDOWS.REMOVE CHROME.WINDOWS.UPDATE",
"source_files": [
"background.html",
+ "jstemplate_compiled.js",
"manifest.json",
- "screenshot.html",
- "screenshot.js"
+ "tabs_api.html"
],
- "zip_path": "examples/api/tabs/screenshot.zip",
- "path": "examples/api/tabs/screenshot/",
+ "source_hash": "3076b39a4302d8e86f456e6d7367129187cce0c0",
+ "zip_path": "examples\/api\/tabs\/inspector.zip"
+ },
+ {
"api_calls": [
"chrome.browserAction.onClicked",
"chrome.extension.getURL",
@@ -1421,34 +1498,52 @@
"chrome.tabs.create",
"chrome.tabs.onUpdated"
],
+ "description": "Demonstrate screenshot functionality in the chrome.tabs api.",
+ "features": [
+ "background_page",
+ "browser_action",
+ "tabs"
+ ],
+ "icon": null,
"id": "e1697cacebad05218798bf3e8a0f724517f0e8c3",
+ "name": "Test Screenshot Extension",
+ "path": "examples\/api\/tabs\/screenshot\/",
"protocols": [],
- "name": "Test Screenshot Extension"
+ "search_string": "TEST SCREENSHOT EXTENSION DEMONSTRATE SCREENSHOT FUNCTIONALITY IN THE CHROME.TABS API. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.EXTENSION.GETVIEWS CHROME.TABS.CAPTUREVISIBLETAB CHROME.TABS.CREATE CHROME.TABS.ONUPDATED",
+ "source_files": [
+ "background.html",
+ "manifest.json",
+ "screenshot.html",
+ "screenshot.js"
+ ],
+ "source_hash": "6be9b92850e86ce311cc12a2cf0cda3b47ab5d58",
+ "zip_path": "examples\/api\/tabs\/screenshot.zip"
},
{
+ "api_calls": [
+ "chrome.history.getVisits",
+ "chrome.history.search",
+ "chrome.tabs.create"
+ ],
+ "description": "Reads your history, and shows the top ten pages you go to by typing the URL.",
"features": [
"browser_action",
"history",
"tabs"
],
"icon": null,
- "description": "Reads your history, and shows the top ten pages you go to by typing the URL.",
+ "id": "b3de91ab04b7d7a2670ca7ee9d740eb42cead0b6",
+ "name": "Typed URL History",
+ "path": "examples\/api\/history\/showHistory\/",
+ "protocols": [],
"search_string": "TYPED URL HISTORY READS YOUR HISTORY, AND SHOWS THE TOP TEN PAGES YOU GO TO BY TYPING THE URL. BROWSER_ACTION HISTORY TABS CHROME.HISTORY.GETVISITS CHROME.HISTORY.SEARCH CHROME.TABS.CREATE",
"source_files": [
"manifest.json",
"typedUrls.html",
"typedUrls.js"
],
- "zip_path": "examples/api/history/showHistory.zip",
- "path": "examples/api/history/showHistory/",
- "api_calls": [
- "chrome.history.getVisits",
- "chrome.history.search",
- "chrome.tabs.create"
- ],
- "id": "b3de91ab04b7d7a2670ca7ee9d740eb42cead0b6",
- "protocols": [],
- "name": "Typed URL History"
+ "source_hash": "72d5c3586feefc692c63039ce8bdb5f9d366c0e2",
+ "zip_path": "examples\/api\/history\/showHistory.zip"
}
]
-}
+} \ No newline at end of file
diff --git a/chrome/common/extensions/docs/server/chromeextensionsdocs.py b/chrome/common/extensions/docs/server/chromeextensionsdocs.py
index 34c1822..9edf5cd 100644
--- a/chrome/common/extensions/docs/server/chromeextensionsdocs.py
+++ b/chrome/common/extensions/docs/server/chromeextensionsdocs.py
@@ -268,7 +268,7 @@ class MainPage(webapp.RequestHandler):
application = webapp.WSGIApplication([
('/.*', MainPage),
-], debug=True)
+], debug=False)
def main():
diff --git a/chrome/common/extensions/docs/tabs.html b/chrome/common/extensions/docs/tabs.html
index 9aa03b4..1ffe88d 100644
--- a/chrome/common/extensions/docs/tabs.html
+++ b/chrome/common/extensions/docs/tabs.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/template/api_template.html b/chrome/common/extensions/docs/template/api_template.html
index dd4f074..a1afec6 100644
--- a/chrome/common/extensions/docs/template/api_template.html
+++ b/chrome/common/extensions/docs/template/api_template.html
@@ -209,7 +209,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/themes.html b/chrome/common/extensions/docs/themes.html
index 9c46460..eff32c2 100644
--- a/chrome/common/extensions/docs/themes.html
+++ b/chrome/common/extensions/docs/themes.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/tut_analytics.html b/chrome/common/extensions/docs/tut_analytics.html
index 4a09e0e..90a7006 100644
--- a/chrome/common/extensions/docs/tut_analytics.html
+++ b/chrome/common/extensions/docs/tut_analytics.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/tut_debugging.html b/chrome/common/extensions/docs/tut_debugging.html
index dad2b44..aa399ae 100644
--- a/chrome/common/extensions/docs/tut_debugging.html
+++ b/chrome/common/extensions/docs/tut_debugging.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/tut_oauth.html b/chrome/common/extensions/docs/tut_oauth.html
index a7b4cb5..0057664 100644
--- a/chrome/common/extensions/docs/tut_oauth.html
+++ b/chrome/common/extensions/docs/tut_oauth.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/tutorials.html b/chrome/common/extensions/docs/tutorials.html
index 4d270ac..5d63ce7 100644
--- a/chrome/common/extensions/docs/tutorials.html
+++ b/chrome/common/extensions/docs/tutorials.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/whats_new.html b/chrome/common/extensions/docs/whats_new.html
index 86f79b9..a632e7c 100644
--- a/chrome/common/extensions/docs/whats_new.html
+++ b/chrome/common/extensions/docs/whats_new.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/windows.html b/chrome/common/extensions/docs/windows.html
index 209fd58..cd6d078 100644
--- a/chrome/common/extensions/docs/windows.html
+++ b/chrome/common/extensions/docs/windows.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/docs/xhr.html b/chrome/common/extensions/docs/xhr.html
index 8987f40..d3c32e2 100644
--- a/chrome/common/extensions/docs/xhr.html
+++ b/chrome/common/extensions/docs/xhr.html
@@ -223,7 +223,15 @@
<li><a href="api_other.html">Other APIs</a></li>
</ul>
</li>
- <li><h2><a href="samples.html">Samples</a></h2></li>
+ <li><h2><a href="samples.html">Samples</a></h2></li>
+ <div class="line"> </div>
+ <li><h2>More</h2>
+ <ul>
+ <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
+ <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
+ <li><a href="themes.html">Themes</a></li>
+ </ul>
+ </li>
</ul>
</div>
<script>
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 2bbf99b..4d33822 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -102,6 +102,7 @@ const char kBrowserActionsModuleName[] = "browserActions";
const char kDevToolsModuleName[] = "devtools";
const char kExtensionModuleName[] = "extension";
const char kI18NModuleName[] = "i18n";
+const char kOmniboxModuleName[] = "omnibox";
const char kPageActionModuleName[] = "pageAction";
const char kPageActionsModuleName[] = "pageActions";
const char kTestModuleName[] = "test";
@@ -114,6 +115,7 @@ const char* kNonPermissionModuleNames[] = {
kDevToolsModuleName,
kExtensionModuleName,
kI18NModuleName,
+ kOmniboxModuleName,
kPageActionModuleName,
kPageActionsModuleName,
kTestModuleName
@@ -218,17 +220,17 @@ const char Extension::kWebstorePrivatePermission[] = "webstorePrivate";
// exception.
const Extension::Permission Extension::kPermissions[] = {
{ kBackgroundPermission, 0 },
- { kBookmarkPermission, IDS_EXTENSION_PROMPT2_WARNING_BOOKMARKS },
+ { kBookmarkPermission, IDS_EXTENSION_PROMPT_WARNING_BOOKMARKS },
{ kContextMenusPermission, 0 },
{ kCookiePermission, 0 },
{ kExperimentalPermission, 0 },
- { kGeolocationPermission, IDS_EXTENSION_PROMPT2_WARNING_GEOLOCATION },
+ { kGeolocationPermission, IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION },
{ kIdlePermission, 0 },
- { kHistoryPermission, IDS_EXTENSION_PROMPT2_WARNING_BROWSING_HISTORY },
- { kManagementPermission, IDS_EXTENSION_PROMPT2_WARNING_MANAGEMENT },
+ { kHistoryPermission, IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY },
+ { kManagementPermission, IDS_EXTENSION_PROMPT_WARNING_MANAGEMENT },
{ kNotificationPermission, 0 },
{ kProxyPermission, 0 },
- { kTabPermission, IDS_EXTENSION_PROMPT2_WARNING_BROWSING_HISTORY },
+ { kTabPermission, IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY },
{ kUnlimitedStoragePermission, 0 },
{ kWebstorePrivatePermission, 0 },
};
@@ -273,7 +275,7 @@ std::vector<string16> Extension::GetPermissionMessages() const {
std::vector<string16> messages;
if (!plugins().empty()) {
messages.push_back(
- l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT2_WARNING_FULL_ACCESS));
+ l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS));
return messages;
}
@@ -331,24 +333,24 @@ std::vector<std::string> Extension::GetDistinctHosts(
string16 Extension::GetHostPermissionMessage() const {
if (HasEffectiveAccessToAllHosts())
- return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT2_WARNING_ALL_HOSTS);
+ return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS);
std::vector<std::string> hosts = GetDistinctHosts();
if (hosts.size() == 1) {
- return l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT2_WARNING_1_HOST,
+ return l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_1_HOST,
UTF8ToUTF16(hosts[0]));
} else if (hosts.size() == 2) {
- return l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT2_WARNING_2_HOSTS,
+ return l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_2_HOSTS,
UTF8ToUTF16(hosts[0]),
UTF8ToUTF16(hosts[1]));
} else if (hosts.size() == 3) {
- return l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT2_WARNING_3_HOSTS,
+ return l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_WARNING_3_HOSTS,
UTF8ToUTF16(hosts[0]),
UTF8ToUTF16(hosts[1]),
UTF8ToUTF16(hosts[2]));
} else if (hosts.size() >= 4) {
return l10n_util::GetStringFUTF16(
- IDS_EXTENSION_PROMPT2_WARNING_4_OR_MORE_HOSTS,
+ IDS_EXTENSION_PROMPT_WARNING_4_OR_MORE_HOSTS,
UTF8ToUTF16(hosts[0]),
UTF8ToUTF16(hosts[1]),
base::IntToString16(hosts.size() - 2));
@@ -1141,8 +1143,6 @@ void Extension::DecodeIcon(const Extension* extension,
void Extension::DecodeIconFromPath(const FilePath& icon_path,
Icons icon_size,
scoped_ptr<SkBitmap>* result) {
- ExtensionResource::CheckFileAccessFromFileThread();
-
if (icon_path.empty())
return;
@@ -1776,17 +1776,12 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key,
}
}
- if (source.HasKey(keys::kOmniboxKeyword)) {
- if (!source.GetString(keys::kOmniboxKeyword,
- &omnibox_keyword_) ||
+ if (source.HasKey(keys::kOmnibox)) {
+ if (!source.GetString(keys::kOmniboxKeyword, &omnibox_keyword_) ||
omnibox_keyword_.empty()) {
*error = errors::kInvalidOmniboxKeyword;
return false;
}
- if (!HasApiPermission(Extension::kExperimentalPermission)) {
- *error = errors::kOmniboxExperimental;
- return false;
- }
}
// Initialize devtools page url (optional).
@@ -1854,8 +1849,7 @@ GURL Extension::GetHomepageURL() const {
if (homepage_url_.is_valid())
return homepage_url_;
- if (update_url()!= GURL(extension_urls::kGalleryUpdateHttpsUrl) &&
- update_url()!= GURL(extension_urls::kGalleryUpdateHttpUrl))
+ if (!UpdatesFromGallery())
return GURL();
// TODO(erikkay): This may not be entirely correct with the webstore.
@@ -2193,6 +2187,11 @@ bool Extension::CanExecuteScriptEverywhere() const {
return false;
}
+bool Extension::UpdatesFromGallery() const {
+ return update_url() == GURL(extension_urls::kGalleryUpdateHttpsUrl) ||
+ update_url() == GURL(extension_urls::kGalleryUpdateHttpUrl);
+}
+
ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest,
const std::string& id,
const FilePath& path,
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index ce7e628..6c545e7 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -356,6 +356,10 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// on the whitelist of extensions that can script all pages.
bool CanExecuteScriptEverywhere() const;
+ // Returns true if this extension updates itself using the extension
+ // gallery.
+ bool UpdatesFromGallery() const;
+
// Accessors:
const FilePath& path() const { return path_; }
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index 5e418b5..b37fcba 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -33,7 +33,8 @@ const char* kLaunchWidth = "app.launch.width";
const char* kMatches = "matches";
const char* kMinimumChromeVersion = "minimum_chrome_version";
const char* kName = "name";
-const char* kOmniboxKeyword = "omnibox_keyword";
+const char* kOmnibox = "omnibox";
+const char* kOmniboxKeyword = "omnibox.keyword";
const char* kOptionsPage = "options_page";
const char* kPageAction = "page_action";
const char* kPageActionDefaultIcon = "default_icon";
@@ -167,7 +168,7 @@ const char* kInvalidMinimumChromeVersion =
const char* kInvalidName =
"Required value 'name' is missing or invalid.";
const char* kInvalidOmniboxKeyword =
- "Invalid value for 'omnibox_keyword'.";
+ "Invalid value for 'omnibox.keyword'.";
const char* kInvalidOptionsPage =
"Invalid value for 'options_page'.";
const char* kInvalidOptionsPageExpectUrlInPackage =
@@ -263,9 +264,6 @@ const char* kMissingFile =
"At least one js or css file is required for 'content_scripts[*]'.";
const char* kMultipleOverrides =
"An extension cannot override more than one page.";
-const char* kOmniboxExperimental =
- "You must request the 'experimental' permission in order to use the"
- " omnibox API.";
const char* kOneUISurfaceOnly =
"Only one of 'browser_action', 'page_action', and 'app' can be specified.";
const char* kReservedMessageFound =
@@ -304,4 +302,5 @@ const char* kDecodedMessageCatalogsFilename = "DECODED_MESSAGE_CATALOGS";
namespace extension_misc {
const char* kBookmarkManagerId = "eemcgdkfndhakfknompkggombfjjjeno";
const char* kWebStoreAppId = "ahfgeienlihckogmohjhadlkjgocpleb";
+const char* kAppsPromoHistogram = "Extensions.AppsPromo";
}
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index 332f386..8c3bee2 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -38,6 +38,7 @@ namespace extension_manifest_keys {
extern const char* kMatches;
extern const char* kMinimumChromeVersion;
extern const char* kName;
+ extern const char* kOmnibox;
extern const char* kOmniboxKeyword;
extern const char* kOptionsPage;
extern const char* kPageAction;
@@ -67,7 +68,6 @@ namespace extension_manifest_keys {
extern const char* kType;
extern const char* kUpdateURL;
extern const char* kVersion;
- extern const char* kWebLaunchUrl;
extern const char* kWebURLs;
} // namespace extension_manifest_keys
@@ -176,7 +176,6 @@ namespace extension_manifest_errors {
extern const char* kManifestUnreadable;
extern const char* kMissingFile;
extern const char* kMultipleOverrides;
- extern const char* kOmniboxExperimental;
extern const char* kOneUISurfaceOnly;
extern const char* kReservedMessageFound;
extern const char* kThemesCannotContainExtensions;
@@ -239,6 +238,18 @@ namespace extension_misc {
LAUNCH_PANEL,
LAUNCH_TAB
};
+
+ // The name of the apps promo histogram.
+ extern const char* kAppsPromoHistogram;
+
+ // The buckets used in the apps promo histogram.
+ enum AppsPromoBuckets {
+ PROMO_LAUNCH_APP,
+ PROMO_LAUNCH_WEB_STORE,
+ PROMO_CLOSE,
+ PROMO_EXPIRE,
+ PROMO_BUCKET_BOUNDARY = PROMO_EXPIRE + 1
+ };
} // extension_misc
#endif // CHROME_COMMON_EXTENSIONS_EXTENSION_CONSTANTS_H_
diff --git a/chrome/common/extensions/extension_l10n_util.cc b/chrome/common/extensions/extension_l10n_util.cc
index 8c7826c..34762fd 100644
--- a/chrome/common/extensions/extension_l10n_util.cc
+++ b/chrome/common/extensions/extension_l10n_util.cc
@@ -107,6 +107,10 @@ bool LocalizeManifest(const ExtensionMessageBundle& messages,
if (!LocalizeManifestValue(key, messages, manifest, error))
return false;
+ // Initialize omnibox.keyword.
+ if (!LocalizeManifestValue(keys::kOmniboxKeyword, messages, manifest, error))
+ return false;
+
// Add current locale key to the manifest, so we can overwrite prefs
// with new manifest when chrome locale changes.
manifest->SetString(keys::kCurrentLocale, CurrentLocaleOrDefault());
diff --git a/chrome/common/extensions/extension_l10n_util_unittest.cc b/chrome/common/extensions/extension_l10n_util_unittest.cc
index 2aafebb..1487452 100644
--- a/chrome/common/extensions/extension_l10n_util_unittest.cc
+++ b/chrome/common/extensions/extension_l10n_util_unittest.cc
@@ -241,13 +241,17 @@ ExtensionMessageBundle* CreateManifestBundle() {
action_title_tree->SetString("message", "action title");
catalog->Set("title", action_title_tree);
+ DictionaryValue* omnibox_keyword_tree = new DictionaryValue();
+ omnibox_keyword_tree->SetString("message", "omnibox keyword");
+ catalog->Set("omnibox_keyword", omnibox_keyword_tree);
+
std::vector<linked_ptr<DictionaryValue> > catalogs;
catalogs.push_back(catalog);
std::string error;
ExtensionMessageBundle* bundle =
- ExtensionMessageBundle::Create(catalogs, &error);
- EXPECT_TRUE(NULL != bundle);
+ ExtensionMessageBundle::Create(catalogs, &error);
+ EXPECT_TRUE(bundle);
EXPECT_TRUE(error.empty());
return bundle;
@@ -347,6 +351,31 @@ TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionDefaultTitleMsgs) {
EXPECT_TRUE(error.empty());
}
+TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionOmniboxMsgs) {
+ DictionaryValue manifest;
+ manifest.SetString(keys::kName, "__MSG_name__");
+ manifest.SetString(keys::kDescription, "__MSG_description__");
+ manifest.SetString(keys::kOmniboxKeyword, "__MSG_omnibox_keyword__");
+
+ std::string error;
+ scoped_ptr<ExtensionMessageBundle> messages(CreateManifestBundle());
+
+ EXPECT_TRUE(
+ extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
+
+ std::string result;
+ ASSERT_TRUE(manifest.GetString(keys::kName, &result));
+ EXPECT_EQ("name", result);
+
+ ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
+ EXPECT_EQ("description", result);
+
+ ASSERT_TRUE(manifest.GetString(keys::kOmniboxKeyword, &result));
+ EXPECT_EQ("omnibox keyword", result);
+
+ EXPECT_TRUE(error.empty());
+}
+
// Try with NULL manifest.
TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithNullManifest) {
ExtensionInfo info(NULL, "", FilePath(), Extension::LOAD);
diff --git a/chrome/common/extensions/extension_resource.cc b/chrome/common/extensions/extension_resource.cc
index be22ec9..258b537 100644
--- a/chrome/common/extensions/extension_resource.cc
+++ b/chrome/common/extensions/extension_resource.cc
@@ -8,10 +8,6 @@
#include "base/logging.h"
#include "base/thread_restrictions.h"
-PlatformThreadId ExtensionResource::file_thread_id_ = 0;
-
-bool ExtensionResource::check_for_file_thread_ = false;
-
ExtensionResource::ExtensionResource() {
}
@@ -23,7 +19,7 @@ ExtensionResource::ExtensionResource(const std::string& extension_id,
relative_path_(relative_path) {
}
-const FilePath& ExtensionResource::GetFilePathOnAnyThreadHack() const {
+const FilePath& ExtensionResource::GetFilePath() const {
if (extension_root_.empty() || relative_path_.empty()) {
DCHECK(full_resource_path_.empty());
return full_resource_path_;
@@ -34,24 +30,13 @@ const FilePath& ExtensionResource::GetFilePathOnAnyThreadHack() const {
return full_resource_path_;
full_resource_path_ =
- GetFilePathOnAnyThreadHack(extension_root_, relative_path_);
+ GetFilePath(extension_root_, relative_path_);
return full_resource_path_;
}
-const FilePath& ExtensionResource::GetFilePath() const {
- ExtensionResource::CheckFileAccessFromFileThread();
- return GetFilePathOnAnyThreadHack();
-}
-
// static
-FilePath ExtensionResource::GetFilePathOnAnyThreadHack(
+FilePath ExtensionResource::GetFilePath(
const FilePath& extension_root, const FilePath& relative_path) {
- // This function is a hack, and causes us to block the IO thread.
- // Fixing
- // http://code.google.com/p/chromium/issues/detail?id=59849
- // would also fix this. Suppress the error for now.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
-
// We need to resolve the parent references in the extension_root
// path on its own because IsParent doesn't like parent references.
FilePath clean_extension_root(extension_root);
@@ -76,19 +61,6 @@ FilePath ExtensionResource::GetFilePathOnAnyThreadHack(
return FilePath();
}
-// static
-FilePath ExtensionResource::GetFilePath(
- const FilePath& extension_root, const FilePath& relative_path) {
- CheckFileAccessFromFileThread();
- return GetFilePathOnAnyThreadHack(extension_root, relative_path);
-}
-
-// static
-void ExtensionResource::CheckFileAccessFromFileThread() {
- DCHECK(!check_for_file_thread_ ||
- file_thread_id_ == PlatformThread::CurrentId());
-}
-
// Unit-testing helpers.
FilePath::StringType ExtensionResource::NormalizeSeperators(
FilePath::StringType path) const {
diff --git a/chrome/common/extensions/extension_resource.h b/chrome/common/extensions/extension_resource.h
index 3d52878..c680345 100644
--- a/chrome/common/extensions/extension_resource.h
+++ b/chrome/common/extensions/extension_resource.h
@@ -35,25 +35,6 @@ class ExtensionResource {
static FilePath GetFilePath(const FilePath& extension_root,
const FilePath& relative_path);
- // Gets the file path on any thread. Unlike GetFilePath(), these can be called
- // from any thread without DCHECKing.
- //
- // In the browser process, calling this method is almost always wrong. Use
- // GetFilePath() on the file thread instead.
- const FilePath& GetFilePathOnAnyThreadHack() const;
- static FilePath GetFilePathOnAnyThreadHack(const FilePath& extension_root,
- const FilePath& relative_path);
-
- // Setter for the proper thread to run file tasks on.
- static void set_file_thread_id(PlatformThreadId thread_id) {
- file_thread_id_ = thread_id;
- check_for_file_thread_ = true;
- }
-
- // Checks whether we are running on the file thread and DCHECKs if not. Relies
- // on set_file_thread_id being called first, otherwise, it will not DCHECK.
- static void CheckFileAccessFromFileThread();
-
// Getters
const std::string& extension_id() const { return extension_id_; }
const FilePath& extension_root() const { return extension_root_; }
@@ -77,15 +58,6 @@ class ExtensionResource {
// Full path to extension resource. Starts empty.
mutable FilePath full_resource_path_;
-
- // The thread id for the file thread. If set, GetFilePath() and related
- // methods will DCHECK that they are on this thread when called.
- static PlatformThreadId file_thread_id_;
-
- // Whether to check for file thread. See |file_thread_id_|. If set,
- // GetFilePath() and related methods will DCHECK that they are on this thread
- // when called.
- static bool check_for_file_thread_;
};
#endif // CHROME_COMMON_EXTENSIONS_EXTENSION_RESOURCE_H_
diff --git a/chrome/common/extensions/url_pattern_unittest.cc b/chrome/common/extensions/url_pattern_unittest.cc
index e0be087..33bf8a0 100644
--- a/chrome/common/extensions/url_pattern_unittest.cc
+++ b/chrome/common/extensions/url_pattern_unittest.cc
@@ -16,7 +16,7 @@ static const int kAllSchemes =
URLPattern::SCHEME_FTP |
URLPattern::SCHEME_CHROMEUI;
-TEST(URLPatternTest, ParseInvalid) {
+TEST(ExtensionURLPatternTest, ParseInvalid) {
const struct {
const char* pattern;
URLPattern::ParseResult expected_result;
@@ -42,7 +42,7 @@ TEST(URLPatternTest, ParseInvalid) {
};
// all pages for a given scheme
-TEST(URLPatternTest, Match1) {
+TEST(ExtensionURLPatternTest, Match1) {
URLPattern pattern(kAllSchemes);
EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("http://*/*"));
EXPECT_EQ("http", pattern.scheme());
@@ -58,7 +58,7 @@ TEST(URLPatternTest, Match1) {
}
// all domains
-TEST(URLPatternTest, Match2) {
+TEST(ExtensionURLPatternTest, Match2) {
URLPattern pattern(kAllSchemes);
EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("https://*/foo*"));
EXPECT_EQ("https", pattern.scheme());
@@ -90,7 +90,7 @@ TEST(URLPatternTest, Match3) {
}
// glob escaping
-TEST(URLPatternTest, Match5) {
+TEST(ExtensionURLPatternTest, Match5) {
URLPattern pattern(kAllSchemes);
EXPECT_EQ(URLPattern::PARSE_SUCCESS,
pattern.Parse("file:///foo?bar\\*baz"));
@@ -104,7 +104,7 @@ TEST(URLPatternTest, Match5) {
}
// ip addresses
-TEST(URLPatternTest, Match6) {
+TEST(ExtensionURLPatternTest, Match6) {
URLPattern pattern(kAllSchemes);
EXPECT_EQ(URLPattern::PARSE_SUCCESS,
pattern.Parse("http://127.0.0.1/*"));
@@ -117,7 +117,7 @@ TEST(URLPatternTest, Match6) {
}
// subdomain matching with ip addresses
-TEST(URLPatternTest, Match7) {
+TEST(ExtensionURLPatternTest, Match7) {
URLPattern pattern(kAllSchemes);
EXPECT_EQ(URLPattern::PARSE_SUCCESS,
pattern.Parse("http://*.0.0.1/*")); // allowed, but useless
@@ -131,7 +131,7 @@ TEST(URLPatternTest, Match7) {
};
// unicode
-TEST(URLPatternTest, Match8) {
+TEST(ExtensionURLPatternTest, Match8) {
URLPattern pattern(kAllSchemes);
// The below is the ASCII encoding of the following URL:
// http://*.\xe1\x80\xbf/a\xc2\x81\xe1*
@@ -149,7 +149,7 @@ TEST(URLPatternTest, Match8) {
};
// chrome://
-TEST(URLPatternTest, Match9) {
+TEST(ExtensionURLPatternTest, Match9) {
URLPattern pattern(kAllSchemes);
EXPECT_EQ(URLPattern::PARSE_SUCCESS,
pattern.Parse("chrome://favicon/*"));
@@ -164,7 +164,7 @@ TEST(URLPatternTest, Match9) {
};
// *://
-TEST(URLPatternTest, Match10) {
+TEST(ExtensionURLPatternTest, Match10) {
URLPattern pattern(kAllSchemes);
EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("*://*/*"));
EXPECT_TRUE(pattern.MatchesScheme("http"));
@@ -181,7 +181,7 @@ TEST(URLPatternTest, Match10) {
};
// <all_urls>
-TEST(URLPatternTest, Match11) {
+TEST(ExtensionURLPatternTest, Match11) {
URLPattern pattern(kAllSchemes);
EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("<all_urls>"));
EXPECT_TRUE(pattern.MatchesScheme("chrome"));
@@ -197,7 +197,7 @@ TEST(URLPatternTest, Match11) {
};
// SCHEME_ALL matches all schemes.
-TEST(URLPatternTest, Match12) {
+TEST(ExtensionURLPatternTest, Match12) {
URLPattern pattern(URLPattern::SCHEME_ALL);
EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("<all_urls>"));
EXPECT_TRUE(pattern.MatchesScheme("chrome"));
@@ -234,7 +234,7 @@ static const struct MatchPatterns {
};
// SCHEME_ALL and specific schemes.
-TEST(URLPatternTest, Match13) {
+TEST(ExtensionURLPatternTest, Match13) {
for (size_t i = 0; i < arraysize(kMatch13UrlPatternTestCases); ++i) {
URLPattern pattern(URLPattern::SCHEME_ALL);
EXPECT_EQ(URLPattern::PARSE_SUCCESS,
@@ -268,7 +268,7 @@ static const struct GetAsStringPatterns {
{ "javascript:atemyhomework" },
};
-TEST(URLPatternTest, GetAsString) {
+TEST(ExtensionURLPatternTest, GetAsString) {
for (size_t i = 0; i < arraysize(kGetAsStringTestCases); ++i) {
URLPattern pattern(URLPattern::SCHEME_ALL);
EXPECT_EQ(URLPattern::PARSE_SUCCESS,
@@ -286,7 +286,7 @@ void TestPatternOverlap(const URLPattern& pattern1, const URLPattern& pattern2,
<< pattern2.GetAsString() << ", " << pattern1.GetAsString();
}
-TEST(URLPatternTest, OverlapsWith) {
+TEST(ExtensionURLPatternTest, OverlapsWith) {
URLPattern pattern1(kAllSchemes, "http://www.google.com/foo/*");
URLPattern pattern2(kAllSchemes, "https://www.google.com/foo/*");
URLPattern pattern3(kAllSchemes, "http://*.google.com/foo/*");
@@ -317,7 +317,7 @@ TEST(URLPatternTest, OverlapsWith) {
TestPatternOverlap(pattern7, pattern10, true);
}
-TEST(URLPatternTest, ConvertToExplicitSchemes) {
+TEST(ExtensionURLPatternTest, ConvertToExplicitSchemes) {
std::vector<URLPattern> all_urls(URLPattern(
kAllSchemes,
"<all_urls>").ConvertToExplicitSchemes());
diff --git a/chrome/common/extensions/user_script_unittest.cc b/chrome/common/extensions/user_script_unittest.cc
index 949ad1a..297de7b 100644
--- a/chrome/common/extensions/user_script_unittest.cc
+++ b/chrome/common/extensions/user_script_unittest.cc
@@ -15,7 +15,7 @@ static const int kAllSchemes =
URLPattern::SCHEME_FTP |
URLPattern::SCHEME_CHROMEUI;
-TEST(UserScriptTest, Match1) {
+TEST(ExtensionUserScriptTest, Match1) {
UserScript script;
script.add_glob("*mail.google.com*");
script.add_glob("*mail.yahoo.com*");
@@ -34,7 +34,7 @@ TEST(UserScriptTest, Match1) {
EXPECT_FALSE(script.MatchesUrl(GURL("http://mail.google.com/foo")));
}
-TEST(UserScriptTest, Match2) {
+TEST(ExtensionUserScriptTest, Match2) {
UserScript script;
script.add_glob("*mail.google.com/");
// GURL normalizes the URL to have a trailing "/"
@@ -43,7 +43,7 @@ TEST(UserScriptTest, Match2) {
EXPECT_FALSE(script.MatchesUrl(GURL("http://mail.google.com/foo")));
}
-TEST(UserScriptTest, Match3) {
+TEST(ExtensionUserScriptTest, Match3) {
UserScript script;
script.add_glob("http://mail.google.com/*");
// GURL normalizes the URL to have a trailing "/"
@@ -52,7 +52,7 @@ TEST(UserScriptTest, Match3) {
EXPECT_FALSE(script.MatchesUrl(GURL("https://mail.google.com/foo")));
}
-TEST(UserScriptTest, Match4) {
+TEST(ExtensionUserScriptTest, Match4) {
UserScript script;
script.add_glob("*");
EXPECT_TRUE(script.MatchesUrl(GURL("http://foo.com/bar")));
@@ -61,7 +61,7 @@ TEST(UserScriptTest, Match4) {
EXPECT_TRUE(script.MatchesUrl(GURL("file:///foo/bar")));
}
-TEST(UserScriptTest, Match5) {
+TEST(ExtensionUserScriptTest, Match5) {
UserScript script;
script.add_glob("*foo*");
EXPECT_TRUE(script.MatchesUrl(GURL("http://foo.com/bar")));
@@ -69,7 +69,7 @@ TEST(UserScriptTest, Match5) {
EXPECT_FALSE(script.MatchesUrl(GURL("http://baz.org")));
}
-TEST(UserScriptTest, Match6) {
+TEST(ExtensionUserScriptTest, Match6) {
URLPattern pattern(kAllSchemes);
ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("http://*/foo*"));
@@ -81,7 +81,7 @@ TEST(UserScriptTest, Match6) {
// NOTE: URLPattern is tested more extensively in url_pattern_unittest.cc.
}
-TEST(UserScriptTest, UrlPatternGlobInteraction) {
+TEST(ExtensionUserScriptTest, UrlPatternGlobInteraction) {
// If there are both, match intersection(union(globs), union(urlpatterns)).
UserScript script;
@@ -112,7 +112,7 @@ TEST(UserScriptTest, UrlPatternGlobInteraction) {
EXPECT_TRUE(script.MatchesUrl(GURL("http://www.google.com/foo")));
}
-TEST(UserScriptTest, Pickle) {
+TEST(ExtensionUserScriptTest, Pickle) {
URLPattern pattern1(kAllSchemes);
URLPattern pattern2(kAllSchemes);
ASSERT_EQ(URLPattern::PARSE_SUCCESS, pattern1.Parse("http://*/foo*"));
@@ -162,7 +162,7 @@ TEST(UserScriptTest, Pickle) {
}
}
-TEST(UserScriptTest, Defaults) {
+TEST(ExtensionUserScriptTest, Defaults) {
UserScript script;
ASSERT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
}
diff --git a/chrome/common/gpu_info.cc b/chrome/common/gpu_info.cc
index 64f0498..744fdfc 100644
--- a/chrome/common/gpu_info.cc
+++ b/chrome/common/gpu_info.cc
@@ -5,15 +5,18 @@
#include "chrome/common/gpu_info.h"
GPUInfo::GPUInfo()
- : initialized_(false), vendor_id_(0), device_id_(0), driver_version_(L""),
+ : progress_(kUninitialized),
+ vendor_id_(0),
+ device_id_(0),
+ driver_version_(L""),
pixel_shader_version_(0),
vertex_shader_version_(0),
gl_version_(0),
can_lose_context_(false) {
}
-bool GPUInfo::initialized() const {
- return initialized_;
+GPUInfo::Progress GPUInfo::progress() const {
+ return progress_;
}
base::TimeDelta GPUInfo::initialization_time() const {
@@ -68,7 +71,10 @@ void GPUInfo::SetGraphicsInfo(uint32 vendor_id, uint32 device_id,
vertex_shader_version_ = vertex_shader_version;
gl_version_ = gl_version;
can_lose_context_ = can_lose_context;
- initialized_ = true;
+}
+
+void GPUInfo::SetProgress(Progress progress) {
+ progress_ = progress;
}
#if defined(OS_WIN)
diff --git a/chrome/common/gpu_info.h b/chrome/common/gpu_info.h
index bdf8709..b8f7cc6 100644
--- a/chrome/common/gpu_info.h
+++ b/chrome/common/gpu_info.h
@@ -21,8 +21,15 @@ class GPUInfo {
GPUInfo();
~GPUInfo() {}
- // Returns whether this GPUInfo has been initialized with information
- bool initialized() const;
+ enum Progress {
+ kUninitialized,
+ kPartial,
+ kComplete,
+ };
+
+ // Returns whether this GPUInfo has been partially or fully initialized with
+ // information.
+ Progress progress() const;
// The amount of time taken to get from the process starting to the message
// loop being pumped.
@@ -60,6 +67,8 @@ class GPUInfo {
// semantics are available.
bool can_lose_context() const;
+ void SetProgress(Progress progress);
+
void SetInitializationTime(const base::TimeDelta& initialization_time);
// Populate variables with passed in values
@@ -78,7 +87,7 @@ class GPUInfo {
#endif
private:
- bool initialized_;
+ Progress progress_;
base::TimeDelta initialization_time_;
uint32 vendor_id_;
uint32 device_id_;
diff --git a/chrome/common/gpu_messages.cc b/chrome/common/gpu_messages.cc
index 671a6a6..1ba2efa 100644
--- a/chrome/common/gpu_messages.cc
+++ b/chrome/common/gpu_messages.cc
@@ -81,14 +81,15 @@ void ParamTraits<GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params> ::Log(
#endif // if defined(OS_MACOSX)
void ParamTraits<GPUInfo> ::Write(Message* m, const param_type& p) {
- ParamTraits<base::TimeDelta> ::Write(m, p.initialization_time());
- m->WriteUInt32(p.vendor_id());
- m->WriteUInt32(p.device_id());
- m->WriteWString(p.driver_version());
- m->WriteUInt32(p.pixel_shader_version());
- m->WriteUInt32(p.vertex_shader_version());
- m->WriteUInt32(p.gl_version());
- m->WriteBool(p.can_lose_context());
+ WriteParam(m, static_cast<int32>(p.progress()));
+ WriteParam(m, p.initialization_time());
+ WriteParam(m, p.vendor_id());
+ WriteParam(m, p.device_id());
+ WriteParam(m, p.driver_version());
+ WriteParam(m, p.pixel_shader_version());
+ WriteParam(m, p.vertex_shader_version());
+ WriteParam(m, p.gl_version());
+ WriteParam(m, p.can_lose_context());
#if defined(OS_WIN)
ParamTraits<DxDiagNode> ::Write(m, p.dx_diagnostics());
@@ -96,6 +97,7 @@ void ParamTraits<GPUInfo> ::Write(Message* m, const param_type& p) {
}
bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) {
+ int32 progress;
base::TimeDelta initialization_time;
uint32 vendor_id;
uint32 device_id;
@@ -104,14 +106,19 @@ bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) {
uint32 vertex_shader_version;
uint32 gl_version;
bool can_lose_context;
- bool ret = ParamTraits<base::TimeDelta> ::Read(m, iter, &initialization_time);
- ret = ret && m->ReadUInt32(iter, &vendor_id);
- ret = ret && m->ReadUInt32(iter, &device_id);
- ret = ret && m->ReadWString(iter, &driver_version);
- ret = ret && m->ReadUInt32(iter, &pixel_shader_version);
- ret = ret && m->ReadUInt32(iter, &vertex_shader_version);
- ret = ret && m->ReadUInt32(iter, &gl_version);
- ret = ret && m->ReadBool(iter, &can_lose_context);
+ bool ret = ReadParam(m, iter, &progress);
+ ret = ret && ReadParam(m, iter, &initialization_time);
+ ret = ret && ReadParam(m, iter, &vendor_id);
+ ret = ret && ReadParam(m, iter, &device_id);
+ ret = ret && ReadParam(m, iter, &driver_version);
+ ret = ret && ReadParam(m, iter, &pixel_shader_version);
+ ret = ret && ReadParam(m, iter, &vertex_shader_version);
+ ret = ret && ReadParam(m, iter, &gl_version);
+ ret = ret && ReadParam(m, iter, &can_lose_context);
+ p->SetProgress(static_cast<GPUInfo::Progress>(progress));
+ if (!ret)
+ return false;
+
p->SetInitializationTime(initialization_time);
p->SetGraphicsInfo(vendor_id,
device_id,
@@ -123,15 +130,18 @@ bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) {
#if defined(OS_WIN)
DxDiagNode dx_diagnostics;
- ret = ret && ParamTraits<DxDiagNode> ::Read(m, iter, &dx_diagnostics);
+ if (!ReadParam(m, iter, &dx_diagnostics))
+ return false;
+
p->SetDxDiagnostics(dx_diagnostics);
#endif
- return ret;
+ return true;
}
void ParamTraits<GPUInfo> ::Log(const param_type& p, std::string* l) {
- l->append(base::StringPrintf("<GPUInfo> %d %x %x %ls %d",
+ l->append(base::StringPrintf("<GPUInfo> %d %d %x %x %ls %d",
+ p.progress(),
static_cast<int32>(
p.initialization_time().InMilliseconds()),
p.vendor_id(),
@@ -141,21 +151,15 @@ void ParamTraits<GPUInfo> ::Log(const param_type& p, std::string* l) {
}
void ParamTraits<DxDiagNode> ::Write(Message* m, const param_type& p) {
- ParamTraits<std::map<std::string, std::string> >::Write(m, p.values);
- ParamTraits<std::map<std::string, DxDiagNode> >::Write(m, p.children);
+ WriteParam(m, p.values);
+ WriteParam(m, p.children);
}
bool ParamTraits<DxDiagNode> ::Read(const Message* m,
void** iter,
param_type* p) {
- bool ret = ParamTraits<std::map<std::string, std::string> >::Read(
- m,
- iter,
- &p->values);
- ret = ret && ParamTraits<std::map<std::string, DxDiagNode> >::Read(
- m,
- iter,
- &p->children);
+ bool ret = ReadParam(m, iter, &p->values);
+ ret = ret && ReadParam(m, iter, &p->children);
return ret;
}
@@ -165,22 +169,22 @@ void ParamTraits<DxDiagNode> ::Log(const param_type& p, std::string* l) {
void ParamTraits<gpu::CommandBuffer::State> ::Write(Message* m,
const param_type& p) {
- m->WriteInt(p.num_entries);
- m->WriteInt(p.get_offset);
- m->WriteInt(p.put_offset);
- m->WriteInt(p.token);
- m->WriteInt(p.error);
+ WriteParam(m, p.num_entries);
+ WriteParam(m, p.get_offset);
+ WriteParam(m, p.put_offset);
+ WriteParam(m, p.token);
+ WriteParam(m, static_cast<int32>(p.error));
}
bool ParamTraits<gpu::CommandBuffer::State> ::Read(const Message* m,
void** iter,
param_type* p) {
int32 temp;
- if (m->ReadInt(iter, &p->num_entries) &&
- m->ReadInt(iter, &p->get_offset) &&
- m->ReadInt(iter, &p->put_offset) &&
- m->ReadInt(iter, &p->token) &&
- m->ReadInt(iter, &temp)) {
+ if (ReadParam(m, iter, &p->num_entries) &&
+ ReadParam(m, iter, &p->get_offset) &&
+ ReadParam(m, iter, &p->put_offset) &&
+ ReadParam(m, iter, &p->token) &&
+ ReadParam(m, iter, &temp)) {
p->error = static_cast<gpu::error::Error>(temp);
return true;
} else {
@@ -195,14 +199,14 @@ void ParamTraits<gpu::CommandBuffer::State> ::Log(const param_type& p,
void ParamTraits<GPUCreateCommandBufferConfig> ::Write(
Message* m, const param_type& p) {
- m->WriteString(p.allowed_extensions);
- ParamTraits<std::vector<int> > ::Write(m, p.attribs);
+ WriteParam(m, p.allowed_extensions);
+ WriteParam(m, p.attribs);
}
bool ParamTraits<GPUCreateCommandBufferConfig> ::Read(
const Message* m, void** iter, param_type* p) {
- if (!m->ReadString(iter, &p->allowed_extensions) ||
- !ParamTraits<std::vector<int> > ::Read(m, iter, &p->attribs)) {
+ if (!ReadParam(m, iter, &p->allowed_extensions) ||
+ !ReadParam(m, iter, &p->attribs)) {
return false;
}
return true;
diff --git a/chrome/common/gpu_messages_unittest.cc b/chrome/common/gpu_messages_unittest.cc
index 59d42ed..904d9da 100644
--- a/chrome/common/gpu_messages_unittest.cc
+++ b/chrome/common/gpu_messages_unittest.cc
@@ -13,6 +13,7 @@
TEST(GPUIPCMessageTest, GPUInfo) {
GPUInfo input;
// Test variables taken from Lenovo T61
+ input.SetProgress(GPUInfo::kPartial);
input.SetInitializationTime(base::TimeDelta::FromMilliseconds(100));
input.SetGraphicsInfo(0x10de, 0x429, L"6.14.11.7715",
0xffff0300,
@@ -26,6 +27,7 @@ TEST(GPUIPCMessageTest, GPUInfo) {
GPUInfo output;
void* iter = NULL;
EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output));
+ EXPECT_EQ(input.progress(), output.progress());
EXPECT_EQ(input.initialization_time().InMilliseconds(),
output.initialization_time().InMilliseconds());
EXPECT_EQ(input.vendor_id(), output.vendor_id());
@@ -38,5 +40,5 @@ TEST(GPUIPCMessageTest, GPUInfo) {
std::string log_message;
IPC::LogParam(output, &log_message);
- EXPECT_STREQ("<GPUInfo> 100 10de 429 6.14.11.7715 1", log_message.c_str());
+ EXPECT_STREQ("<GPUInfo> 1 100 10de 429 6.14.11.7715 1", log_message.c_str());
}
diff --git a/chrome/common/json_schema_validator.cc b/chrome/common/json_schema_validator.cc
new file mode 100644
index 0000000..ee28a89
--- /dev/null
+++ b/chrome/common/json_schema_validator.cc
@@ -0,0 +1,503 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/json_schema_validator.h"
+
+#include <cfloat>
+#include <cmath>
+
+#include "app/l10n_util.h"
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "base/values.h"
+
+namespace {
+
+double GetNumberValue(Value* value) {
+ double result = 0;
+ if (value->GetAsReal(&result))
+ return result;
+
+ int int_result = 0;
+ if (value->GetAsInteger(&int_result)) {
+ return int_result;
+ }
+
+ CHECK(false) << "Unexpected value type: " << value->GetType();
+ return 0;
+}
+
+bool GetNumberFromDictionary(DictionaryValue* value, const std::string& key,
+ double* number) {
+ if (value->GetReal(key, number))
+ return true;
+
+ int int_value = 0;
+ if (value->GetInteger(key, &int_value)) {
+ *number = int_value;
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+
+JSONSchemaValidator::Error::Error() {
+}
+
+JSONSchemaValidator::Error::Error(const std::string& message)
+ : path(message) {
+}
+
+JSONSchemaValidator::Error::Error(const std::string& path,
+ const std::string& message)
+ : path(path), message(message) {
+}
+
+
+const char JSONSchemaValidator::kUnknownTypeReference[] =
+ "Unknown schema reference: *.";
+const char JSONSchemaValidator::kInvalidChoice[] =
+ "Value does not match any valid type choices.";
+const char JSONSchemaValidator::kInvalidEnum[] =
+ "Value does not match any valid enum choices.";
+const char JSONSchemaValidator::kObjectPropertyIsRequired[] =
+ "Property is required.";
+const char JSONSchemaValidator::kUnexpectedProperty[] =
+ "Unexpected property.";
+const char JSONSchemaValidator::kArrayMinItems[] =
+ "Array must have at least * items.";
+const char JSONSchemaValidator::kArrayMaxItems[] =
+ "Array must not have more than * items.";
+const char JSONSchemaValidator::kArrayItemRequired[] =
+ "Item is required.";
+const char JSONSchemaValidator::kStringMinLength[] =
+ "String must be at least * characters long.";
+const char JSONSchemaValidator::kStringMaxLength[] =
+ "String must not be more than * characters long.";
+const char JSONSchemaValidator::kStringPattern[] =
+ "String must match the pattern: *.";
+const char JSONSchemaValidator::kNumberMinimum[] =
+ "Value must not be less than *.";
+const char JSONSchemaValidator::kNumberMaximum[] =
+ "Value must not be greater than *.";
+const char JSONSchemaValidator::kInvalidType[] =
+ "Expected '*' but got '*'.";
+
+
+// static
+std::string JSONSchemaValidator::GetJSONSchemaType(Value* value) {
+ switch (value->GetType()) {
+ case Value::TYPE_NULL:
+ return "null";
+ case Value::TYPE_BOOLEAN:
+ return "boolean";
+ case Value::TYPE_INTEGER:
+ return "integer";
+ case Value::TYPE_REAL: {
+ double double_value = 0;
+ value->GetAsReal(&double_value);
+ if (std::abs(double_value) <= std::pow(2.0, DBL_MANT_DIG) &&
+ double_value == floor(double_value)) {
+ return "integer";
+ } else {
+ return "number";
+ }
+ }
+ case Value::TYPE_STRING:
+ return "string";
+ case Value::TYPE_DICTIONARY:
+ return "object";
+ case Value::TYPE_LIST:
+ return "array";
+ default:
+ CHECK(false) << "Unexpected value type: " << value->GetType();
+ return "";
+ }
+}
+
+// static
+std::string JSONSchemaValidator::FormatErrorMessage(const std::string& format,
+ const std::string& s1) {
+ std::string ret_val = format;
+ ReplaceFirstSubstringAfterOffset(&ret_val, 0, "*", s1);
+ return ret_val;
+}
+
+// static
+std::string JSONSchemaValidator::FormatErrorMessage(const std::string& format,
+ const std::string& s1,
+ const std::string& s2) {
+ std::string ret_val = format;
+ ReplaceFirstSubstringAfterOffset(&ret_val, 0, "*", s1);
+ ReplaceFirstSubstringAfterOffset(&ret_val, 0, "*", s2);
+ return ret_val;
+}
+
+JSONSchemaValidator::JSONSchemaValidator(DictionaryValue* schema)
+ : schema_root_(schema), default_allow_additional_properties_(false) {
+}
+
+JSONSchemaValidator::JSONSchemaValidator(DictionaryValue* schema,
+ ListValue* types)
+ : schema_root_(schema), default_allow_additional_properties_(false) {
+ if (!types)
+ return;
+
+ for (size_t i = 0; i < types->GetSize(); ++i) {
+ DictionaryValue* type = NULL;
+ CHECK(types->GetDictionary(i, &type));
+
+ std::string id;
+ CHECK(type->GetString("id", &id));
+
+ CHECK(types_.find(id) == types_.end());
+ types_[id] = type;
+ }
+}
+
+
+bool JSONSchemaValidator::Validate(Value* instance) {
+ errors_.clear();
+ Validate(instance, schema_root_, "");
+ return errors_.empty();
+}
+
+void JSONSchemaValidator::Validate(Value* instance,
+ DictionaryValue* schema,
+ const std::string& path) {
+ // If this schema defines itself as reference type, save it in this.types.
+ std::string id;
+ if (schema->GetString("id", &id)) {
+ TypeMap::iterator iter = types_.find(id);
+ if (iter == types_.end())
+ types_[id] = schema;
+ else
+ CHECK(iter->second == schema);
+ }
+
+ // If the schema has a $ref property, the instance must validate against
+ // that schema. It must be present in types_ to be referenced.
+ std::string ref;
+ if (schema->GetString("$ref", &ref)) {
+ TypeMap::iterator type = types_.find(ref);
+ if (type == types_.end()) {
+ errors_.push_back(
+ Error(path, FormatErrorMessage(kUnknownTypeReference, ref)));
+ } else {
+ Validate(instance, type->second, path);
+ }
+ return;
+ }
+
+ // If the schema has a choices property, the instance must validate against at
+ // least one of the items in that array.
+ ListValue* choices = NULL;
+ if (schema->GetList("choices", &choices)) {
+ ValidateChoices(instance, choices, path);
+ return;
+ }
+
+ // If the schema has an enum property, the instance must be one of those
+ // values.
+ ListValue* enumeration = NULL;
+ if (schema->GetList("enum", &enumeration)) {
+ ValidateEnum(instance, enumeration, path);
+ return;
+ }
+
+ std::string type;
+ schema->GetString("type", &type);
+ CHECK(!type.empty());
+ if (type != "any") {
+ if (!ValidateType(instance, type, path))
+ return;
+
+ // These casts are safe because of checks in ValidateType().
+ if (type == "object")
+ ValidateObject(static_cast<DictionaryValue*>(instance), schema, path);
+ else if (type == "array")
+ ValidateArray(static_cast<ListValue*>(instance), schema, path);
+ else if (type == "string")
+ ValidateString(static_cast<StringValue*>(instance), schema, path);
+ else if (type == "number" || type == "integer")
+ ValidateNumber(instance, schema, path);
+ else if (type != "boolean" && type != "null")
+ CHECK(false) << "Unexpected type: " << type;
+ }
+}
+
+void JSONSchemaValidator::ValidateChoices(Value* instance,
+ ListValue* choices,
+ const std::string& path) {
+ size_t original_num_errors = errors_.size();
+
+ for (size_t i = 0; i < choices->GetSize(); ++i) {
+ DictionaryValue* choice = NULL;
+ CHECK(choices->GetDictionary(i, &choice));
+
+ Validate(instance, choice, path);
+ if (errors_.size() == original_num_errors)
+ return;
+
+ // We discard the error from each choice. We only want to know if any of the
+ // validations succeeded.
+ errors_.resize(original_num_errors);
+ }
+
+ // Now add a generic error that no choices matched.
+ errors_.push_back(Error(path, kInvalidChoice));
+ return;
+}
+
+void JSONSchemaValidator::ValidateEnum(Value* instance,
+ ListValue* choices,
+ const std::string& path) {
+ for (size_t i = 0; i < choices->GetSize(); ++i) {
+ Value* choice = NULL;
+ CHECK(choices->Get(i, &choice));
+ switch (choice->GetType()) {
+ case Value::TYPE_NULL:
+ case Value::TYPE_BOOLEAN:
+ case Value::TYPE_STRING:
+ if (instance->Equals(choice))
+ return;
+ break;
+
+ case Value::TYPE_INTEGER:
+ case Value::TYPE_REAL:
+ if (instance->IsType(Value::TYPE_INTEGER) ||
+ instance->IsType(Value::TYPE_REAL)) {
+ if (GetNumberValue(choice) == GetNumberValue(instance))
+ return;
+ }
+ break;
+
+ default:
+ CHECK(false) << "Unexpected type in enum: " << choice->GetType();
+ }
+ }
+
+ errors_.push_back(Error(path, kInvalidEnum));
+}
+
+void JSONSchemaValidator::ValidateObject(DictionaryValue* instance,
+ DictionaryValue* schema,
+ const std::string& path) {
+ DictionaryValue* properties = NULL;
+ schema->GetDictionary("properties", &properties);
+ if (properties) {
+ for (DictionaryValue::key_iterator key = properties->begin_keys();
+ key != properties->end_keys(); ++key) {
+ std::string prop_path = path.empty() ? *key : (path + "." + *key);
+ DictionaryValue* prop_schema = NULL;
+ CHECK(properties->GetDictionary(*key, &prop_schema));
+
+ Value* prop_value = NULL;
+ if (instance->Get(*key, &prop_value)) {
+ Validate(prop_value, prop_schema, prop_path);
+ } else {
+ // Properties are required unless there is an optional field set to
+ // 'true'.
+ bool is_optional = false;
+ prop_schema->GetBoolean("optional", &is_optional);
+ if (!is_optional) {
+ errors_.push_back(Error(prop_path, kObjectPropertyIsRequired));
+ }
+ }
+ }
+ }
+
+ DictionaryValue* additional_properties_schema = NULL;
+ if (SchemaAllowsAnyAdditionalItems(schema, &additional_properties_schema))
+ return;
+
+ // Validate additional properties.
+ for (DictionaryValue::key_iterator key = instance->begin_keys();
+ key != instance->end_keys(); ++key) {
+ if (properties && properties->HasKey(*key))
+ continue;
+
+ std::string prop_path = path.empty() ? *key : path + "." + *key;
+ if (!additional_properties_schema) {
+ errors_.push_back(Error(prop_path, kUnexpectedProperty));
+ } else {
+ Value* prop_value = NULL;
+ CHECK(instance->Get(*key, &prop_value));
+ Validate(prop_value, additional_properties_schema, prop_path);
+ }
+ }
+}
+
+void JSONSchemaValidator::ValidateArray(ListValue* instance,
+ DictionaryValue* schema,
+ const std::string& path) {
+ DictionaryValue* single_type = NULL;
+ size_t instance_size = instance->GetSize();
+ if (schema->GetDictionary("items", &single_type)) {
+ int min_items = 0;
+ if (schema->GetInteger("minItems", &min_items)) {
+ CHECK(min_items >= 0);
+ if (instance_size < static_cast<size_t>(min_items)) {
+ errors_.push_back(Error(path, FormatErrorMessage(
+ kArrayMinItems, base::IntToString(min_items))));
+ }
+ }
+
+ int max_items = 0;
+ if (schema->GetInteger("maxItems", &max_items)) {
+ CHECK(max_items >= 0);
+ if (instance_size > static_cast<size_t>(max_items)) {
+ errors_.push_back(Error(path, FormatErrorMessage(
+ kArrayMaxItems, base::IntToString(max_items))));
+ }
+ }
+
+ // If the items property is a single schema, each item in the array must
+ // validate against that schema.
+ for (size_t i = 0; i < instance_size; ++i) {
+ Value* item = NULL;
+ CHECK(instance->Get(i, &item));
+ std::string i_str = base::UintToString(i);
+ std::string item_path = path.empty() ? i_str : (path + "." + i_str);
+ Validate(item, single_type, item_path);
+ }
+
+ return;
+ }
+
+ // Otherwise, the list must be a tuple type, where each item in the list has a
+ // particular schema.
+ ValidateTuple(instance, schema, path);
+}
+
+void JSONSchemaValidator::ValidateTuple(ListValue* instance,
+ DictionaryValue* schema,
+ const std::string& path) {
+ ListValue* tuple_type = NULL;
+ schema->GetList("items", &tuple_type);
+ size_t tuple_size = tuple_type ? tuple_type->GetSize() : 0;
+ if (tuple_type) {
+ for (size_t i = 0; i < tuple_size; ++i) {
+ std::string i_str = base::UintToString(i);
+ std::string item_path = path.empty() ? i_str : (path + "." + i_str);
+ DictionaryValue* item_schema = NULL;
+ CHECK(tuple_type->GetDictionary(i, &item_schema));
+ Value* item_value = NULL;
+ instance->Get(i, &item_value);
+ if (item_value && item_value->GetType() != Value::TYPE_NULL) {
+ Validate(item_value, item_schema, item_path);
+ } else {
+ bool is_optional = false;
+ item_schema->GetBoolean("optional", &is_optional);
+ if (!is_optional) {
+ errors_.push_back(Error(item_path, kArrayItemRequired));
+ return;
+ }
+ }
+ }
+ }
+
+ DictionaryValue* additional_properties_schema = NULL;
+ if (SchemaAllowsAnyAdditionalItems(schema, &additional_properties_schema))
+ return;
+
+ size_t instance_size = instance->GetSize();
+ if (additional_properties_schema) {
+ // Any additional properties must validate against the additionalProperties
+ // schema.
+ for (size_t i = tuple_size; i < instance_size; ++i) {
+ std::string i_str = base::UintToString(i);
+ std::string item_path = path.empty() ? i_str : (path + "." + i_str);
+ Value* item_value = NULL;
+ CHECK(instance->Get(i, &item_value));
+ Validate(item_value, additional_properties_schema, item_path);
+ }
+ } else if (instance_size > tuple_size) {
+ errors_.push_back(Error(path, FormatErrorMessage(
+ kArrayMaxItems, base::UintToString(tuple_size))));
+ }
+}
+
+void JSONSchemaValidator::ValidateString(StringValue* instance,
+ DictionaryValue* schema,
+ const std::string& path) {
+ std::string value;
+ CHECK(instance->GetAsString(&value));
+
+ int min_length = 0;
+ if (schema->GetInteger("minLength", &min_length)) {
+ CHECK(min_length >= 0);
+ if (value.size() < static_cast<size_t>(min_length)) {
+ errors_.push_back(Error(path, FormatErrorMessage(
+ kStringMinLength, base::IntToString(min_length))));
+ }
+ }
+
+ int max_length = 0;
+ if (schema->GetInteger("maxLength", &max_length)) {
+ CHECK(max_length >= 0);
+ if (value.size() > static_cast<size_t>(max_length)) {
+ errors_.push_back(Error(path, FormatErrorMessage(
+ kStringMaxLength, base::IntToString(max_length))));
+ }
+ }
+
+ CHECK(!schema->HasKey("pattern")) << "Pattern is not supported.";
+}
+
+void JSONSchemaValidator::ValidateNumber(Value* instance,
+ DictionaryValue* schema,
+ const std::string& path) {
+ double value = GetNumberValue(instance);
+
+ // TODO(aa): It would be good to test that the double is not infinity or nan,
+ // but isnan and isinf aren't defined on Windows.
+
+ double minimum = 0;
+ if (GetNumberFromDictionary(schema, "minimum", &minimum)) {
+ if (value < minimum)
+ errors_.push_back(Error(path, FormatErrorMessage(
+ kNumberMinimum, base::DoubleToString(minimum))));
+ }
+
+ double maximum = 0;
+ if (GetNumberFromDictionary(schema, "maximum", &maximum)) {
+ if (value > maximum)
+ errors_.push_back(Error(path, FormatErrorMessage(
+ kNumberMaximum, base::DoubleToString(maximum))));
+ }
+}
+
+bool JSONSchemaValidator::ValidateType(Value* instance,
+ const std::string& expected_type,
+ const std::string& path) {
+ std::string actual_type = GetJSONSchemaType(instance);
+ if (expected_type == actual_type ||
+ (expected_type == "number" && actual_type == "integer")) {
+ return true;
+ } else {
+ errors_.push_back(Error(path, FormatErrorMessage(
+ kInvalidType, expected_type, actual_type)));
+ return false;
+ }
+}
+
+bool JSONSchemaValidator::SchemaAllowsAnyAdditionalItems(
+ DictionaryValue* schema, DictionaryValue** additional_properties_schema) {
+ // If the validator allows additional properties globally, and this schema
+ // doesn't override, then we can exit early.
+ schema->GetDictionary("additionalProperties", additional_properties_schema);
+
+ if (*additional_properties_schema) {
+ std::string additional_properties_type("any");
+ CHECK((*additional_properties_schema)->GetString(
+ "type", &additional_properties_type));
+ return additional_properties_type == "any";
+ } else {
+ return default_allow_additional_properties_;
+ }
+}
diff --git a/chrome/common/json_schema_validator.h b/chrome/common/json_schema_validator.h
new file mode 100644
index 0000000..9af31fb
--- /dev/null
+++ b/chrome/common/json_schema_validator.h
@@ -0,0 +1,211 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_JSON_SCHEMA_VALIDATOR_H_
+#define CHROME_COMMON_JSON_SCHEMA_VALIDATOR_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+
+class DictionaryValue;
+class FundamentalValue;
+class ListValue;
+class StringValue;
+class Value;
+
+//==============================================================================
+// This class implements a subset of JSON Schema.
+// See: http://www.json.com/json-schema-proposal/ for more details.
+//
+// There is also an older JavaScript implementation of the same functionality in
+// chrome/renderer/resources/json_schema.js.
+//
+// The following features of JSON Schema are not implemented:
+// - requires
+// - unique
+// - disallow
+// - union types (but replaced with 'choices')
+// - number.maxDecimal
+// - string.pattern
+//
+// The following properties are not applicable to the interface exposed by
+// this class:
+// - options
+// - readonly
+// - title
+// - description
+// - format
+// - default
+// - transient
+// - hidden
+//
+// There are also these departures from the JSON Schema proposal:
+// - null counts as 'unspecified' for optional values
+// - added the 'choices' property, to allow specifying a list of possible types
+// for a value
+// - by default an "object" typed schema does not allow additional properties.
+// if present, "additionalProperties" is to be a schema against which all
+// additional properties will be validated.
+//==============================================================================
+class JSONSchemaValidator {
+ public:
+ // Details about a validation error.
+ struct Error {
+ Error();
+
+ explicit Error(const std::string& message);
+
+ Error(const std::string& path, const std::string& message);
+
+ // The path to the location of the error in the JSON structure.
+ std::string path;
+
+ // An english message describing the error.
+ std::string message;
+ };
+
+ // Error messages.
+ static const char kUnknownTypeReference[];
+ static const char kInvalidChoice[];
+ static const char kInvalidEnum[];
+ static const char kObjectPropertyIsRequired[];
+ static const char kUnexpectedProperty[];
+ static const char kArrayMinItems[];
+ static const char kArrayMaxItems[];
+ static const char kArrayItemRequired[];
+ static const char kStringMinLength[];
+ static const char kStringMaxLength[];
+ static const char kStringPattern[];
+ static const char kNumberMinimum[];
+ static const char kNumberMaximum[];
+ static const char kInvalidType[];
+
+ // Classifies a Value as one of the JSON schema primitive types.
+ static std::string GetJSONSchemaType(Value* value);
+
+ // Utility methods to format error messages. The first method can have one
+ // wildcard represented by '*', which is replaced with s1. The second method
+ // can have two, which are replaced by s1 and s2.
+ static std::string FormatErrorMessage(const std::string& format,
+ const std::string& s1);
+ static std::string FormatErrorMessage(const std::string& format,
+ const std::string& s1,
+ const std::string& s2);
+
+ // Creates a validator for the specified schema.
+ //
+ // NOTE: This constructor assumes that |schema| is well formed and valid.
+ // Errors will result in CHECK at runtime; this constructor should not be used
+ // with untrusted schemas.
+ explicit JSONSchemaValidator(DictionaryValue* schema);
+
+ // Creates a validator for the specified schema and user-defined types. Each
+ // type must be a valid JSONSchema type description with an additional "id"
+ // field. Schema objects in |schema| can refer to these types with the "$ref"
+ // property.
+ //
+ // NOTE: This constructor assumes that |schema| and |types| are well-formed
+ // and valid. Errors will result in CHECK at runtime; this constructor should
+ // not be used with untrusted schemas.
+ JSONSchemaValidator(DictionaryValue* schema, ListValue* types);
+
+ // Whether the validator allows additional items for objects and lists, beyond
+ // those defined by their schema, by default.
+ //
+ // This setting defaults to false: all items in an instance list or object
+ // must be defined by the corresponding schema.
+ //
+ // This setting can be overridden on individual object and list schemas by
+ // setting the "additionalProperties" field.
+ bool default_allow_additional_properties() const {
+ return default_allow_additional_properties_;
+ }
+
+ void set_default_allow_additional_properties(bool val) {
+ default_allow_additional_properties_ = val;
+ }
+
+ // Returns any errors from the last call to to Validate().
+ const std::vector<Error>& errors() const {
+ return errors_;
+ }
+
+ // Validates a JSON value. Returns true if the instance is valid, false
+ // otherwise. If false is returned any errors are available from the errors()
+ // getter.
+ bool Validate(Value* instance);
+
+ private:
+ typedef std::map<std::string, DictionaryValue*> TypeMap;
+
+ // Each of the below methods handle a subset of the validation process. The
+ // path paramater is the path to |instance| from the root of the instance tree
+ // and is used in error messages.
+
+ // Validates any instance node against any schema node. This is called for
+ // every node in the instance tree, and it just decides which of the more
+ // detailed methods to call.
+ void Validate(Value* instance, DictionaryValue* schema,
+ const std::string& path);
+
+ // Validates a node against a list of possible schemas. If any one of the
+ // schemas match, the node is valid.
+ void ValidateChoices(Value* instance, ListValue* choices,
+ const std::string& path);
+
+ // Validates a node against a list of exact primitive values, eg 42, "foobar".
+ void ValidateEnum(Value* instance, ListValue* choices,
+ const std::string& path);
+
+ // Validates a JSON object against an object schema node.
+ void ValidateObject(DictionaryValue* instance, DictionaryValue* schema,
+ const std::string& path);
+
+ // Validates a JSON array against an array schema node.
+ void ValidateArray(ListValue* instance, DictionaryValue* schema,
+ const std::string& path);
+
+ // Validates a JSON array against an array schema node configured to be a
+ // tuple. In a tuple, there is one schema node for each item expected in the
+ // array.
+ void ValidateTuple(ListValue* instance, DictionaryValue* schema,
+ const std::string& path);
+
+ // Validate a JSON string against a string schema node.
+ void ValidateString(StringValue* instance, DictionaryValue* schema,
+ const std::string& path);
+
+ // Validate a JSON number against a number schema node.
+ void ValidateNumber(Value* instance, DictionaryValue* schema,
+ const std::string& path);
+
+ // Validates that the JSON node |instance| has |expected_type|.
+ bool ValidateType(Value* instance, const std::string& expected_type,
+ const std::string& path);
+
+ // Returns true if |schema| will allow additional items of any type.
+ bool SchemaAllowsAnyAdditionalItems(
+ DictionaryValue* schema, DictionaryValue** addition_items_schema);
+
+ // The root schema node.
+ DictionaryValue* schema_root_;
+
+ // Map of user-defined name to type.
+ TypeMap types_;
+
+ // Whether we allow additional properties on objects by default. This can be
+ // overridden by the allow_additional_properties flag on an Object schema.
+ bool default_allow_additional_properties_;
+
+ // Errors accumulated since the last call to Validate().
+ std::vector<Error> errors_;
+
+
+ DISALLOW_COPY_AND_ASSIGN(JSONSchemaValidator);
+};
+
+#endif // CHROME_COMMON_JSON_SCHEMA_VALIDATOR_H_
diff --git a/chrome/common/json_schema_validator_unittest.cc b/chrome/common/json_schema_validator_unittest.cc
new file mode 100644
index 0000000..ca4b388
--- /dev/null
+++ b/chrome/common/json_schema_validator_unittest.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/values.h"
+#include "chrome/common/json_schema_validator.h"
+#include "chrome/common/json_schema_validator_unittest_base.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class JSONSchemaValidatorCPPTest : public JSONSchemaValidatorTestBase {
+ public:
+ JSONSchemaValidatorCPPTest()
+ : JSONSchemaValidatorTestBase(JSONSchemaValidatorTestBase::CPP) {
+ }
+
+ protected:
+ virtual void ExpectValid(const std::string& test_source,
+ Value* instance, DictionaryValue* schema,
+ ListValue* types) {
+ JSONSchemaValidator validator(schema, types);
+ if (validator.Validate(instance))
+ return;
+
+ for (size_t i = 0; i < validator.errors().size(); ++i) {
+ ADD_FAILURE() << test_source << ": "
+ << validator.errors()[i].path << ": "
+ << validator.errors()[i].message;
+ }
+ }
+
+ virtual void ExpectNotValid(const std::string& test_source,
+ Value* instance, DictionaryValue* schema,
+ ListValue* types,
+ const std::string& expected_error_path,
+ const std::string& expected_error_message) {
+ JSONSchemaValidator validator(schema, types);
+ if (validator.Validate(instance)) {
+ ADD_FAILURE() << test_source;
+ return;
+ }
+
+ ASSERT_EQ(1u, validator.errors().size()) << test_source;
+ EXPECT_EQ(expected_error_path, validator.errors()[0].path) << test_source;
+ EXPECT_EQ(expected_error_message, validator.errors()[0].message)
+ << test_source;
+ }
+};
+
+TEST_F(JSONSchemaValidatorCPPTest, Test) {
+ RunTests();
+}
diff --git a/chrome/common/json_schema_validator_unittest_base.cc b/chrome/common/json_schema_validator_unittest_base.cc
new file mode 100644
index 0000000..782d6bc
--- /dev/null
+++ b/chrome/common/json_schema_validator_unittest_base.cc
@@ -0,0 +1,628 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/json_schema_validator_unittest_base.h"
+
+#include <cfloat>
+#include <cmath>
+#include <limits>
+
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/scoped_ptr.h"
+#include "base/stringprintf.h"
+#include "base/values.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/json_schema_validator.h"
+#include "chrome/common/json_value_serializer.h"
+
+namespace {
+
+#define TEST_SOURCE base::StringPrintf("%s:%i", __FILE__, __LINE__)
+
+Value* LoadValue(const std::string& filename) {
+ FilePath path;
+ PathService::Get(chrome::DIR_TEST_DATA, &path);
+ path = path.AppendASCII("json_schema_validator").AppendASCII(filename);
+ EXPECT_TRUE(file_util::PathExists(path));
+
+ std::string error_message;
+ JSONFileValueSerializer serializer(path);
+ Value* result = serializer.Deserialize(NULL, &error_message);
+ if (!result)
+ ADD_FAILURE() << "Could not parse JSON: " << error_message;
+ return result;
+}
+
+Value* LoadValue(const std::string& filename, Value::ValueType type) {
+ scoped_ptr<Value> result(LoadValue(filename));
+ if (!result.get())
+ return NULL;
+ if (!result->IsType(type)) {
+ ADD_FAILURE() << "Expected type " << type << ", got: " << result->GetType();
+ return NULL;
+ }
+ return result.release();
+}
+
+ListValue* LoadList(const std::string& filename) {
+ return static_cast<ListValue*>(
+ LoadValue(filename, Value::TYPE_LIST));
+}
+
+DictionaryValue* LoadDictionary(const std::string& filename) {
+ return static_cast<DictionaryValue*>(
+ LoadValue(filename, Value::TYPE_DICTIONARY));
+}
+
+} // namespace
+
+
+JSONSchemaValidatorTestBase::JSONSchemaValidatorTestBase(
+ JSONSchemaValidatorTestBase::ValidatorType type)
+ : type_(type) {
+}
+
+void JSONSchemaValidatorTestBase::RunTests() {
+ TestComplex();
+ TestStringPattern();
+ TestEnum();
+ TestChoices();
+ TestExtends();
+ TestObject();
+ TestTypeReference();
+ TestArrayTuple();
+ TestArrayNonTuple();
+ TestString();
+ TestNumber();
+ TestTypeClassifier();
+ TestTypes();
+}
+
+void JSONSchemaValidatorTestBase::TestComplex() {
+ scoped_ptr<DictionaryValue> schema(LoadDictionary("complex_schema.json"));
+ scoped_ptr<ListValue> instance(LoadList("complex_instance.json"));
+
+ ASSERT_TRUE(schema.get());
+ ASSERT_TRUE(instance.get());
+
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+ instance->Remove(instance->GetSize() - 1, NULL);
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+ instance->Append(new DictionaryValue());
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "number", "object"));
+ instance->Remove(instance->GetSize() - 1, NULL);
+
+ DictionaryValue* item = NULL;
+ ASSERT_TRUE(instance->GetDictionary(0, &item));
+ item->SetString("url", "xxxxxxxxxxx");
+
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
+ "0.url",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kStringMaxLength, "10"));
+}
+
+void JSONSchemaValidatorTestBase::TestStringPattern() {
+ // Regex patterns not supported in CPP validator.
+ if (type_ == CPP)
+ return;
+
+ scoped_ptr<DictionaryValue> schema(new DictionaryValue());
+ schema->SetString("type", "string");
+ schema->SetString("pattern", "foo+");
+
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("foo")).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("foooooo")).get(),
+ schema.get(), NULL);
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("bar")).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kStringPattern, "foo+"));
+}
+
+void JSONSchemaValidatorTestBase::TestEnum() {
+ scoped_ptr<DictionaryValue> schema(LoadDictionary("enum_schema.json"));
+
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("foo")).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateBooleanValue(false)).get(),
+ schema.get(), NULL);
+
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("42")).get(),
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidEnum);
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateNullValue()).get(),
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidEnum);
+}
+
+void JSONSchemaValidatorTestBase::TestChoices() {
+ scoped_ptr<DictionaryValue> schema(LoadDictionary("choices_schema.json"));
+
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateNullValue()).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
+ schema.get(), NULL);
+
+ scoped_ptr<DictionaryValue> instance(new DictionaryValue());
+ instance->SetString("foo", "bar");
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("foo")).get(),
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidChoice);
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(new ListValue()).get(),
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidChoice);
+
+ instance->SetInteger("foo", 42);
+ ExpectNotValid(TEST_SOURCE, instance.get(),
+ schema.get(), NULL, "", JSONSchemaValidator::kInvalidChoice);
+}
+
+void JSONSchemaValidatorTestBase::TestExtends() {
+ // TODO(aa): JS only
+}
+
+void JSONSchemaValidatorTestBase::TestObject() {
+ scoped_ptr<DictionaryValue> schema(new DictionaryValue());
+ schema->SetString("type", "object");
+ schema->SetString("properties.foo.type", "string");
+ schema->SetString("properties.bar.type", "integer");
+
+ scoped_ptr<DictionaryValue> instance(new DictionaryValue());
+ instance->SetString("foo", "foo");
+ instance->SetInteger("bar", 42);
+
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+
+ instance->SetBoolean("extra", true);
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
+ "extra", JSONSchemaValidator::kUnexpectedProperty);
+
+ instance->Remove("extra", NULL);
+ instance->Remove("bar", NULL);
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar",
+ JSONSchemaValidator::kObjectPropertyIsRequired);
+
+ instance->SetString("bar", "42");
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "bar",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "integer", "string"));
+
+ DictionaryValue* additional_properties = new DictionaryValue();
+ additional_properties->SetString("type", "any");
+ schema->Set("additionalProperties", additional_properties);
+
+ instance->SetInteger("bar", 42);
+ instance->SetBoolean("extra", true);
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+
+ instance->SetString("extra", "foo");
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+
+ additional_properties->SetString("type", "boolean");
+ instance->SetBoolean("extra", true);
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+
+ instance->SetString("extra", "foo");
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
+ "extra", JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "boolean", "string"));
+
+ DictionaryValue* properties = NULL;
+ DictionaryValue* bar_property = NULL;
+ ASSERT_TRUE(schema->GetDictionary("properties", &properties));
+ ASSERT_TRUE(properties->GetDictionary("bar", &bar_property));
+
+ bar_property->SetBoolean("optional", true);
+ instance->Remove("extra", NULL);
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+ instance->Remove("bar", NULL);
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+ instance->Set("bar", Value::CreateNullValue());
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
+ "bar", JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "integer", "null"));
+ instance->SetString("bar", "42");
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL,
+ "bar", JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "integer", "string"));
+}
+
+void JSONSchemaValidatorTestBase::TestTypeReference() {
+ scoped_ptr<ListValue> types(LoadList("reference_types.json"));
+ ASSERT_TRUE(types.get());
+
+ scoped_ptr<DictionaryValue> schema(new DictionaryValue());
+ schema->SetString("type", "object");
+ schema->SetString("properties.foo.type", "string");
+ schema->SetString("properties.bar.$ref", "Max10Int");
+ schema->SetString("properties.baz.$ref", "MinLengthString");
+
+ scoped_ptr<DictionaryValue> schema_inline(new DictionaryValue());
+ schema_inline->SetString("type", "object");
+ schema_inline->SetString("properties.foo.type", "string");
+ schema_inline->SetString("properties.bar.id", "NegativeInt");
+ schema_inline->SetString("properties.bar.type", "integer");
+ schema_inline->SetInteger("properties.bar.maximum", 0);
+ schema_inline->SetString("properties.baz.$ref", "NegativeInt");
+
+ scoped_ptr<DictionaryValue> instance(new DictionaryValue());
+ instance->SetString("foo", "foo");
+ instance->SetInteger("bar", 4);
+ instance->SetString("baz", "ab");
+
+ scoped_ptr<DictionaryValue> instance_inline(new DictionaryValue());
+ instance_inline->SetString("foo", "foo");
+ instance_inline->SetInteger("bar", -4);
+ instance_inline->SetInteger("baz", -2);
+
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), types.get());
+ ExpectValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL);
+
+ // Validation failure, but successful schema reference.
+ instance->SetString("baz", "a");
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(),
+ "baz", JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kStringMinLength, "2"));
+
+ instance_inline->SetInteger("bar", 20);
+ ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL,
+ "bar", JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kNumberMaximum, "0"));
+
+ // Remove MinLengthString type.
+ types->Remove(types->GetSize() - 1, NULL);
+ instance->SetString("baz", "ab");
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), types.get(),
+ "bar", JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kUnknownTypeReference,
+ "Max10Int"));
+
+ // Remove internal type "NegativeInt".
+ schema_inline->Remove("properties.bar", NULL);
+ instance_inline->Remove("bar", NULL);
+ ExpectNotValid(TEST_SOURCE, instance_inline.get(), schema_inline.get(), NULL,
+ "baz", JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kUnknownTypeReference,
+ "NegativeInt"));
+}
+
+void JSONSchemaValidatorTestBase::TestArrayTuple() {
+ scoped_ptr<DictionaryValue> schema(LoadDictionary("array_tuple_schema.json"));
+ ASSERT_TRUE(schema.get());
+
+ scoped_ptr<ListValue> instance(new ListValue());
+ instance->Append(Value::CreateStringValue("42"));
+ instance->Append(Value::CreateIntegerValue(42));
+
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+
+ instance->Append(Value::CreateStringValue("anything"));
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kArrayMaxItems, "2"));
+
+ instance->Remove(1, NULL);
+ instance->Remove(1, NULL);
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
+ JSONSchemaValidator::kArrayItemRequired);
+
+ instance->Set(0, Value::CreateIntegerValue(42));
+ instance->Append(Value::CreateIntegerValue(42));
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "string", "integer"));
+
+ DictionaryValue* additional_properties = new DictionaryValue();
+ additional_properties->SetString("type", "any");
+ schema->Set("additionalProperties", additional_properties);
+ instance->Set(0, Value::CreateStringValue("42"));
+ instance->Append(Value::CreateStringValue("anything"));
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+ instance->Set(2, new ListValue());
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+
+ additional_properties->SetString("type", "boolean");
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "2",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "boolean", "array"));
+ instance->Set(2, Value::CreateBooleanValue(false));
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+
+ ListValue* items_schema = NULL;
+ DictionaryValue* item0_schema = NULL;
+ ASSERT_TRUE(schema->GetList("items", &items_schema));
+ ASSERT_TRUE(items_schema->GetDictionary(0, &item0_schema));
+ item0_schema->SetBoolean("optional", true);
+ instance->Remove(2, NULL);
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+ // TODO(aa): I think this is inconsistent with the handling of NULL+optional
+ // for objects.
+ instance->Set(0, Value::CreateNullValue());
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+ instance->Set(0, Value::CreateIntegerValue(42));
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "0",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "string", "integer"));
+}
+
+void JSONSchemaValidatorTestBase::TestArrayNonTuple() {
+ scoped_ptr<DictionaryValue> schema(new DictionaryValue());
+ schema->SetString("type", "array");
+ schema->SetString("items.type", "string");
+ schema->SetInteger("minItems", 2);
+ schema->SetInteger("maxItems", 3);
+
+ scoped_ptr<ListValue> instance(new ListValue());
+ instance->Append(Value::CreateStringValue("x"));
+ instance->Append(Value::CreateStringValue("x"));
+
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+ instance->Append(Value::CreateStringValue("x"));
+ ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
+
+ instance->Append(Value::CreateStringValue("x"));
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kArrayMaxItems, "3"));
+ instance->Remove(1, NULL);
+ instance->Remove(1, NULL);
+ instance->Remove(1, NULL);
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kArrayMinItems, "2"));
+
+ instance->Remove(1, NULL);
+ instance->Append(Value::CreateIntegerValue(42));
+ ExpectNotValid(TEST_SOURCE, instance.get(), schema.get(), NULL, "1",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "string", "integer"));
+}
+
+void JSONSchemaValidatorTestBase::TestString() {
+ scoped_ptr<DictionaryValue> schema(new DictionaryValue());
+ schema->SetString("type", "string");
+ schema->SetInteger("minLength", 1);
+ schema->SetInteger("maxLength", 10);
+
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("x")).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("xxxxxxxxxx")).get(),
+ schema.get(), NULL);
+
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("")).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kStringMinLength, "1"));
+ ExpectNotValid(
+ TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("xxxxxxxxxxx")).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kStringMaxLength, "10"));
+
+}
+
+void JSONSchemaValidatorTestBase::TestNumber() {
+ scoped_ptr<DictionaryValue> schema(new DictionaryValue());
+ schema->SetString("type", "number");
+ schema->SetInteger("minimum", 1);
+ schema->SetInteger("maximum", 100);
+ schema->SetInteger("maxDecimal", 2);
+
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(1)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(50)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(100)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateRealValue(88.88)).get(),
+ schema.get(), NULL);
+
+ ExpectNotValid(
+ TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateRealValue(0.5)).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kNumberMinimum, "1"));
+ ExpectNotValid(
+ TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateRealValue(100.1)).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kNumberMaximum, "100"));
+}
+
+void JSONSchemaValidatorTestBase::TestTypeClassifier() {
+ EXPECT_EQ("boolean", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateBooleanValue(true)).get()));
+ EXPECT_EQ("boolean", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateBooleanValue(false)).get()));
+
+ // It doesn't matter whether the C++ type is 'integer' or 'real'. If the
+ // number is integral and within the representable range of integers in
+ // double, it's classified as 'integer'.
+ EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateIntegerValue(42)).get()));
+ EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateIntegerValue(0)).get()));
+ EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateRealValue(42)).get()));
+ EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(
+ Value::CreateRealValue(pow(2.0, DBL_MANT_DIG))).get()));
+ EXPECT_EQ("integer", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(
+ Value::CreateRealValue(pow(-2.0, DBL_MANT_DIG))).get()));
+
+ // "number" is only used for non-integral numbers, or numbers beyond what
+ // double can accurately represent.
+ EXPECT_EQ("number", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateRealValue(88.8)).get()));
+ EXPECT_EQ("number", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateRealValue(
+ pow(2.0, DBL_MANT_DIG) * 2)).get()));
+ EXPECT_EQ("number", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateRealValue(
+ pow(-2.0, DBL_MANT_DIG) * 2)).get()));
+
+ EXPECT_EQ("string", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateStringValue("foo")).get()));
+ EXPECT_EQ("array", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(new ListValue()).get()));
+ EXPECT_EQ("object", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(new DictionaryValue()).get()));
+ EXPECT_EQ("null", JSONSchemaValidator::GetJSONSchemaType(
+ scoped_ptr<Value>(Value::CreateNullValue()).get()));
+}
+
+void JSONSchemaValidatorTestBase::TestTypes() {
+ scoped_ptr<DictionaryValue> schema(new DictionaryValue());
+
+ // valid
+ schema->SetString("type", "object");
+ ExpectValid(TEST_SOURCE, scoped_ptr<Value>(new DictionaryValue()).get(),
+ schema.get(), NULL);
+
+ schema->SetString("type", "array");
+ ExpectValid(TEST_SOURCE, scoped_ptr<Value>(new ListValue()).get(),
+ schema.get(), NULL);
+
+ schema->SetString("type", "string");
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("foobar")).get(),
+ schema.get(), NULL);
+
+ schema->SetString("type", "number");
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateRealValue(88.8)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateRealValue(42)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(0)).get(),
+ schema.get(), NULL);
+
+ schema->SetString("type", "integer");
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateRealValue(42)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(0)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(
+ Value::CreateRealValue(pow(2.0, DBL_MANT_DIG))).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(
+ Value::CreateRealValue(pow(-2.0, DBL_MANT_DIG))).get(),
+ schema.get(), NULL);
+
+ schema->SetString("type", "boolean");
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateBooleanValue(false)).get(),
+ schema.get(), NULL);
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateBooleanValue(true)).get(),
+ schema.get(), NULL);
+
+ schema->SetString("type", "null");
+ ExpectValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateNullValue()).get(),
+ schema.get(), NULL);
+
+ // not valid
+ schema->SetString("type", "object");
+ ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(new ListValue()).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "object", "array"));
+
+ schema->SetString("type", "object");
+ ExpectNotValid(TEST_SOURCE, scoped_ptr<Value>(Value::CreateNullValue()).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "object", "null"));
+
+ schema->SetString("type", "array");
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "array", "integer"));
+
+ schema->SetString("type", "string");
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(42)).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "string", "integer"));
+
+ schema->SetString("type", "number");
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateStringValue("42")).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "number", "string"));
+
+ schema->SetString("type", "integer");
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateRealValue(88.8)).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "integer", "number"));
+
+ schema->SetString("type", "integer");
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateRealValue(88.8)).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "integer", "number"));
+
+ schema->SetString("type", "boolean");
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateIntegerValue(1)).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "boolean", "integer"));
+
+ schema->SetString("type", "null");
+ ExpectNotValid(TEST_SOURCE,
+ scoped_ptr<Value>(Value::CreateBooleanValue(false)).get(),
+ schema.get(), NULL, "",
+ JSONSchemaValidator::FormatErrorMessage(
+ JSONSchemaValidator::kInvalidType, "null", "boolean"));
+}
diff --git a/chrome/common/json_schema_validator_unittest_base.h b/chrome/common/json_schema_validator_unittest_base.h
new file mode 100644
index 0000000..8530a13
--- /dev/null
+++ b/chrome/common/json_schema_validator_unittest_base.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_JSON_SCHEMA_VALIDATOR_UNITTEST_BASE_H_
+#define CHROME_COMMON_JSON_SCHEMA_VALIDATOR_UNITTEST_BASE_H_
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+class DictionaryValue;
+class ListValue;
+class Value;
+
+// Base class for unit tests for JSONSchemaValidator. There is currently only
+// one implementation, JSONSchemaValidatorCPPTest.
+//
+// TODO(aa): Refactor chrome/test/data/json_schema_test.js into
+// JSONSchemaValidatorJSTest that inherits from this.
+class JSONSchemaValidatorTestBase : public testing::Test {
+ public:
+ enum ValidatorType {
+ CPP = 1,
+ JS = 2
+ };
+
+ explicit JSONSchemaValidatorTestBase(ValidatorType type);
+
+ void RunTests();
+
+ protected:
+ virtual void ExpectValid(const std::string& test_source,
+ Value* instance, DictionaryValue* schema,
+ ListValue* types) = 0;
+
+ virtual void ExpectNotValid(const std::string& test_source,
+ Value* instance, DictionaryValue* schema,
+ ListValue* types,
+ const std::string& expected_error_path,
+ const std::string& expected_error_message) = 0;
+
+ private:
+ void TestComplex();
+ void TestStringPattern();
+ void TestEnum();
+ void TestChoices();
+ void TestExtends();
+ void TestObject();
+ void TestTypeReference();
+ void TestArrayTuple();
+ void TestArrayNonTuple();
+ void TestString();
+ void TestNumber();
+ void TestTypeClassifier();
+ void TestTypes();
+
+ ValidatorType type_;
+};
+
+#endif // CHROME_COMMON_JSON_SCHEMA_VALIDATOR_UNITTEST_BASE_H_
diff --git a/chrome/common/metrics_helpers.cc b/chrome/common/metrics_helpers.cc
index e25355c..d5d8f78 100644
--- a/chrome/common/metrics_helpers.cc
+++ b/chrome/common/metrics_helpers.cc
@@ -16,7 +16,6 @@
#include "base/file_util.h"
#include "base/md5.h"
#include "base/perftimer.h"
-#include "base/scoped_ptr.h"
#include "base/string_number_conversions.h"
#include "base/sys_info.h"
#include "base/utf_string_conversions.h"
@@ -413,8 +412,7 @@ void MetricsLogBase::RecordHistogramDelta(
MetricsServiceBase::MetricsServiceBase()
: pending_log_(NULL),
compressed_log_(),
- current_log_(NULL),
- logged_samples_() {
+ current_log_(NULL) {
}
MetricsServiceBase::~MetricsServiceBase() {
@@ -467,20 +465,56 @@ bool MetricsServiceBase::Bzip2Compress(const std::string& input,
return true;
}
+void MetricsServiceBase::DiscardPendingLog() {
+ if (pending_log_) { // Shutdown might have deleted it!
+ delete pending_log_;
+ pending_log_ = NULL;
+ }
+ compressed_log_.clear();
+}
+
void MetricsServiceBase::RecordCurrentHistograms() {
DCHECK(current_log_);
+ TransmitAllHistograms(base::Histogram::kNoFlags, true);
+}
+
+void MetricsServiceBase::TransmitHistogramDelta(
+ const base::Histogram& histogram,
+ const base::Histogram::SampleSet& snapshot) {
+ current_log_->RecordHistogramDelta(histogram, snapshot);
+}
+void MetricsServiceBase::InconsistencyDetected(int problem) {
+ UMA_HISTOGRAM_ENUMERATION("Histogram.InconsistenciesBrowser",
+ problem, Histogram::NEVER_EXCEEDED_VALUE);
+}
+
+void MetricsServiceBase::UniqueInconsistencyDetected(int problem) {
+ UMA_HISTOGRAM_ENUMERATION("Histogram.InconsistenciesBrowserUnique",
+ problem, Histogram::NEVER_EXCEEDED_VALUE);
+}
+
+void MetricsServiceBase::SnapshotProblemResolved(int amount) {
+ UMA_HISTOGRAM_COUNTS("Histogram.InconsistentSnapshotBrowser",
+ std::abs(amount));
+}
+
+void HistogramSender::TransmitAllHistograms(Histogram::Flags flag_to_set,
+ bool send_only_uma) {
StatisticsRecorder::Histograms histograms;
StatisticsRecorder::GetHistograms(&histograms);
for (StatisticsRecorder::Histograms::const_iterator it = histograms.begin();
histograms.end() != it;
++it) {
- if ((*it)->flags() & Histogram::kUmaTargetedHistogramFlag)
- RecordHistogram(**it);
+ (*it)->SetFlags(flag_to_set);
+ if (send_only_uma &&
+ 0 == ((*it)->flags() & Histogram::kUmaTargetedHistogramFlag))
+ continue;
+ TransmitHistogram(**it);
}
}
-void MetricsServiceBase::RecordHistogram(const Histogram& histogram) {
+void HistogramSender::TransmitHistogram(const Histogram& histogram) {
// Get up-to-date snapshot of sample stats.
Histogram::SampleSet snapshot;
histogram.SnapshotSample(&snapshot);
@@ -489,21 +523,20 @@ void MetricsServiceBase::RecordHistogram(const Histogram& histogram) {
int corruption = histogram.FindCorruption(snapshot);
if (corruption) {
NOTREACHED();
+ InconsistencyDetected(corruption);
// Don't send corrupt data to metrics survices.
- UMA_HISTOGRAM_ENUMERATION("Histogram.InconsistenciesBrowser",
- corruption, Histogram::NEVER_EXCEEDED_VALUE);
- typedef std::map<std::string, int> ProblemMap;
- static ProblemMap* inconsistencies = new ProblemMap;
- int old_corruption = (*inconsistencies)[histogram_name];
+ if (NULL == inconsistencies_.get())
+ inconsistencies_.reset(new ProblemMap);
+ int old_corruption = (*inconsistencies_)[histogram_name];
if (old_corruption == (corruption | old_corruption))
return; // We've already seen this corruption for this histogram.
- (*inconsistencies)[histogram_name] |= corruption;
- UMA_HISTOGRAM_ENUMERATION("Histogram.InconsistenciesBrowserUnique",
- corruption, Histogram::NEVER_EXCEEDED_VALUE);
+ (*inconsistencies_)[histogram_name] |= corruption;
+ UniqueInconsistencyDetected(corruption);
return;
}
- // Find the already sent stats, or create an empty set.
+ // Find the already sent stats, or create an empty set. Remove from our
+ // snapshot anything that we've already sent.
LoggedSampleMap::iterator it = logged_samples_.find(histogram_name);
Histogram::SampleSet* already_logged;
if (logged_samples_.end() == it) {
@@ -512,23 +545,28 @@ void MetricsServiceBase::RecordHistogram(const Histogram& histogram) {
already_logged->Resize(histogram); // Complete initialization.
} else {
already_logged = &(it->second);
+ int64 discrepancy(already_logged->TotalCount() -
+ already_logged->redundant_count());
+ if (discrepancy) {
+ NOTREACHED(); // Already_logged has become corrupt.
+ int problem = static_cast<int>(discrepancy);
+ if (problem != discrepancy)
+ problem = INT_MAX;
+ SnapshotProblemResolved(problem);
+ // With no valid baseline, we'll act like we've sent everything in our
+ // snapshot.
+ already_logged->Subtract(*already_logged);
+ already_logged->Add(snapshot);
+ }
// Deduct any stats we've already logged from our snapshot.
snapshot.Subtract(*already_logged);
}
// Snapshot now contains only a delta to what we've already_logged.
-
- if (snapshot.TotalCount() > 0) {
- current_log_->RecordHistogramDelta(histogram, snapshot);
+ DCHECK_EQ(snapshot.TotalCount(), snapshot.redundant_count());
+ if (snapshot.redundant_count() > 0) {
+ TransmitHistogramDelta(histogram, snapshot);
// Add new data into our running total.
already_logged->Add(snapshot);
}
}
-
-void MetricsServiceBase::DiscardPendingLog() {
- if (pending_log_) { // Shutdown might have deleted it!
- delete pending_log_;
- pending_log_ = NULL;
- }
- compressed_log_.clear();
-}
diff --git a/chrome/common/metrics_helpers.h b/chrome/common/metrics_helpers.h
index b0bbec2..b261488 100644
--- a/chrome/common/metrics_helpers.h
+++ b/chrome/common/metrics_helpers.h
@@ -14,6 +14,7 @@
#include "base/basictypes.h"
#include "base/metrics/histogram.h"
+#include "base/scoped_ptr.h"
#include "base/time.h"
#include "chrome/common/page_transition_types.h"
@@ -173,11 +174,62 @@ class MetricsLogBase {
DISALLOW_COPY_AND_ASSIGN(MetricsLogBase);
};
+// HistogramSender handles the logistics of gathering up available histograms
+// for transmission (such as from renderer to browser, or from browser to UMA
+// upload). It has several pure virtual functions that are replaced in
+// derived classes to allow the exact lower level transmission mechanism,
+// or error report mechanism, to be replaced. Since histograms can sit in
+// memory for an extended period of time, and are vulnerable to memory
+// corruption, this class also validates as much rendundancy as it can before
+// calling for the marginal change (a.k.a., delta) in a histogram to be sent
+// onward.
+class HistogramSender {
+ protected:
+ HistogramSender() {}
+ virtual ~HistogramSender() {}
+
+ // Snapshot all histograms, and transmit the delta.
+ // The arguments allow a derived class to select only a subset for
+ // transmission, or to set a flag in each transmitted histogram.
+ void TransmitAllHistograms(base::Histogram::Flags flags_to_set,
+ bool send_only_uma);
+
+ // Send the histograms onward, as defined in a derived class.
+ // This is only called with a delta, listing samples that have not previously
+ // been transmitted.
+ virtual void TransmitHistogramDelta(
+ const base::Histogram& histogram,
+ const base::Histogram::SampleSet& snapshot) = 0;
+
+ // Record various errors found during attempts to send histograms.
+ virtual void InconsistencyDetected(int problem) = 0;
+ virtual void UniqueInconsistencyDetected(int problem) = 0;
+ virtual void SnapshotProblemResolved(int amount) = 0;
+
+ private:
+ // Maintain a map of histogram names to the sample stats we've sent.
+ typedef std::map<std::string, base::Histogram::SampleSet> LoggedSampleMap;
+ // List of histograms names, and their encontered corruptions.
+ typedef std::map<std::string, int> ProblemMap;
+
+ // Snapshot this histogram, and transmit the delta.
+ void TransmitHistogram(const base::Histogram& histogram);
+
+ // For histograms, record what we've already transmitted (as a sample for each
+ // histogram) so that we can send only the delta with the next log.
+ LoggedSampleMap logged_samples_;
+
+ // List of histograms found corrupt to be corrupt, and their problems.
+ scoped_ptr<ProblemMap> inconsistencies_;
+
+ DISALLOW_COPY_AND_ASSIGN(HistogramSender);
+};
+
// This class provides base functionality for logging metrics data.
// TODO(ananta)
// Factor out more common code from chrome and chrome frame metrics service
// into this class.
-class MetricsServiceBase {
+class MetricsServiceBase : public HistogramSender {
protected:
MetricsServiceBase();
virtual ~MetricsServiceBase();
@@ -199,9 +251,6 @@ class MetricsServiceBase {
// Called when we close a log.
void RecordCurrentHistograms();
- // Record a specific histogram .
- void RecordHistogram(const base::Histogram& histogram);
-
// A log that we are currently transmiting, or about to try to transmit.
MetricsLogBase* pending_log_;
@@ -213,12 +262,14 @@ class MetricsServiceBase {
// The log that we are still appending to.
MetricsLogBase* current_log_;
- // Maintain a map of histogram names to the sample stats we've sent.
- typedef std::map<std::string, base::Histogram::SampleSet> LoggedSampleMap;
-
- // For histograms, record what we've already logged (as a sample for each
- // histogram) so that we can send only the delta with the next log.
- LoggedSampleMap logged_samples_;
+ private:
+ // HistogramSender interface (override) methods.
+ virtual void TransmitHistogramDelta(
+ const base::Histogram& histogram,
+ const base::Histogram::SampleSet& snapshot);
+ virtual void InconsistencyDetected(int problem);
+ virtual void UniqueInconsistencyDetected(int problem);
+ virtual void SnapshotProblemResolved(int amount);
DISALLOW_COPY_AND_ASSIGN(MetricsServiceBase);
};
diff --git a/chrome/common/multi_process_lock.h b/chrome/common/multi_process_lock.h
new file mode 100644
index 0000000..24754f5
--- /dev/null
+++ b/chrome/common/multi_process_lock.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_MULTI_PROCESS_LOCK_H_
+#define CHROME_COMMON_MULTI_PROCESS_LOCK_H_
+#pragma once
+
+#include <sys/types.h>
+#include <string>
+
+// Platform abstraction for a lock that can be shared between processes.
+// The process that owns the lock will release it on exit even if
+// the exit is due to a crash. Locks are not recursive.
+class MultiProcessLock {
+ public:
+
+ // The length of a multi-process lock name is limited on Linux, so
+ // it is limited it on all platforms for consistency. This length does
+ // not include a terminator.
+ static const size_t MULTI_PROCESS_LOCK_NAME_MAX_LEN = 106;
+
+ // Factory method for creating a multi-process lock.
+ // |name| is the name of the lock. The name has special meaning on Windows
+ // where the prefix can determine the namespace of the lock.
+ // See http://msdn.microsoft.com/en-us/library/aa382954(v=VS.85).aspx for
+ // details.
+ static MultiProcessLock* Create(const std::string& name);
+
+ virtual ~MultiProcessLock() { }
+
+ // Try to grab ownership of the lock.
+ virtual bool TryLock() = 0;
+
+ // Release ownership of the lock.
+ virtual void Unlock() = 0;
+};
+
+#endif // CHROME_COMMON_MULTI_PROCESS_LOCK_H_
diff --git a/chrome/common/multi_process_lock_linux.cc b/chrome/common/multi_process_lock_linux.cc
new file mode 100644
index 0000000..c0c92c7
--- /dev/null
+++ b/chrome/common/multi_process_lock_linux.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/multi_process_lock.h"
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "base/eintr_wrapper.h"
+#include "base/logging.h"
+
+class MultiProcessLockLinux : public MultiProcessLock {
+ public:
+ explicit MultiProcessLockLinux(const std::string& name)
+ : name_(name), fd_(-1) { }
+
+ virtual ~MultiProcessLockLinux() {
+ if (fd_ != -1) {
+ Unlock();
+ }
+ }
+
+ virtual bool TryLock() {
+ if (fd_ != -1) {
+ DLOG(ERROR) << "MultiProcessLock is already locked - " << name_;
+ return true;
+ }
+
+ if (name_.length() > MULTI_PROCESS_LOCK_NAME_MAX_LEN) {
+ LOG(ERROR) << "Socket name too long - " << name_;
+ return false;
+ }
+
+ struct sockaddr_un address;
+
+ // +1 for terminator, +1 for 0 in position 0 that makes it an
+ // abstract named socket.
+ // If this assert fails it is because sockaddr_un.sun_path size has been
+ // redefined and MULTI_PROCESS_LOCK_NAME_MAX_LEN can change accordingly.
+ COMPILE_ASSERT(sizeof(address.sun_path)
+ == MULTI_PROCESS_LOCK_NAME_MAX_LEN + 2, sun_path_size_changed);
+
+ memset(&address, 0, sizeof(address));
+ int print_length = snprintf(&address.sun_path[1],
+ MULTI_PROCESS_LOCK_NAME_MAX_LEN + 1,
+ "%s", name_.c_str());
+
+ if (print_length < 0 ||
+ print_length > static_cast<int>(MULTI_PROCESS_LOCK_NAME_MAX_LEN)) {
+ PLOG(ERROR) << "Couldn't create sun_path - " << name_;
+ return false;
+ }
+
+ // Must set the first character of the path to something non-zero
+ // before we call SUN_LEN which depends on strcpy working.
+ address.sun_path[0] = '@';
+ size_t length = SUN_LEN(&address);
+
+ // Reset the first character of the path back to zero so that
+ // bind returns an abstract name socket.
+ address.sun_path[0] = 0;
+ address.sun_family = AF_LOCAL;
+
+ int socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (socket_fd < 0) {
+ PLOG(ERROR) << "Couldn't create socket - " << name_;
+ return false;
+ }
+
+ if (bind(socket_fd,
+ reinterpret_cast<sockaddr *>(&address),
+ length) == 0) {
+ fd_ = socket_fd;
+ return true;
+ } else {
+ PLOG(ERROR) << "Couldn't bind socket - "
+ << &(address.sun_path[1])
+ << " Length: " << length;
+ if (HANDLE_EINTR(close(socket_fd)) < 0) {
+ PLOG(ERROR) << "close";
+ }
+ return false;
+ }
+ }
+
+ virtual void Unlock() {
+ if (fd_ == -1) {
+ DLOG(ERROR) << "Over-unlocked MultiProcessLock - " << name_;
+ return;
+ }
+ if (HANDLE_EINTR(close(fd_)) < 0) {
+ PLOG(ERROR) << "close";
+ }
+ fd_ = -1;
+ }
+
+ private:
+ std::string name_;
+ int fd_;
+ DISALLOW_COPY_AND_ASSIGN(MultiProcessLockLinux);
+};
+
+MultiProcessLock* MultiProcessLock::Create(const std::string &name) {
+ return new MultiProcessLockLinux(name);
+}
diff --git a/chrome/common/multi_process_lock_mac.cc b/chrome/common/multi_process_lock_mac.cc
new file mode 100644
index 0000000..9a16d71
--- /dev/null
+++ b/chrome/common/multi_process_lock_mac.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/multi_process_lock.h"
+
+#include "base/logging.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/sys_string_conversions.h"
+
+class MultiProcessLockMac : public MultiProcessLock {
+ public:
+ explicit MultiProcessLockMac(const std::string& name) : name_(name) { }
+
+ virtual ~MultiProcessLockMac() {
+ if (port_ != NULL) {
+ Unlock();
+ }
+ }
+
+ virtual bool TryLock() {
+ if (port_ != NULL) {
+ DLOG(ERROR) << "MultiProcessLock is already locked - " << name_;
+ return true;
+ }
+
+ if (name_.length() > MULTI_PROCESS_LOCK_NAME_MAX_LEN) {
+ LOG(ERROR) << "Socket name too long - " << name_;
+ return false;
+ }
+
+ CFStringRef cf_name(base::SysUTF8ToCFStringRef(name_));
+ base::mac::ScopedCFTypeRef<CFStringRef> scoped_cf_name(cf_name);
+ port_.reset(CFMessagePortCreateLocal(NULL, cf_name, NULL, NULL, NULL));
+ return port_ != NULL;
+ }
+
+ virtual void Unlock() {
+ if (port_ == NULL) {
+ DLOG(ERROR) << "Over-unlocked MultiProcessLock - " << name_;
+ return;
+ }
+ port_.reset();
+ }
+
+ private:
+ std::string name_;
+ base::mac::ScopedCFTypeRef<CFMessagePortRef> port_;
+ DISALLOW_COPY_AND_ASSIGN(MultiProcessLockMac);
+};
+
+MultiProcessLock* MultiProcessLock::Create(const std::string &name) {
+ return new MultiProcessLockMac(name);
+}
diff --git a/chrome/common/multi_process_lock_unittest.cc b/chrome/common/multi_process_lock_unittest.cc
new file mode 100644
index 0000000..d408db7
--- /dev/null
+++ b/chrome/common/multi_process_lock_unittest.cc
@@ -0,0 +1,157 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "base/environment.h"
+#include "base/logging.h"
+#include "base/rand_util.h"
+#include "base/scoped_ptr.h"
+#include "base/stringprintf.h"
+#include "base/test/multiprocess_test.h"
+#include "base/time.h"
+#include "chrome/common/multi_process_lock.h"
+#include "testing/multiprocess_func_list.h"
+
+class MultiProcessLockTest : public base::MultiProcessTest {
+ public:
+ static const char kLockEnviromentVarName[];
+
+ class ScopedEnvironmentVariable {
+ public:
+ ScopedEnvironmentVariable(const std::string &name,
+ const std::string &value)
+ : name_(name), environment_(base::Environment::Create()) {
+ environment_->SetVar(name_.c_str(), value);
+ }
+ ~ScopedEnvironmentVariable() {
+ environment_->UnSetVar(name_.c_str());
+ }
+
+ private:
+ std::string name_;
+ scoped_ptr<base::Environment> environment_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedEnvironmentVariable);
+ };
+
+ std::string GenerateLockName();
+ void ExpectLockIsLocked(const std::string &name);
+ void ExpectLockIsUnlocked(const std::string &name);
+};
+
+const char MultiProcessLockTest::kLockEnviromentVarName[]
+ = "MULTI_PROCESS_TEST_LOCK_NAME";
+
+std::string MultiProcessLockTest::GenerateLockName() {
+ base::Time now = base::Time::NowFromSystemTime();
+ return base::StringPrintf("multi_process_test_lock %lf%lf",
+ now.ToDoubleT(), base::RandDouble());
+}
+
+void MultiProcessLockTest::ExpectLockIsLocked(const std::string &name) {
+ ScopedEnvironmentVariable var(kLockEnviromentVarName, name);
+ base::ProcessHandle handle = SpawnChild("MultiProcessLockTryFailMain", false);
+ ASSERT_TRUE(handle);
+ int exit_code = 0;
+ EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code));
+ EXPECT_EQ(exit_code, 0);
+}
+
+void MultiProcessLockTest::ExpectLockIsUnlocked(
+ const std::string &name) {
+ ScopedEnvironmentVariable var(kLockEnviromentVarName, name);
+ base::ProcessHandle handle = SpawnChild("MultiProcessLockTrySucceedMain",
+ false);
+ ASSERT_TRUE(handle);
+ int exit_code = 0;
+ EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code));
+ EXPECT_EQ(exit_code, 0);
+}
+
+TEST_F(MultiProcessLockTest, BasicCreationTest) {
+ // Test basic creation/destruction with no lock taken
+ std::string name = GenerateLockName();
+ scoped_ptr<MultiProcessLock> scoped(MultiProcessLock::Create(name));
+ ExpectLockIsUnlocked(name);
+ scoped.reset(NULL);
+}
+
+TEST_F(MultiProcessLockTest, LongNameTest) {
+ // Linux has a max path name of 108 characters.
+ // http://lxr.linux.no/linux+v2.6.36/include/linux/un.h
+ // This is enforced on all platforms.
+ LOG(INFO) << "Following error log due to long name is expected";
+ std::string name("This is a name that is longer than one hundred and eight "
+ "characters to make sure that we fail appropriately on linux when we "
+ "have a path that is to long for linux to handle");
+ scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
+ EXPECT_FALSE(test_lock->TryLock());
+}
+
+TEST_F(MultiProcessLockTest, SimpleLock) {
+ std::string name = GenerateLockName();
+ scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
+ EXPECT_TRUE(test_lock->TryLock());
+ ExpectLockIsLocked(name);
+ test_lock->Unlock();
+ ExpectLockIsUnlocked(name);
+}
+
+TEST_F(MultiProcessLockTest, RecursiveLock) {
+ std::string name = GenerateLockName();
+ scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
+ EXPECT_TRUE(test_lock->TryLock());
+ ExpectLockIsLocked(name);
+ LOG(INFO) << "Following error log "
+ << "'MultiProcessLock is already locked' is expected";
+ EXPECT_TRUE(test_lock->TryLock());
+ ExpectLockIsLocked(name);
+ test_lock->Unlock();
+ ExpectLockIsUnlocked(name);
+ LOG(INFO) << "Following error log "
+ << "'Over-unlocked MultiProcessLock' is expected";
+ test_lock->Unlock();
+ ExpectLockIsUnlocked(name);
+ test_lock.reset();
+}
+
+TEST_F(MultiProcessLockTest, LockScope) {
+ // Check to see that lock is released when it goes out of scope.
+ std::string name = GenerateLockName();
+ {
+ scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
+ EXPECT_TRUE(test_lock->TryLock());
+ ExpectLockIsLocked(name);
+ }
+ ExpectLockIsUnlocked(name);
+}
+
+MULTIPROCESS_TEST_MAIN(MultiProcessLockTryFailMain) {
+ std::string name;
+ scoped_ptr<base::Environment> environment(base::Environment::Create());
+ EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnviromentVarName,
+ &name));
+#if defined(OS_MACOSX)
+ // OS X sends out a log if a lock fails.
+ // Hopefully this will keep people from panicking about it when they
+ // are perusing the build logs.
+ LOG(INFO) << "Following error log "
+ << "\"CFMessagePort: bootstrap_register(): failed 1100 (0x44c) "
+ << "'Permission denied'\" is expected";
+#endif // defined(OS_MACOSX)
+ scoped_ptr<MultiProcessLock> test_lock(
+ MultiProcessLock::Create(name));
+ EXPECT_FALSE(test_lock->TryLock());
+ return 0;
+}
+
+MULTIPROCESS_TEST_MAIN(MultiProcessLockTrySucceedMain) {
+ std::string name;
+ scoped_ptr<base::Environment> environment(base::Environment::Create());
+ EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnviromentVarName,
+ &name));
+ scoped_ptr<MultiProcessLock> test_lock(
+ MultiProcessLock::Create(name));
+ EXPECT_TRUE(test_lock->TryLock());
+ return 0;
+}
diff --git a/chrome/common/multi_process_lock_win.cc b/chrome/common/multi_process_lock_win.cc
new file mode 100644
index 0000000..8bb525d
--- /dev/null
+++ b/chrome/common/multi_process_lock_win.cc
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/multi_process_lock.h"
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "base/win/scoped_handle.h"
+
+class MultiProcessLockWin : public MultiProcessLock {
+ public:
+ explicit MultiProcessLockWin(const std::string& name) : name_(name) { }
+
+ virtual ~MultiProcessLockWin() {
+ if (event_.Get() != NULL) {
+ Unlock();
+ }
+ }
+
+ virtual bool TryLock() {
+ if (event_.Get() != NULL) {
+ DLOG(ERROR) << "MultiProcessLock is already locked - " << name_;
+ return true;
+ }
+
+ if (name_.length() > MULTI_PROCESS_LOCK_NAME_MAX_LEN) {
+ LOG(ERROR) << "Socket name too long - " << name_;
+ return false;
+ }
+
+ string16 wname = UTF8ToUTF16(name_);
+ event_.Set(CreateEvent(NULL, FALSE, FALSE, wname.c_str()));
+ if (event_.Get() && GetLastError() != ERROR_ALREADY_EXISTS) {
+ return true;
+ } else {
+ event_.Set(NULL);
+ return false;
+ }
+ }
+
+ virtual void Unlock() {
+ if (event_.Get() == NULL) {
+ DLOG(ERROR) << "Over-unlocked MultiProcessLock - " << name_;
+ return;
+ }
+ event_.Set(NULL);
+ }
+
+ private:
+ std::string name_;
+ base::win::ScopedHandle event_;
+ DISALLOW_COPY_AND_ASSIGN(MultiProcessLockWin);
+};
+
+MultiProcessLock* MultiProcessLock::Create(const std::string &name) {
+ return new MultiProcessLockWin(name);
+}
diff --git a/chrome/common/net/gaia/gaia_auth_consumer.h b/chrome/common/net/gaia/gaia_auth_consumer.h
index 429ab7f..706d19e 100644
--- a/chrome/common/net/gaia/gaia_auth_consumer.h
+++ b/chrome/common/net/gaia/gaia_auth_consumer.h
@@ -11,7 +11,7 @@
class GoogleServiceAuthError;
// An interface that defines the callbacks for objects that
-// GaiaAuthenticator2 can return data to.
+// GaiaAuthFetcher can return data to.
class GaiaAuthConsumer {
public:
struct ClientLoginResult {
diff --git a/chrome/common/net/gaia/gaia_authenticator2.cc b/chrome/common/net/gaia/gaia_auth_fetcher.cc
index 21b8190..ec6e808 100644
--- a/chrome/common/net/gaia/gaia_authenticator2.cc
+++ b/chrome/common/net/gaia/gaia_auth_fetcher.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/common/net/gaia/gaia_authenticator2.h"
+#include "chrome/common/net/gaia/gaia_auth_fetcher.h"
#include <string>
#include <utility>
@@ -21,7 +21,7 @@
// TODO(chron): Add sourceless version of this formatter.
// static
-const char GaiaAuthenticator2::kClientLoginFormat[] =
+const char GaiaAuthFetcher::kClientLoginFormat[] =
"Email=%s&"
"Passwd=%s&"
"PersistentCookie=%s&"
@@ -29,7 +29,7 @@ const char GaiaAuthenticator2::kClientLoginFormat[] =
"source=%s&"
"service=%s";
// static
-const char GaiaAuthenticator2::kClientLoginCaptchaFormat[] =
+const char GaiaAuthFetcher::kClientLoginCaptchaFormat[] =
"Email=%s&"
"Passwd=%s&"
"PersistentCookie=%s&"
@@ -39,59 +39,59 @@ const char GaiaAuthenticator2::kClientLoginCaptchaFormat[] =
"logintoken=%s&"
"logincaptcha=%s";
// static
-const char GaiaAuthenticator2::kIssueAuthTokenFormat[] =
+const char GaiaAuthFetcher::kIssueAuthTokenFormat[] =
"SID=%s&"
"LSID=%s&"
"service=%s&"
"Session=%s";
// static
-const char GaiaAuthenticator2::kGetUserInfoFormat[] =
+const char GaiaAuthFetcher::kGetUserInfoFormat[] =
"LSID=%s";
// static
-const char GaiaAuthenticator2::kAccountDeletedError[] = "AccountDeleted";
+const char GaiaAuthFetcher::kAccountDeletedError[] = "AccountDeleted";
// static
-const char GaiaAuthenticator2::kAccountDisabledError[] = "AccountDisabled";
+const char GaiaAuthFetcher::kAccountDisabledError[] = "AccountDisabled";
// static
-const char GaiaAuthenticator2::kCaptchaError[] = "CaptchaRequired";
+const char GaiaAuthFetcher::kCaptchaError[] = "CaptchaRequired";
// static
-const char GaiaAuthenticator2::kServiceUnavailableError[] =
+const char GaiaAuthFetcher::kServiceUnavailableError[] =
"ServiceUnavailable";
// static
-const char GaiaAuthenticator2::kErrorParam[] = "Error";
+const char GaiaAuthFetcher::kErrorParam[] = "Error";
// static
-const char GaiaAuthenticator2::kErrorUrlParam[] = "Url";
+const char GaiaAuthFetcher::kErrorUrlParam[] = "Url";
// static
-const char GaiaAuthenticator2::kCaptchaUrlParam[] = "CaptchaUrl";
+const char GaiaAuthFetcher::kCaptchaUrlParam[] = "CaptchaUrl";
// static
-const char GaiaAuthenticator2::kCaptchaTokenParam[] = "CaptchaToken";
+const char GaiaAuthFetcher::kCaptchaTokenParam[] = "CaptchaToken";
// static
-const char GaiaAuthenticator2::kCaptchaUrlPrefix[] =
+const char GaiaAuthFetcher::kCaptchaUrlPrefix[] =
"http://www.google.com/accounts/";
// static
-const char GaiaAuthenticator2::kCookiePersistence[] = "true";
+const char GaiaAuthFetcher::kCookiePersistence[] = "true";
// static
// TODO(johnnyg): When hosted accounts are supported by sync,
// we can always use "HOSTED_OR_GOOGLE"
-const char GaiaAuthenticator2::kAccountTypeHostedOrGoogle[] =
+const char GaiaAuthFetcher::kAccountTypeHostedOrGoogle[] =
"HOSTED_OR_GOOGLE";
-const char GaiaAuthenticator2::kAccountTypeGoogle[] =
+const char GaiaAuthFetcher::kAccountTypeGoogle[] =
"GOOGLE";
// static
-const char GaiaAuthenticator2::kSecondFactor[] = "Info=InvalidSecondFactor";
+const char GaiaAuthFetcher::kSecondFactor[] = "Info=InvalidSecondFactor";
// TODO(chron): These urls are also in auth_response_handler.h.
// The URLs for different calls in the Google Accounts programmatic login API.
-const char GaiaAuthenticator2::kClientLoginUrl[] =
+const char GaiaAuthFetcher::kClientLoginUrl[] =
"https://www.google.com/accounts/ClientLogin";
-const char GaiaAuthenticator2::kIssueAuthTokenUrl[] =
+const char GaiaAuthFetcher::kIssueAuthTokenUrl[] =
"https://www.google.com/accounts/IssueAuthToken";
-const char GaiaAuthenticator2::kGetUserInfoUrl[] =
+const char GaiaAuthFetcher::kGetUserInfoUrl[] =
"https://www.google.com/accounts/GetUserInfo";
-GaiaAuthenticator2::GaiaAuthenticator2(GaiaAuthConsumer* consumer,
+GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer,
const std::string& source,
URLRequestContextGetter* getter)
: consumer_(consumer),
@@ -102,19 +102,19 @@ GaiaAuthenticator2::GaiaAuthenticator2(GaiaAuthConsumer* consumer,
get_user_info_gurl_(kGetUserInfoUrl),
fetch_pending_(false) {}
-GaiaAuthenticator2::~GaiaAuthenticator2() {}
+GaiaAuthFetcher::~GaiaAuthFetcher() {}
-bool GaiaAuthenticator2::HasPendingFetch() {
+bool GaiaAuthFetcher::HasPendingFetch() {
return fetch_pending_;
}
-void GaiaAuthenticator2::CancelRequest() {
+void GaiaAuthFetcher::CancelRequest() {
fetcher_.reset();
fetch_pending_ = false;
}
// static
-URLFetcher* GaiaAuthenticator2::CreateGaiaFetcher(
+URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher(
URLRequestContextGetter* getter,
const std::string& body,
const GURL& gaia_gurl,
@@ -132,7 +132,7 @@ URLFetcher* GaiaAuthenticator2::CreateGaiaFetcher(
}
// static
-std::string GaiaAuthenticator2::MakeClientLoginBody(
+std::string GaiaAuthFetcher::MakeClientLoginBody(
const std::string& username,
const std::string& password,
const std::string& source,
@@ -172,7 +172,7 @@ std::string GaiaAuthenticator2::MakeClientLoginBody(
}
// static
-std::string GaiaAuthenticator2::MakeIssueAuthTokenBody(
+std::string GaiaAuthFetcher::MakeIssueAuthTokenBody(
const std::string& sid,
const std::string& lsid,
const char* const service) {
@@ -192,14 +192,14 @@ std::string GaiaAuthenticator2::MakeIssueAuthTokenBody(
}
// static
-std::string GaiaAuthenticator2::MakeGetUserInfoBody(const std::string& lsid) {
+std::string GaiaAuthFetcher::MakeGetUserInfoBody(const std::string& lsid) {
std::string encoded_lsid = UrlEncodeString(lsid);
return base::StringPrintf(kGetUserInfoFormat, encoded_lsid.c_str());
}
// Helper method that extracts tokens from a successful reply.
// static
-void GaiaAuthenticator2::ParseClientLoginResponse(const std::string& data,
+void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data,
std::string* sid,
std::string* lsid,
std::string* token) {
@@ -222,11 +222,11 @@ void GaiaAuthenticator2::ParseClientLoginResponse(const std::string& data,
}
// static
-void GaiaAuthenticator2::ParseClientLoginFailure(const std::string& data,
- std::string* error,
- std::string* error_url,
- std::string* captcha_url,
- std::string* captcha_token) {
+void GaiaAuthFetcher::ParseClientLoginFailure(const std::string& data,
+ std::string* error,
+ std::string* error_url,
+ std::string* captcha_url,
+ std::string* captcha_token) {
using std::vector;
using std::pair;
using std::string;
@@ -234,7 +234,7 @@ void GaiaAuthenticator2::ParseClientLoginFailure(const std::string& data,
vector<pair<string, string> > tokens;
base::SplitStringIntoKeyValuePairs(data, '=', '\n', &tokens);
for (vector<pair<string, string> >::iterator i = tokens.begin();
- i != tokens.end(); ++i) {
+ i != tokens.end(); ++i) {
if (i->first == kErrorParam) {
error->assign(i->second);
} else if (i->first == kErrorUrlParam) {
@@ -247,7 +247,7 @@ void GaiaAuthenticator2::ParseClientLoginFailure(const std::string& data,
}
}
-void GaiaAuthenticator2::StartClientLogin(
+void GaiaAuthFetcher::StartClientLogin(
const std::string& username,
const std::string& password,
const char* const service,
@@ -277,9 +277,9 @@ void GaiaAuthenticator2::StartClientLogin(
fetcher_->Start();
}
-void GaiaAuthenticator2::StartIssueAuthToken(const std::string& sid,
- const std::string& lsid,
- const char* const service) {
+void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid,
+ const std::string& lsid,
+ const char* const service) {
DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
@@ -294,8 +294,8 @@ void GaiaAuthenticator2::StartIssueAuthToken(const std::string& sid,
fetcher_->Start();
}
-void GaiaAuthenticator2::StartGetUserInfo(const std::string& lsid,
- const std::string& info_key) {
+void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid,
+ const std::string& info_key) {
DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
VLOG(1) << "Starting GetUserInfo for lsid=" << lsid;
@@ -310,7 +310,7 @@ void GaiaAuthenticator2::StartGetUserInfo(const std::string& lsid,
}
// static
-GoogleServiceAuthError GaiaAuthenticator2::GenerateAuthError(
+GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError(
const std::string& data,
const URLRequestStatus& status) {
@@ -356,9 +356,9 @@ GoogleServiceAuthError GaiaAuthenticator2::GenerateAuthError(
NOTREACHED();
}
-void GaiaAuthenticator2::OnClientLoginFetched(const std::string& data,
- const URLRequestStatus& status,
- int response_code) {
+void GaiaAuthFetcher::OnClientLoginFetched(const std::string& data,
+ const URLRequestStatus& status,
+ int response_code) {
if (status.is_success() && response_code == RC_REQUEST_OK) {
VLOG(1) << "ClientLogin successful!";
@@ -373,7 +373,7 @@ void GaiaAuthenticator2::OnClientLoginFetched(const std::string& data,
}
}
-void GaiaAuthenticator2::OnIssueAuthTokenFetched(
+void GaiaAuthFetcher::OnIssueAuthTokenFetched(
const std::string& data,
const URLRequestStatus& status,
int response_code) {
@@ -387,7 +387,7 @@ void GaiaAuthenticator2::OnIssueAuthTokenFetched(
}
}
-void GaiaAuthenticator2::OnGetUserInfoFetched(
+void GaiaAuthFetcher::OnGetUserInfoFetched(
const std::string& data,
const URLRequestStatus& status,
int response_code) {
@@ -411,12 +411,12 @@ void GaiaAuthenticator2::OnGetUserInfoFetched(
}
}
-void GaiaAuthenticator2::OnURLFetchComplete(const URLFetcher* source,
- const GURL& url,
- const URLRequestStatus& status,
- int response_code,
- const ResponseCookies& cookies,
- const std::string& data) {
+void GaiaAuthFetcher::OnURLFetchComplete(const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data) {
fetch_pending_ = false;
if (url == client_login_gurl_) {
OnClientLoginFetched(data, status, response_code);
@@ -430,7 +430,7 @@ void GaiaAuthenticator2::OnURLFetchComplete(const URLFetcher* source,
}
// static
-bool GaiaAuthenticator2::IsSecondFactorSuccess(
+bool GaiaAuthFetcher::IsSecondFactorSuccess(
const std::string& alleged_error) {
return alleged_error.find(kSecondFactor) !=
std::string::npos;
diff --git a/chrome/common/net/gaia/gaia_authenticator2.h b/chrome/common/net/gaia/gaia_auth_fetcher.h
index fece7db..fd644a3 100644
--- a/chrome/common/net/gaia/gaia_authenticator2.h
+++ b/chrome/common/net/gaia/gaia_auth_fetcher.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_COMMON_NET_GAIA_GAIA_AUTHENTICATOR2_H_
-#define CHROME_COMMON_NET_GAIA_GAIA_AUTHENTICATOR2_H_
+#ifndef CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_H_
+#define CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_H_
#pragma once
#include <string>
@@ -22,12 +22,11 @@
// that you like.
//
// This class can handle one request at a time. To parallelize requests,
-// create multiple GaiaAuthenticator2's.
+// create multiple GaiaAuthFetcher's.
-class GaiaAuthenticator2Test;
+class GaiaAuthFetcherTest;
-// TODO(chron): Rename this to GaiaAuthFetcher or something.
-class GaiaAuthenticator2 : public URLFetcher::Delegate {
+class GaiaAuthFetcher : public URLFetcher::Delegate {
public:
enum HostedAccountsSetting {
HostedAccountsAllowed,
@@ -45,10 +44,10 @@ class GaiaAuthenticator2 : public URLFetcher::Delegate {
// This will later be hidden behind an auth service which caches
// tokens.
- GaiaAuthenticator2(GaiaAuthConsumer* consumer,
- const std::string& source,
- URLRequestContextGetter* getter);
- virtual ~GaiaAuthenticator2();
+ GaiaAuthFetcher(GaiaAuthConsumer* consumer,
+ const std::string& source,
+ URLRequestContextGetter* getter);
+ virtual ~GaiaAuthFetcher();
// GaiaAuthConsumer will be called on the original thread
// after results come back. This class is thread agnostic.
@@ -174,7 +173,7 @@ class GaiaAuthenticator2 : public URLFetcher::Delegate {
URLFetcher::Delegate* delegate);
- // These fields are common to GaiaAuthenticator2, same every request
+ // These fields are common to GaiaAuthFetcher, same every request
GaiaAuthConsumer* const consumer_;
URLRequestContextGetter* const getter_;
std::string source_;
@@ -189,16 +188,16 @@ class GaiaAuthenticator2 : public URLFetcher::Delegate {
std::string requested_info_key_; // Currently tracked for GetUserInfo only
bool fetch_pending_;
- friend class GaiaAuthenticator2Test;
- FRIEND_TEST_ALL_PREFIXES(GaiaAuthenticator2Test, CaptchaParse);
- FRIEND_TEST_ALL_PREFIXES(GaiaAuthenticator2Test, AccountDeletedError);
- FRIEND_TEST_ALL_PREFIXES(GaiaAuthenticator2Test, AccountDisabledError);
- FRIEND_TEST_ALL_PREFIXES(GaiaAuthenticator2Test, ServiceUnavailableError);
- FRIEND_TEST_ALL_PREFIXES(GaiaAuthenticator2Test, CheckNormalErrorCode);
- FRIEND_TEST_ALL_PREFIXES(GaiaAuthenticator2Test, CheckTwoFactorResponse);
- FRIEND_TEST_ALL_PREFIXES(GaiaAuthenticator2Test, LoginNetFailure);
+ friend class GaiaAuthFetcherTest;
+ FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CaptchaParse);
+ FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDeletedError);
+ FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDisabledError);
+ FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ServiceUnavailableError);
+ FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckNormalErrorCode);
+ FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckTwoFactorResponse);
+ FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, LoginNetFailure);
- DISALLOW_COPY_AND_ASSIGN(GaiaAuthenticator2);
+ DISALLOW_COPY_AND_ASSIGN(GaiaAuthFetcher);
};
-#endif // CHROME_COMMON_NET_GAIA_GAIA_AUTHENTICATOR2_H_
+#endif // CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_H_
diff --git a/chrome/common/net/gaia/gaia_authenticator2_unittest.cc b/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc
index 6ef0a51..47df6b7 100644
--- a/chrome/common/net/gaia/gaia_authenticator2_unittest.cc
+++ b/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// A complete set of unit tests for GaiaAuthenticator2.
+// A complete set of unit tests for GaiaAuthFetcher.
// Originally ported from GoogleAuthenticator tests.
#include <string>
@@ -10,8 +10,8 @@
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/common/net/gaia/gaia_auth_consumer.h"
-#include "chrome/common/net/gaia/gaia_authenticator2.h"
-#include "chrome/common/net/gaia/gaia_authenticator2_unittest.h"
+#include "chrome/common/net/gaia/gaia_auth_fetcher.h"
+#include "chrome/common/net/gaia/gaia_auth_fetcher_unittest.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
#include "chrome/common/net/http_return.h"
#include "chrome/common/net/test_url_fetcher_factory.h"
@@ -25,11 +25,11 @@
using ::testing::_;
-class GaiaAuthenticator2Test : public testing::Test {
+class GaiaAuthFetcherTest : public testing::Test {
public:
- GaiaAuthenticator2Test()
- : client_login_source_(GaiaAuthenticator2::kClientLoginUrl),
- issue_auth_token_source_(GaiaAuthenticator2::kIssueAuthTokenUrl) {}
+ GaiaAuthFetcherTest()
+ : client_login_source_(GaiaAuthFetcher::kClientLoginUrl),
+ issue_auth_token_source_(GaiaAuthFetcher::kIssueAuthTokenUrl) {}
void RunParsingTest(const std::string& data,
const std::string& sid,
@@ -39,7 +39,7 @@ class GaiaAuthenticator2Test : public testing::Test {
std::string out_lsid;
std::string out_token;
- GaiaAuthenticator2::ParseClientLoginResponse(data,
+ GaiaAuthFetcher::ParseClientLoginResponse(data,
&out_sid,
&out_lsid,
&out_token);
@@ -58,7 +58,7 @@ class GaiaAuthenticator2Test : public testing::Test {
std::string out_captcha_url;
std::string out_captcha_token;
- GaiaAuthenticator2::ParseClientLoginFailure(data,
+ GaiaAuthFetcher::ParseClientLoginFailure(data,
&out_error,
&out_error_url,
&out_captcha_url,
@@ -89,7 +89,7 @@ class MockGaiaConsumer : public GaiaAuthConsumer {
const GoogleServiceAuthError& error));
};
-TEST_F(GaiaAuthenticator2Test, ErrorComparator) {
+TEST_F(GaiaAuthFetcherTest, ErrorComparator) {
GoogleServiceAuthError expected_error =
GoogleServiceAuthError::FromConnectionError(-101);
@@ -111,7 +111,7 @@ TEST_F(GaiaAuthenticator2Test, ErrorComparator) {
EXPECT_TRUE(expected_error == matching_error);
}
-TEST_F(GaiaAuthenticator2Test, LoginNetFailure) {
+TEST_F(GaiaAuthFetcherTest, LoginNetFailure) {
int error_no = net::ERR_CONNECTION_RESET;
URLRequestStatus status(URLRequestStatus::FAILED, error_no);
@@ -122,7 +122,7 @@ TEST_F(GaiaAuthenticator2Test, LoginNetFailure) {
EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
.Times(1);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.OnURLFetchComplete(NULL,
@@ -133,7 +133,7 @@ TEST_F(GaiaAuthenticator2Test, LoginNetFailure) {
std::string());
}
-TEST_F(GaiaAuthenticator2Test, TokenNetFailure) {
+TEST_F(GaiaAuthFetcherTest, TokenNetFailure) {
int error_no = net::ERR_CONNECTION_RESET;
URLRequestStatus status(URLRequestStatus::FAILED, error_no);
@@ -144,7 +144,7 @@ TEST_F(GaiaAuthenticator2Test, TokenNetFailure) {
EXPECT_CALL(consumer, OnIssueAuthTokenFailure(_, expected_error))
.Times(1);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.OnURLFetchComplete(NULL,
@@ -156,7 +156,7 @@ TEST_F(GaiaAuthenticator2Test, TokenNetFailure) {
}
-TEST_F(GaiaAuthenticator2Test, LoginDenied) {
+TEST_F(GaiaAuthFetcherTest, LoginDenied) {
std::string data("Error: NO!");
URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
@@ -167,7 +167,7 @@ TEST_F(GaiaAuthenticator2Test, LoginDenied) {
EXPECT_CALL(consumer, OnClientLoginFailure(expected_error))
.Times(1);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.OnURLFetchComplete(NULL,
client_login_source_,
@@ -177,7 +177,7 @@ TEST_F(GaiaAuthenticator2Test, LoginDenied) {
data);
}
-TEST_F(GaiaAuthenticator2Test, ParseRequest) {
+TEST_F(GaiaAuthFetcherTest, ParseRequest) {
RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth\n", "sid", "lsid", "auth");
RunParsingTest("LSID=lsid\nSID=sid\nAuth=auth\n", "sid", "lsid", "auth");
RunParsingTest("SID=sid\nLSID=lsid\nAuth=auth", "sid", "lsid", "auth");
@@ -187,7 +187,7 @@ TEST_F(GaiaAuthenticator2Test, ParseRequest) {
RunParsingTest("SID=sid", "sid", "", "");
}
-TEST_F(GaiaAuthenticator2Test, ParseErrorRequest) {
+TEST_F(GaiaAuthFetcherTest, ParseErrorRequest) {
RunErrorParsingTest("Url=U\n"
"Error=E\n"
"CaptchaToken=T\n"
@@ -203,7 +203,7 @@ TEST_F(GaiaAuthenticator2Test, ParseErrorRequest) {
}
-TEST_F(GaiaAuthenticator2Test, OnlineLogin) {
+TEST_F(GaiaAuthFetcherTest, OnlineLogin) {
std::string data("SID=sid\nLSID=lsid\nAuth=auth\n");
GaiaAuthConsumer::ClientLoginResult result;
@@ -216,7 +216,7 @@ TEST_F(GaiaAuthenticator2Test, OnlineLogin) {
EXPECT_CALL(consumer, OnClientLoginSuccess(result))
.Times(1);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
auth.OnURLFetchComplete(NULL,
@@ -227,12 +227,12 @@ TEST_F(GaiaAuthenticator2Test, OnlineLogin) {
data);
}
-TEST_F(GaiaAuthenticator2Test, WorkingIssueAuthToken) {
+TEST_F(GaiaAuthFetcherTest, WorkingIssueAuthToken) {
MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnIssueAuthTokenSuccess(_, "token"))
.Times(1);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
auth.OnURLFetchComplete(NULL,
@@ -243,21 +243,21 @@ TEST_F(GaiaAuthenticator2Test, WorkingIssueAuthToken) {
"token");
}
-TEST_F(GaiaAuthenticator2Test, CheckTwoFactorResponse) {
+TEST_F(GaiaAuthFetcherTest, CheckTwoFactorResponse) {
std::string response =
base::StringPrintf("Error=BadAuthentication\n%s\n",
- GaiaAuthenticator2::kSecondFactor);
- EXPECT_TRUE(GaiaAuthenticator2::IsSecondFactorSuccess(response));
+ GaiaAuthFetcher::kSecondFactor);
+ EXPECT_TRUE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
}
-TEST_F(GaiaAuthenticator2Test, CheckNormalErrorCode) {
+TEST_F(GaiaAuthFetcherTest, CheckNormalErrorCode) {
std::string response = "Error=BadAuthentication\n";
- EXPECT_FALSE(GaiaAuthenticator2::IsSecondFactorSuccess(response));
+ EXPECT_FALSE(GaiaAuthFetcher::IsSecondFactorSuccess(response));
}
-TEST_F(GaiaAuthenticator2Test, TwoFactorLogin) {
+TEST_F(GaiaAuthFetcherTest, TwoFactorLogin) {
std::string response = base::StringPrintf("Error=BadAuthentication\n%s\n",
- GaiaAuthenticator2::kSecondFactor);
+ GaiaAuthFetcher::kSecondFactor);
GoogleServiceAuthError error =
GoogleServiceAuthError(GoogleServiceAuthError::TWO_FACTOR);
@@ -266,7 +266,7 @@ TEST_F(GaiaAuthenticator2Test, TwoFactorLogin) {
EXPECT_CALL(consumer, OnClientLoginFailure(error))
.Times(1);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
auth.OnURLFetchComplete(NULL,
@@ -277,14 +277,14 @@ TEST_F(GaiaAuthenticator2Test, TwoFactorLogin) {
response);
}
-TEST_F(GaiaAuthenticator2Test, CaptchaParse) {
+TEST_F(GaiaAuthFetcherTest, CaptchaParse) {
URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
std::string data = "Url=http://www.google.com/login/captcha\n"
"Error=CaptchaRequired\n"
"CaptchaToken=CCTOKEN\n"
"CaptchaUrl=Captcha?ctoken=CCTOKEN\n";
GoogleServiceAuthError error =
- GaiaAuthenticator2::GenerateAuthError(data, status);
+ GaiaAuthFetcher::GenerateAuthError(data, status);
std::string token = "CCTOKEN";
GURL image_url("http://www.google.com/accounts/Captcha?ctoken=CCTOKEN");
@@ -296,31 +296,31 @@ TEST_F(GaiaAuthenticator2Test, CaptchaParse) {
EXPECT_EQ(error.captcha().unlock_url, unlock_url);
}
-TEST_F(GaiaAuthenticator2Test, AccountDeletedError) {
+TEST_F(GaiaAuthFetcherTest, AccountDeletedError) {
URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
std::string data = "Error=AccountDeleted\n";
GoogleServiceAuthError error =
- GaiaAuthenticator2::GenerateAuthError(data, status);
+ GaiaAuthFetcher::GenerateAuthError(data, status);
EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DELETED);
}
-TEST_F(GaiaAuthenticator2Test, AccountDisabledError) {
+TEST_F(GaiaAuthFetcherTest, AccountDisabledError) {
URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
std::string data = "Error=AccountDisabled\n";
GoogleServiceAuthError error =
- GaiaAuthenticator2::GenerateAuthError(data, status);
+ GaiaAuthFetcher::GenerateAuthError(data, status);
EXPECT_EQ(error.state(), GoogleServiceAuthError::ACCOUNT_DISABLED);
}
-TEST_F(GaiaAuthenticator2Test,ServiceUnavailableError) {
+TEST_F(GaiaAuthFetcherTest,ServiceUnavailableError) {
URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
std::string data = "Error=ServiceUnavailable\n";
GoogleServiceAuthError error =
- GaiaAuthenticator2::GenerateAuthError(data, status);
+ GaiaAuthFetcher::GenerateAuthError(data, status);
EXPECT_EQ(error.state(), GoogleServiceAuthError::SERVICE_UNAVAILABLE);
}
-TEST_F(GaiaAuthenticator2Test, FullLogin) {
+TEST_F(GaiaAuthFetcherTest, FullLogin) {
MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnClientLoginSuccess(_))
.Times(1);
@@ -330,19 +330,19 @@ TEST_F(GaiaAuthenticator2Test, FullLogin) {
MockFactory<MockFetcher> factory;
URLFetcher::set_factory(&factory);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.StartClientLogin("username",
"password",
"service",
std::string(),
std::string(),
- GaiaAuthenticator2::HostedAccountsAllowed);
+ GaiaAuthFetcher::HostedAccountsAllowed);
URLFetcher::set_factory(NULL);
}
-TEST_F(GaiaAuthenticator2Test, FullLoginFailure) {
+TEST_F(GaiaAuthFetcherTest, FullLoginFailure) {
MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnClientLoginFailure(_))
.Times(1);
@@ -353,19 +353,19 @@ TEST_F(GaiaAuthenticator2Test, FullLoginFailure) {
URLFetcher::set_factory(&factory);
factory.set_success(false);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.StartClientLogin("username",
"password",
"service",
std::string(),
std::string(),
- GaiaAuthenticator2::HostedAccountsAllowed);
+ GaiaAuthFetcher::HostedAccountsAllowed);
URLFetcher::set_factory(NULL);
}
-TEST_F(GaiaAuthenticator2Test, ClientFetchPending) {
+TEST_F(GaiaAuthFetcherTest, ClientFetchPending) {
MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnClientLoginSuccess(_))
.Times(1);
@@ -374,14 +374,14 @@ TEST_F(GaiaAuthenticator2Test, ClientFetchPending) {
TestURLFetcherFactory factory;
URLFetcher::set_factory(&factory);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.StartClientLogin("username",
"password",
"service",
std::string(),
std::string(),
- GaiaAuthenticator2::HostedAccountsAllowed);
+ GaiaAuthFetcher::HostedAccountsAllowed);
URLFetcher::set_factory(NULL);
EXPECT_TRUE(auth.HasPendingFetch());
@@ -394,7 +394,7 @@ TEST_F(GaiaAuthenticator2Test, ClientFetchPending) {
EXPECT_FALSE(auth.HasPendingFetch());
}
-TEST_F(GaiaAuthenticator2Test, FullTokenSuccess) {
+TEST_F(GaiaAuthFetcherTest, FullTokenSuccess) {
MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnIssueAuthTokenSuccess("service", "token"))
.Times(1);
@@ -403,7 +403,7 @@ TEST_F(GaiaAuthenticator2Test, FullTokenSuccess) {
TestURLFetcherFactory factory;
URLFetcher::set_factory(&factory);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.StartIssueAuthToken("sid", "lsid", "service");
@@ -418,7 +418,7 @@ TEST_F(GaiaAuthenticator2Test, FullTokenSuccess) {
EXPECT_FALSE(auth.HasPendingFetch());
}
-TEST_F(GaiaAuthenticator2Test, FullTokenFailure) {
+TEST_F(GaiaAuthFetcherTest, FullTokenFailure) {
MockGaiaConsumer consumer;
EXPECT_CALL(consumer, OnIssueAuthTokenFailure("service", _))
.Times(1);
@@ -427,7 +427,7 @@ TEST_F(GaiaAuthenticator2Test, FullTokenFailure) {
TestURLFetcherFactory factory;
URLFetcher::set_factory(&factory);
- GaiaAuthenticator2 auth(&consumer, std::string(),
+ GaiaAuthFetcher auth(&consumer, std::string(),
profile_.GetRequestContext());
auth.StartIssueAuthToken("sid", "lsid", "service");
diff --git a/chrome/common/net/gaia/gaia_authenticator2_unittest.h b/chrome/common/net/gaia/gaia_auth_fetcher_unittest.h
index 3c6f22c..4676a26 100644
--- a/chrome/common/net/gaia/gaia_authenticator2_unittest.h
+++ b/chrome/common/net/gaia/gaia_auth_fetcher_unittest.h
@@ -3,15 +3,15 @@
// found in the LICENSE file.
//
// A collection of classes that are useful when testing things that use a
-// GaiaAuthenticator2.
+// GaiaAuthFetcher.
-#ifndef CHROME_COMMON_NET_GAIA_GAIA_AUTHENTICATOR2_UNITTEST_H_
-#define CHROME_COMMON_NET_GAIA_GAIA_AUTHENTICATOR2_UNITTEST_H_
+#ifndef CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_UNITTEST_H_
+#define CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_UNITTEST_H_
#pragma once
#include <string>
-#include "chrome/common/net/gaia/gaia_authenticator2.h"
+#include "chrome/common/net/gaia/gaia_auth_fetcher.h"
#include "chrome/common/net/url_fetcher.h"
#include "chrome/common/net/http_return.h"
#include "net/url_request/url_request_status.h"
@@ -81,4 +81,4 @@ class MockFactory : public URLFetcher::Factory {
DISALLOW_COPY_AND_ASSIGN(MockFactory);
};
-#endif // CHROME_COMMON_NET_GAIA_GAIA_AUTHENTICATOR2_UNITTEST_H_
+#endif // CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_UNITTEST_H_
diff --git a/chrome/common/net/test_url_fetcher_factory.cc b/chrome/common/net/test_url_fetcher_factory.cc
index 635319f..48fb314 100644
--- a/chrome/common/net/test_url_fetcher_factory.cc
+++ b/chrome/common/net/test_url_fetcher_factory.cc
@@ -3,6 +3,10 @@
// found in the LICENSE file.
#include "chrome/common/net/test_url_fetcher_factory.h"
+#include <string>
+
+#include "base/message_loop.h"
+#include "net/url_request/url_request_status.h"
TestURLFetcher::TestURLFetcher(int id,
const GURL& url,
@@ -33,3 +37,76 @@ void TestURLFetcherFactory::RemoveFetcherFromMap(int id) {
DCHECK(i != fetchers_.end());
fetchers_.erase(i);
}
+
+// This class is used by the FakeURLFetcherFactory below.
+class FakeURLFetcher : public URLFetcher {
+ public:
+ // Normal URL fetcher constructor but also takes in a pre-baked response.
+ FakeURLFetcher(const GURL& url, RequestType request_type, Delegate* d,
+ const std::string& response_data, bool success)
+ : URLFetcher(url, request_type, d),
+ url_(url),
+ response_data_(response_data),
+ success_(success),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
+ }
+
+ // Start the request. This will call the given delegate asynchronously
+ // with the pre-baked response as parameter.
+ virtual void Start() {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(&FakeURLFetcher::RunDelegate));
+ }
+
+ private:
+ virtual ~FakeURLFetcher() {
+ }
+
+ // This is the method which actually calls the delegate that is passed in the
+ // constructor.
+ void RunDelegate() {
+ URLRequestStatus status;
+ status.set_status(success_ ? URLRequestStatus::SUCCESS :
+ URLRequestStatus::FAILED);
+ delegate()->OnURLFetchComplete(this, url_, status, success_ ? 200 : 500,
+ ResponseCookies(), response_data_);
+ }
+
+ // Pre-baked response data and flag which indicates whether the request should
+ // be successful or not.
+ GURL url_;
+ std::string response_data_;
+ bool success_;
+
+ // Method factory used to run the delegate.
+ ScopedRunnableMethodFactory<FakeURLFetcher> method_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeURLFetcher);
+};
+
+URLFetcher* FakeURLFetcherFactory::CreateURLFetcher(
+ int id,
+ const GURL& url,
+ URLFetcher::RequestType request_type,
+ URLFetcher::Delegate* d) {
+ FakeResponseMap::const_iterator it = fake_responses_.find(url);
+ if (it == fake_responses_.end()) {
+ // If we don't have a baked response for that URL we return NULL.
+ DLOG(ERROR) << "No baked response for URL: " << url.spec();
+ return NULL;
+ }
+ return new FakeURLFetcher(url, request_type, d,
+ it->second.first, it->second.second);
+}
+
+void FakeURLFetcherFactory::SetFakeResponse(const std::string& url,
+ const std::string& response_data,
+ bool success) {
+ // Overwrite existing URL if it already exists.
+ fake_responses_[GURL(url)] = std::make_pair(response_data, success);
+}
+
+void FakeURLFetcherFactory::ClearFakeReponses() {
+ fake_responses_.clear();
+}
diff --git a/chrome/common/net/test_url_fetcher_factory.h b/chrome/common/net/test_url_fetcher_factory.h
index 3afa19e..73f4b46 100644
--- a/chrome/common/net/test_url_fetcher_factory.h
+++ b/chrome/common/net/test_url_fetcher_factory.h
@@ -8,6 +8,7 @@
#include <map>
#include <string>
+#include <utility>
#include "chrome/common/net/url_fetcher.h"
#include "googleurl/src/gurl.h"
@@ -35,7 +36,10 @@
// ...
// // Reset factory.
// URLFetcher::set_factory(NULL);
-
+//
+// Note: if you don't know when your request objects will be created you
+// might want to use the FakeUrlFetcher and FakeUrlFetcherFactory classes
+// below.
class TestURLFetcher : public URLFetcher {
public:
@@ -89,4 +93,66 @@ class TestURLFetcherFactory : public URLFetcher::Factory {
DISALLOW_COPY_AND_ASSIGN(TestURLFetcherFactory);
};
+// The FakeUrlFetcher and FakeUrlFetcherFactory classes are similar to the
+// ones above but don't require you to know when exactly the URLFetcher objects
+// will be created.
+//
+// These classes let you set pre-baked HTTP responses for particular URLs.
+// E.g., if the user requests http://a.com/ then respond with an HTTP/500.
+//
+// We assume that the thread that is calling Start() on the URLFetcher object
+// has a message loop running.
+//
+// This class is not thread-safe. You should not call SetFakeResponse or
+// ClearFakeResponse at the same time you call CreateURLFetcher. However, it is
+// OK to start URLFetcher objects while setting or clearning fake responses
+// since already created URLFetcher objects will not be affected by any changes
+// made to the fake responses (once a URLFetcher object is created you cannot
+// change its fake response).
+//
+// Example usage:
+// FakeURLFetcherFactory factory;
+// URLFetcher::set_factory(&factory);
+//
+// // You know that class SomeService will request url http://a.com/ and you
+// // want to test the service class by returning an error.
+// factory.SetFakeResponse("http://a.com/", "", false);
+// // But if the service requests http://b.com/asdf you want to respond with
+// // a simple html page and an HTTP/200 code.
+// factory.SetFakeResponse("http://b.com/asdf",
+// "<html><body>hello world</body></html>",
+// true);
+//
+// SomeService service;
+// service.Run(); // Will eventually request these two URLs.
+
+class FakeURLFetcherFactory : public URLFetcher::Factory {
+ public:
+ FakeURLFetcherFactory() {}
+
+ // If no fake response is set for the given URL this method will return NULL.
+ // Otherwise, it will return a URLFetcher object which will respond with the
+ // pre-baked response that the client has set by calling SetFakeResponse().
+ virtual URLFetcher* CreateURLFetcher(int id,
+ const GURL& url,
+ URLFetcher::RequestType request_type,
+ URLFetcher::Delegate* d);
+
+ // Sets the fake response for a given URL. If success is true we will serve
+ // an HTTP/200 and an HTTP/500 otherwise. The |response_data| may be empty.
+ void SetFakeResponse(const std::string& url,
+ const std::string& response_data,
+ bool success);
+
+ // Clear all the fake responses that were previously set via
+ // SetFakeResponse().
+ void ClearFakeReponses();
+
+ private:
+ typedef std::map<GURL, std::pair<std::string, bool> > FakeResponseMap;
+ FakeResponseMap fake_responses_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeURLFetcherFactory);
+};
+
#endif // CHROME_COMMON_NET_TEST_URL_FETCHER_FACTORY_H_
diff --git a/chrome/common/net/url_fetcher_unittest.cc b/chrome/common/net/url_fetcher_unittest.cc
index 466d8e6..65fb3c5 100644
--- a/chrome/common/net/url_fetcher_unittest.cc
+++ b/chrome/common/net/url_fetcher_unittest.cc
@@ -15,7 +15,7 @@
#include "net/test/test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if defined(OS_LINUX)
+#if defined(USE_NSS)
#include "net/ocsp/nss_ocsp.h"
#endif
@@ -79,13 +79,13 @@ class URLFetcherTest : public testing::Test, public URLFetcher::Delegate {
// Ensure that any plugin operations done by other tests are cleaned up.
ChromePluginLib::UnloadAllPlugins();
-#if defined(OS_LINUX)
+#if defined(USE_NSS)
net::EnsureOCSPInit();
#endif
}
virtual void TearDown() {
-#if defined(OS_LINUX)
+#if defined(USE_NSS)
net::ShutdownOCSP();
#endif
}
diff --git a/chrome/common/notification_service.h b/chrome/common/notification_service.h
index c20b98d..83c5ec1 100644
--- a/chrome/common/notification_service.h
+++ b/chrome/common/notification_service.h
@@ -67,8 +67,8 @@ class NotificationService {
// Registers a NotificationObserver to be called whenever a matching
// notification is posted. Observer is a pointer to an object subclassing
// NotificationObserver to be notified when an event matching the other two
- // parameters is posted to this service. Type is the type of events to
- // be notified about (or NOTIFY_ALL to receive events of all types).
+ // parameters is posted to this service. Type is the type of events to be
+ // notified about (or NotificationType::ALL to receive events of all types).
// Source is a NotificationSource object (created using
// "Source<classname>(pointer)"), if this observer only wants to
// receive events from that object, or NotificationService::AllSources()
diff --git a/chrome/common/page_type.h b/chrome/common/page_type.h
new file mode 100644
index 0000000..2a2bd1a
--- /dev/null
+++ b/chrome/common/page_type.h
@@ -0,0 +1,17 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_PAGE_TYPE_H_
+#define CHROME_COMMON_PAGE_TYPE_H_
+#pragma once
+
+// The type of the page an entry corresponds to. Used by chrome_frame and the
+// automation layer to detect the state of a TabContents.
+enum PageType {
+ NORMAL_PAGE = 0,
+ ERROR_PAGE,
+ INTERSTITIAL_PAGE
+};
+
+#endif // CHROME_COMMON_PAGE_TYPE_H_
diff --git a/chrome/common/pepper_plugin_registry.cc b/chrome/common/pepper_plugin_registry.cc
index 92fae2e..f812afd 100644
--- a/chrome/common/pepper_plugin_registry.cc
+++ b/chrome/common/pepper_plugin_registry.cc
@@ -21,7 +21,9 @@ const char* PepperPluginRegistry::kPDFPluginExtension = "pdf";
const char* PepperPluginRegistry::kPDFPluginDescription =
"Portable Document Format";
-PepperPluginInfo::PepperPluginInfo() : is_internal(false) {
+PepperPluginInfo::PepperPluginInfo()
+ : is_internal(false),
+ is_out_of_process(false) {
}
PepperPluginInfo::~PepperPluginInfo() {}
@@ -52,7 +54,7 @@ void PepperPluginRegistry::PreloadModules() {
std::vector<PepperPluginInfo> plugins;
GetList(&plugins);
for (size_t i = 0; i < plugins.size(); ++i) {
- if (!plugins[i].is_internal) {
+ if (!plugins[i].is_internal && !plugins[i].is_out_of_process) {
base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path);
LOG_IF(WARNING, !library) << "Unable to load plugin "
<< plugins[i].path.value();
@@ -69,6 +71,9 @@ void PepperPluginRegistry::GetPluginInfoFromSwitch(
if (value.empty())
return;
+ bool out_of_process =
+ CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess);
+
// FORMAT:
// command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
// plugin-entry = <file-path> + ["#" + <name> + ["#" + <description>]] +
@@ -88,6 +93,7 @@ void PepperPluginRegistry::GetPluginInfoFromSwitch(
base::SplitString(parts[0], '#', &name_parts);
PepperPluginInfo plugin;
+ plugin.is_out_of_process = out_of_process;
#if defined(OS_WIN)
// This means we can't provide plugins from non-ASCII paths, but
// since this switch is only for development I don't think that's
@@ -147,7 +153,7 @@ void PepperPluginRegistry::GetInternalPluginInfo(
// RendererMain() and BrowserMain(). This seemed like the better tradeoff.
//
// TODO(ajwong): Think up a better way to maintain the plugin registration
- // information. Pehraps by construction of a singly linked list of
+ // information. Perhaps by construction of a singly linked list of
// plugin initializers that is built with static initializers?
#if defined(ENABLE_REMOTING)
@@ -168,6 +174,19 @@ void PepperPluginRegistry::GetInternalPluginInfo(
#endif
}
+bool PepperPluginRegistry::RunOutOfProcessForPlugin(
+ const FilePath& path) const {
+ // TODO(brettw) don't recompute this every time. But since this Pepper
+ // switch is only for development, it's OK for now.
+ std::vector<PepperPluginInfo> plugins;
+ GetList(&plugins);
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ if (path == plugins[i].path)
+ return plugins[i].is_out_of_process;
+ }
+ return false;
+}
+
pepper::PluginModule* PepperPluginRegistry::GetModule(
const FilePath& path) const {
ModuleMap::const_iterator it = modules_.find(path);
@@ -181,6 +200,7 @@ PepperPluginRegistry::~PepperPluginRegistry() {}
PepperPluginRegistry::PepperPluginRegistry() {
InternalPluginInfoList internal_plugin_info;
GetInternalPluginInfo(&internal_plugin_info);
+
// Register modules for these suckers.
for (InternalPluginInfoList::const_iterator it =
internal_plugin_info.begin();
@@ -203,6 +223,9 @@ PepperPluginRegistry::PepperPluginRegistry() {
GetPluginInfoFromSwitch(&plugins);
GetExtraPlugins(&plugins);
for (size_t i = 0; i < plugins.size(); ++i) {
+ if (plugins[i].is_out_of_process)
+ continue; // Only preload in-process plugins.
+
const FilePath& path = plugins[i].path;
ModuleHandle module = pepper::PluginModule::CreateModule(path);
if (!module) {
diff --git a/chrome/common/pepper_plugin_registry.h b/chrome/common/pepper_plugin_registry.h
index ebabc2e..60762c5 100644
--- a/chrome/common/pepper_plugin_registry.h
+++ b/chrome/common/pepper_plugin_registry.h
@@ -14,10 +14,16 @@
#include "webkit/glue/plugins/pepper_plugin_module.h"
struct PepperPluginInfo {
- PepperPluginInfo(); // Needed to initialize |is_internal|.
+ PepperPluginInfo();
~PepperPluginInfo();
- bool is_internal; // Defaults to false (see constructor).
+ // Indicates internal plugins for which there's not actually a library.
+ // Defaults to false.
+ bool is_internal;
+
+ // True when this plugin should be run out of process. Defaults to false.
+ bool is_out_of_process;
+
FilePath path; // Internal plugins have "internal-[name]" as path.
std::vector<std::string> mime_types;
std::string name;
@@ -46,6 +52,13 @@ class PepperPluginRegistry {
// access to the plugins before entering the sandbox.
static void PreloadModules();
+ // Returns true if the given plugin is a pepper plugin that should be run
+ // out of process.
+ bool RunOutOfProcessForPlugin(const FilePath& path) const;
+
+ // Returns a preloaded module for the given path. This only works for
+ // non-out-of-process plugins since we preload them so they will run in the
+ // sandbox. Returns NULL if the plugin hasn't been preloaded.
pepper::PluginModule* GetModule(const FilePath& path) const;
~PepperPluginRegistry();
diff --git a/chrome/common/policy_constants.cc b/chrome/common/policy_constants.cc
index f56f2b2..36e6874 100644
--- a/chrome/common/policy_constants.cc
+++ b/chrome/common/policy_constants.cc
@@ -57,6 +57,18 @@ const char kJavascriptEnabled[] = "JavascriptEnabled";
const char kSavingBrowserHistoryDisabled[] = "SavingBrowserHistoryDisabled";
const char kDeveloperToolsDisabled[] = "DeveloperToolsDisabled";
const char kBlockThirdPartyCookies[] = "BlockThirdPartyCookies";
+const char kDefaultCookiesSetting[] = "DefaultCookiesSetting";
+const char kDefaultImagesSetting[] = "DefaultImagesSetting";
+const char kDefaultJavaScriptSetting[] = "DefaultJavaScriptSetting";
+const char kDefaultPluginsSetting[] = "DefaultPluginsSetting";
+const char kDefaultPopupsSetting[] = "DefaultPopupsSetting";
+const char kAuthSchemes[] = "AuthSchemes";
+const char kDisableAuthNegotiateCnameLookup[] =
+ "DisableAuthNegotiateCnameLookup";
+const char kEnableAuthNegotiatePort[] = "EnableAuthNegotiatePort";
+const char kAuthServerWhitelist[] = "AuthServerWhitelist";
+const char kAuthNegotiateDelegateWhitelist[] = "AuthNegotiateDelegateWhitelist";
+const char kGSSAPILibraryName[] = "GSSAPILibraryName";
// Chrome Frame specific policy constants
const char kChromeFrameRendererSettings[] = "ChromeFrameRendererSettings";
diff --git a/chrome/common/policy_constants.h b/chrome/common/policy_constants.h
index 1bff710..623cc17 100644
--- a/chrome/common/policy_constants.h
+++ b/chrome/common/policy_constants.h
@@ -54,6 +54,17 @@ extern const char kJavascriptEnabled[];
extern const char kSavingBrowserHistoryDisabled[];
extern const char kDeveloperToolsDisabled[];
extern const char kBlockThirdPartyCookies[];
+extern const char kDefaultCookiesSetting[];
+extern const char kDefaultImagesSetting[];
+extern const char kDefaultJavaScriptSetting[];
+extern const char kDefaultPluginsSetting[];
+extern const char kDefaultPopupsSetting[];
+extern const char kAuthSchemes[];
+extern const char kDisableAuthNegotiateCnameLookup[];
+extern const char kEnableAuthNegotiatePort[];
+extern const char kAuthServerWhitelist[];
+extern const char kAuthNegotiateDelegateWhitelist[];
+extern const char kGSSAPILibraryName[];
// Chrome Frame specific policy constants
extern const char kChromeFrameRendererSettings[];
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 9c91912..13006f5 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -212,6 +212,19 @@ const char kInstantConfirmDialogShown[] = "instant.confirm_dialog_shown";
// Boolean pref indicating if instant is enabled.
const char kInstantEnabled[] = "instant.enabled";
+// Boolean pref indicating if instant was ever enabled.
+const char kInstantEnabledOnce[] = "instant.enabled_once";
+
+// Time when instant was last enabled.
+const char kInstantEnabledTime[] = "instant.enabled_time";
+
+// Used to maintain instant promo keys. See PromoCounter for details of subkeys
+// that are used.
+const char kInstantPromo[] = "instant.promo";
+
+// Type of instant. This is one of the enums defined in InstantController::TYPE.
+const char kInstantType[] = "instant.type";
+
#if defined(USE_NSS) || defined(USE_OPENSSL)
// Prefs for SSLConfigServicePref. Currently, these are only present on
// and used by NSS/OpenSSL using OSes.
@@ -1025,6 +1038,25 @@ const char kRemotingHasSetupCompleted[] = "remoting.has_setup_completed";
// launches.
const char kRegisteredBackgroundContents[] = "background_contents.registered";
+// String that lists supported HTTP authentication schemes.
+const char kAuthSchemes[] = "auth.schemes";
+
+// Boolean that specifies whether to disable CNAME lookups when generating
+// Kerberos SPN.
+const char kDisableAuthNegotiateCnameLookup[] =
+ "auth.disable_negotiate_cname_lookup";
+// Boolean that specifies whether to include the port in a generated Kerberos
+// SPN.
+const char kEnableAuthNegotiatePort[] = "auth.enable_negotiate_port";
+// Whitelist containing servers for which Integrated Authentication is enabled.
+const char kAuthServerWhitelist[] = "auth.server_whitelist";
+// Whitelist containing servers Chrome is allowed to do Kerberos delegation
+// with.
+const char kAuthNegotiateDelegateWhitelist[] =
+ "auth.negotiate_delegate_whitelist";
+// String that specifies the name of a custom GSSAPI library to load.
+const char kGSSAPILibraryName[] = "auth.gssapi_library_name";
+
#if defined(OS_CHROMEOS)
// Dictionary for transient storage of settings that should go into signed
// settings storage before owner has been assigned.
@@ -1066,4 +1098,17 @@ const char kProxyPacUrl[] = "proxy.pac_url";
// expected syntax see net::ProxyBypassRules::ParseFromString().
const char kProxyBypassList[] = "proxy.bypass_list";
+// Preferences that are exclusivly used to store managed values for default
+// content settings.
+const char kManagedDefaultCookiesSetting[] =
+ "profile.managed_default_content_settings.cookies";
+const char kManagedDefaultImagesSetting[] =
+ "profile.managed_default_content_settings.images";
+const char kManagedDefaultJavaScriptSetting[] =
+ "profile.managed_default_content_settings.javascript";
+const char kManagedDefaultPluginsSetting[] =
+ "profile.managed_default_content_settings.plugins";
+const char kManagedDefaultPopupsSetting[] =
+ "profile.managed_default_content_settings.popups";
+
} // namespace prefs
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 0d5275c..c4d6af1 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -20,7 +20,12 @@ extern const char kHomePage[];
extern const char kSessionExitedCleanly[];
extern const char kRestoreOnStartup[];
extern const char kURLsToRestoreOnStartup[];
+
+// For OS_CHROMEOS we maintain kApplicationLocale property in both local state
+// and user's profile. Global property determines locale of login screen,
+// while user's profile determines his personal locale preference.
extern const char kApplicationLocale[];
+
extern const char kDefaultCharset[];
extern const char kAcceptLanguages[];
extern const char kStaticEncodings[];
@@ -75,6 +80,10 @@ extern const char kDisableSpdy[];
extern const char kCookiePromptExpanded[];
extern const char kInstantConfirmDialogShown[];
extern const char kInstantEnabled[];
+extern const char kInstantEnabledOnce[];
+extern const char kInstantEnabledTime[];
+extern const char kInstantPromo[];
+extern const char kInstantType[];
#if defined(USE_NSS) || defined(USE_OPENSSL)
extern const char kCertRevocationCheckingEnabled[];
extern const char kSSL2Enabled[];
@@ -394,12 +403,25 @@ extern const char kProxyServer[];
extern const char kProxyPacUrl[];
extern const char kProxyBypassList[];
+extern const char kManagedDefaultCookiesSetting[];
+extern const char kManagedDefaultImagesSetting[];
+extern const char kManagedDefaultJavaScriptSetting[];
+extern const char kManagedDefaultPluginsSetting[];
+extern const char kManagedDefaultPopupsSetting[];
+
#if defined(OS_CHROMEOS)
extern const char kSignedSettingsTempStorage[];
#endif
extern const char kRegisteredBackgroundContents[];
+extern const char kAuthSchemes[];
+extern const char kDisableAuthNegotiateCnameLookup[];
+extern const char kEnableAuthNegotiatePort[];
+extern const char kAuthServerWhitelist[];
+extern const char kAuthNegotiateDelegateWhitelist[];
+extern const char kGSSAPILibraryName[];
+
} // namespace prefs
#endif // CHROME_COMMON_PREF_NAMES_H_
diff --git a/chrome/common/render_messages.cc b/chrome/common/render_messages.cc
index 2a42c6c..e6d3126 100644
--- a/chrome/common/render_messages.cc
+++ b/chrome/common/render_messages.cc
@@ -16,6 +16,7 @@
#include "chrome/common/serialized_script_value.h"
#include "chrome/common/speech_input_result.h"
#include "chrome/common/thumbnail_score.h"
+#include "chrome/common/web_apps.h"
#include "gfx/rect.h"
#include "ipc/ipc_channel_handle.h"
#include "media/audio/audio_buffers_state.h"
@@ -29,7 +30,6 @@
#include "webkit/appcache/appcache_interfaces.h"
#include "webkit/blob/blob_data.h"
#include "webkit/glue/context_menu.h"
-#include "webkit/glue/dom_operations.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"
#include "webkit/glue/password_form.h"
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index f00c806..6f6b6cd 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1125,6 +1125,10 @@ IPC_BEGIN_MESSAGES(View)
IPC_MESSAGE_ROUTED1(ViewMsg_SelectPopupMenuItem,
int /* selected index, -1 means no selection */)
+ // Indicate whether speech input API is enabled or not.
+ IPC_MESSAGE_CONTROL1(ViewMsg_SpeechInput_SetFeatureEnabled,
+ bool /* enabled */)
+
IPC_END_MESSAGES(View)
@@ -1578,6 +1582,14 @@ IPC_BEGIN_MESSAGES(ViewHost)
WebPluginInfo /* info */)
// A renderer sends this to the browser process when it wants to
+ // create a pepper plugin. The browser will create the plugin process if
+ // necessary, and will return a handle to the channel on success.
+ // On error an empty string is returned.
+ IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_OpenChannelToPepperPlugin,
+ FilePath /* path */,
+ IPC::ChannelHandle /* handle to channel */)
+
+ // A renderer sends this to the browser process when it wants to
// create connect to the GPU. The browser will create the GPU process if
// necessary, and will return a handle to the channel via
// a GpuChannelEstablished message.
@@ -1850,16 +1862,6 @@ IPC_BEGIN_MESSAGES(ViewHost)
IPC_MESSAGE_ROUTED1(ViewHostMsg_MissingPluginStatus,
int /* status */)
- // Notifies when a non-sandboxed plugin was blocked.
- // |plugin| is the identifier for the plugin (currently its path),
- // |name| is its user-visible name.
- IPC_MESSAGE_ROUTED2(ViewHostMsg_NonSandboxedPluginBlocked,
- std::string /* plugin */,
- string16 /* name */)
-
- // Notifies when a blocked plugin was loaded via click-to-load.
- IPC_MESSAGE_ROUTED0(ViewHostMsg_BlockedPluginLoaded)
-
// Sent by the renderer process to indicate that a plugin instance has
// crashed.
IPC_MESSAGE_ROUTED1(ViewHostMsg_CrashedPlugin,
@@ -1901,7 +1903,7 @@ IPC_BEGIN_MESSAGES(ViewHost)
IPC_MESSAGE_ROUTED2(ViewHostMsg_DidGetApplicationInfo,
int32 /* page_id */,
- webkit_glue::WebApplicationInfo)
+ WebApplicationInfo)
// Provides the result from running OnMsgShouldClose. |proceed| matches the
// return value of the the frame's shouldClose method (which includes the
@@ -2085,7 +2087,7 @@ IPC_BEGIN_MESSAGES(ViewHost)
// Queries the browser for AutoFill suggestions for a form input field.
IPC_MESSAGE_ROUTED3(ViewHostMsg_QueryFormFieldAutoFill,
int /* id of this message */,
- bool /* form_autofilled */,
+ bool /* field autofilled */,
webkit_glue::FormField /* the form field */)
// Sent when the popup with AutoFill suggestions for a form is shown.
diff --git a/chrome/common/render_messages_params.cc b/chrome/common/render_messages_params.cc
index a57b076..15b04d2 100644
--- a/chrome/common/render_messages_params.cc
+++ b/chrome/common/render_messages_params.cc
@@ -136,8 +136,7 @@ ViewHostMsg_DidPrintPage_Params::ViewHostMsg_DidPrintPage_Params()
ViewHostMsg_DidPrintPage_Params::~ViewHostMsg_DidPrintPage_Params() {
}
-ViewHostMsg_Audio_CreateStream_Params::ViewHostMsg_Audio_CreateStream_Params()
- : packet_size(0) {
+ViewHostMsg_Audio_CreateStream_Params::ViewHostMsg_Audio_CreateStream_Params() {
}
ViewHostMsg_Audio_CreateStream_Params::
@@ -842,6 +841,7 @@ void ParamTraits<ViewHostMsg_UpdateRect_Params>::Write(
WriteParam(m, p.scroll_rect);
WriteParam(m, p.copy_rects);
WriteParam(m, p.view_size);
+ WriteParam(m, p.resizer_rect);
WriteParam(m, p.plugin_window_moves);
WriteParam(m, p.flags);
}
@@ -856,6 +856,7 @@ bool ParamTraits<ViewHostMsg_UpdateRect_Params>::Read(
ReadParam(m, iter, &p->scroll_rect) &&
ReadParam(m, iter, &p->copy_rects) &&
ReadParam(m, iter, &p->view_size) &&
+ ReadParam(m, iter, &p->resizer_rect) &&
ReadParam(m, iter, &p->plugin_window_moves) &&
ReadParam(m, iter, &p->flags);
}
@@ -877,6 +878,8 @@ void ParamTraits<ViewHostMsg_UpdateRect_Params>::Log(const param_type& p,
l->append(", ");
LogParam(p.view_size, l);
l->append(", ");
+ LogParam(p.resizer_rect, l);
+ l->append(", ");
LogParam(p.plugin_window_moves, l);
l->append(", ");
LogParam(p.flags, l);
@@ -1096,7 +1099,7 @@ void ParamTraits<ViewHostMsg_Audio_CreateStream_Params>::Write(
WriteParam(m, p.params.channels);
WriteParam(m, p.params.sample_rate);
WriteParam(m, p.params.bits_per_sample);
- WriteParam(m, p.packet_size);
+ WriteParam(m, p.params.samples_per_packet);
}
bool ParamTraits<ViewHostMsg_Audio_CreateStream_Params>::Read(const Message* m,
@@ -1107,7 +1110,7 @@ bool ParamTraits<ViewHostMsg_Audio_CreateStream_Params>::Read(const Message* m,
ReadParam(m, iter, &p->params.channels) &&
ReadParam(m, iter, &p->params.sample_rate) &&
ReadParam(m, iter, &p->params.bits_per_sample) &&
- ReadParam(m, iter, &p->packet_size);
+ ReadParam(m, iter, &p->params.samples_per_packet);
}
void ParamTraits<ViewHostMsg_Audio_CreateStream_Params>::Log(
@@ -1122,7 +1125,7 @@ void ParamTraits<ViewHostMsg_Audio_CreateStream_Params>::Log(
l->append(", ");
LogParam(p.params.bits_per_sample, l);
l->append(", ");
- LogParam(p.packet_size, l);
+ LogParam(p.params.samples_per_packet, l);
l->append(")");
}
diff --git a/chrome/common/render_messages_params.h b/chrome/common/render_messages_params.h
index d92def3..ef5716b 100644
--- a/chrome/common/render_messages_params.h
+++ b/chrome/common/render_messages_params.h
@@ -27,6 +27,8 @@
#include "chrome/common/renderer_preferences.h"
#include "chrome/common/serialized_script_value.h"
#include "chrome/common/window_container_type.h"
+#include "gfx/rect.h"
+#include "gfx/size.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_param_traits.h"
#include "media/audio/audio_parameters.h"
@@ -347,6 +349,10 @@ struct ViewHostMsg_UpdateRect_Params {
// progress.
gfx::Size view_size;
+ // The area of the RenderView reserved for resize corner when this message
+ // was generated. Reported for the same reason as view_size is.
+ gfx::Rect resizer_rect;
+
// New window locations for plugin child windows.
std::vector<webkit_glue::WebPluginGeometry> plugin_window_moves;
@@ -577,14 +583,10 @@ struct ViewHostMsg_Audio_CreateStream_Params {
ViewHostMsg_Audio_CreateStream_Params();
~ViewHostMsg_Audio_CreateStream_Params();
- // Format request for the stream.
+ // Parameters for the new audio stream.
+ // If |samples_per_packet| is set 0, the audio packet size is selected
+ // automatically by the browser process.
AudioParameters params;
-
- // Number of bytes per packet. Determines the maximum number of bytes
- // transported for each audio packet request.
- // A value of 0 means that the audio packet size is selected automatically
- // by the browser process.
- uint32 packet_size;
};
// This message is used for supporting popup menus on Mac OS X using native
diff --git a/chrome/common/resource_dispatcher_unittest.cc b/chrome/common/resource_dispatcher_unittest.cc
index f5828ff..e5d6dfd 100644
--- a/chrome/common/resource_dispatcher_unittest.cc
+++ b/chrome/common/resource_dispatcher_unittest.cc
@@ -30,6 +30,8 @@ static const char test_page_contents[] =
"<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
static const uint32 test_page_contents_len = arraysize(test_page_contents) - 1;
+static const char kShmemSegmentName[] = "DeferredResourceLoaderTest";
+
// Listens for request response data and stores it so that it can be compared
// to the reference data.
class TestRequestCallback : public ResourceLoaderBridge::Peer {
@@ -289,13 +291,14 @@ class DeferredResourceLoadingTest : public ResourceDispatcherTest,
protected:
virtual void SetUp() {
- EXPECT_EQ(true, shared_handle_.CreateNamed("DeferredResourceLoaderTest",
- false, 100));
ResourceDispatcherTest::SetUp();
+ shared_handle_.Delete(kShmemSegmentName);
+ EXPECT_EQ(true, shared_handle_.CreateNamed(kShmemSegmentName, false, 100));
}
virtual void TearDown() {
shared_handle_.Close();
+ EXPECT_TRUE(shared_handle_.Delete(kShmemSegmentName));
ResourceDispatcherTest::TearDown();
}
@@ -325,4 +328,3 @@ TEST_F(DeferredResourceLoadingTest, DeferredLoadTest) {
message_loop.RunAllPending();
delete bridge;
}
-
diff --git a/chrome/common/sandbox_mac.mm b/chrome/common/sandbox_mac.mm
index 6ede3bf..81defc7 100644
--- a/chrome/common/sandbox_mac.mm
+++ b/chrome/common/sandbox_mac.mm
@@ -94,7 +94,7 @@ bool Sandbox::QuotePlainString(const std::string& src_utf8, std::string* dst) {
if (c < 32 || c > 126) {
// Any characters that aren't printable ASCII get the \u treatment.
unsigned int as_uint = static_cast<unsigned int>(c);
- StringAppendF(dst, "\\u%04X", as_uint);
+ base::StringAppendF(dst, "\\u%04X", as_uint);
continue;
}
@@ -485,23 +485,20 @@ bool Sandbox::EnableSandbox(SandboxProcessType sandbox_type,
substitutions["DISABLE_SANDBOX_DENIAL_LOGGING"] = SandboxSubstring("");
}
+ // Splice the path of the user's home directory into the sandbox profile
+ // (see renderer.sb for details).
+ std::string home_dir = base::SysNSStringToUTF8(NSHomeDirectory());
+
+ FilePath home_dir_canonical(home_dir);
+ GetCanonicalSandboxPath(&home_dir_canonical);
+
+ substitutions["USER_HOMEDIR_AS_LITERAL"] =
+ SandboxSubstring(home_dir_canonical.value(),
+ SandboxSubstring::LITERAL);
+
if (snow_leopard_or_higher) {
// 10.6-only Sandbox rules.
[tokens_to_remove addObject:@";10.6_ONLY"];
- // Splice the path of the user's home directory into the sandbox profile
- // (see renderer.sb for details).
- // This code is in the 10.6-only block because the sandbox syntax we use
- // for this "subdir" is only supported on 10.6.
- // If we ever need this on pre-10.6 OSs then we'll have to rethink the
- // surrounding sandbox syntax.
- std::string home_dir = base::SysNSStringToUTF8(NSHomeDirectory());
-
- FilePath home_dir_canonical(home_dir);
- GetCanonicalSandboxPath(&home_dir_canonical);
-
- substitutions["USER_HOMEDIR_AS_LITERAL"] =
- SandboxSubstring(home_dir_canonical.value(),
- SandboxSubstring::LITERAL);
} else {
// Sandbox rules only for versions before 10.6.
[tokens_to_remove addObject:@";BEFORE_10.6"];
diff --git a/chrome/common/sandbox_policy.cc b/chrome/common/sandbox_policy.cc
index 0ab7563..7adf2b9 100644
--- a/chrome/common/sandbox_policy.cc
+++ b/chrome/common/sandbox_policy.cc
@@ -329,6 +329,24 @@ bool LoadFlashBroker(const FilePath& plugin_path, CommandLine* cmd_line) {
cmd_line->AppendSwitchASCII("flash-broker",
base::Int64ToString(::GetProcessId(process)));
+
+ // The flash broker, unders some circumstances can linger beyond the lifetime
+ // of the flash player, so we put it in a job object, when the browser
+ // terminates the job object is destroyed (by the OS) and the flash broker
+ // is terminated.
+ HANDLE job = ::CreateJobObjectW(NULL, NULL);
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_limits = {0};
+ job_limits.BasicLimitInformation.LimitFlags =
+ JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+ if (::SetInformationJobObject(job, JobObjectExtendedLimitInformation,
+ &job_limits, sizeof(job_limits))) {
+ ::AssignProcessToJobObject(job, process);
+ // Yes, we are leaking the object here. Read comment above.
+ } else {
+ ::CloseHandle(job);
+ return false;
+ }
+
::CloseHandle(process);
return true;
}
@@ -347,7 +365,6 @@ bool ApplyPolicyForBuiltInFlashPlugin(sandbox::TargetPolicy* policy) {
initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS;
policy->SetTokenLevel(initial_token, sandbox::USER_LIMITED);
-
policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
// TODO(cpu): Proxy registry access and remove these policies.
@@ -363,6 +380,26 @@ bool ApplyPolicyForBuiltInFlashPlugin(sandbox::TargetPolicy* policy) {
return true;
}
+// Returns true of the plugin specified in |cmd_line| is the built-in
+// flash plugin and optionally returns its full path in |flash_path|
+bool IsBuiltInFlash(const CommandLine* cmd_line, FilePath* flash_path) {
+ std::wstring plugin_dll = cmd_line->
+ GetSwitchValueNative(switches::kPluginPath);
+
+ FilePath builtin_flash;
+ if (!PathService::Get(chrome::FILE_FLASH_PLUGIN, &builtin_flash))
+ return false;
+
+ FilePath plugin_path(plugin_dll);
+ if (plugin_path != builtin_flash)
+ return false;
+
+ if (flash_path)
+ *flash_path = plugin_path;
+ return true;
+}
+
+
// Adds the custom policy rules for a given plugin. |trusted_plugins| contains
// the comma separate list of plugin dll names that should not be sandboxed.
bool AddPolicyForPlugin(CommandLine* cmd_line,
@@ -382,18 +419,15 @@ bool AddPolicyForPlugin(CommandLine* cmd_line,
}
// The built-in flash gets a custom, more restricted sandbox.
- FilePath builtin_flash;
- if (PathService::Get(chrome::FILE_FLASH_PLUGIN, &builtin_flash)) {
- FilePath plugin_path(plugin_dll);
- if (plugin_path == builtin_flash) {
- // Spawn the flash broker and apply sandbox policy.
- if (!LoadFlashBroker(plugin_path, cmd_line)) {
- // Could not start the broker, use a very weak policy instead.
- DLOG(WARNING) << "Failed to start flash broker";
- return ApplyPolicyForTrustedPlugin(policy);
- }
- return ApplyPolicyForBuiltInFlashPlugin(policy);
+ FilePath flash_path;
+ if (IsBuiltInFlash(cmd_line, &flash_path)) {
+ // Spawn the flash broker and apply sandbox policy.
+ if (!LoadFlashBroker(flash_path, cmd_line)) {
+ // Could not start the broker, use a very weak policy instead.
+ DLOG(WARNING) << "Failed to start flash broker";
+ return ApplyPolicyForTrustedPlugin(policy);
}
+ return ApplyPolicyForBuiltInFlashPlugin(policy);
}
PluginPolicyCategory policy_category =
@@ -475,6 +509,8 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
type = ChildProcessInfo::NACL_BROKER_PROCESS;
} else if (type_str == switches::kGpuProcess) {
type = ChildProcessInfo::GPU_PROCESS;
+ } else if (type_str == switches::kPpapiPluginProcess) {
+ type = ChildProcessInfo::PPAPI_PLUGIN_PROCESS;
} else {
NOTREACHED();
return 0;
@@ -482,12 +518,28 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
TRACE_EVENT_BEGIN("StartProcessWithAccess", 0, type_str);
+ // To decide if the process is going to be sandboxed we have two cases.
+ // First case: all process types except the nacl broker, gpu process and
+ // the plugin process are sandboxed by default.
bool in_sandbox =
(type != ChildProcessInfo::NACL_BROKER_PROCESS) &&
- !browser_command_line.HasSwitch(switches::kNoSandbox) &&
- (type != ChildProcessInfo::PLUGIN_PROCESS ||
- browser_command_line.HasSwitch(switches::kSafePlugins)) &&
- (type != ChildProcessInfo::GPU_PROCESS);
+ (type != ChildProcessInfo::GPU_PROCESS) &&
+ (type != ChildProcessInfo::PLUGIN_PROCESS);
+
+ // Second case: If it is the plugin process then it depends on it being
+ // the built-in flash, the user forcing plugins into sandbox or the
+ // the user explicitly excluding flash from the sandbox.
+ if (!in_sandbox && (type == ChildProcessInfo::PLUGIN_PROCESS)) {
+ in_sandbox = browser_command_line.HasSwitch(switches::kSafePlugins) ||
+ (IsBuiltInFlash(cmd_line, NULL) &&
+ !browser_command_line.HasSwitch(switches::kDisableFlashSandbox));
+ }
+
+ if (browser_command_line.HasSwitch(switches::kNoSandbox)) {
+ // The user has explicity opted-out from all sandboxing.
+ in_sandbox = false;
+ }
+
#if !defined (GOOGLE_CHROME_BUILD)
if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) {
// In process plugins won't work if the sandbox is enabled.
diff --git a/chrome/common/security_style.h b/chrome/common/security_style.h
new file mode 100644
index 0000000..7d92d0e
--- /dev/null
+++ b/chrome/common/security_style.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_SECURITY_STYLE_H_
+#define CHROME_COMMON_SECURITY_STYLE_H_
+#pragma once
+
+// Various aspects of the UI change their appearance according to the security
+// context in which they are displayed. For example, the location bar displays
+// a lock icon when it is displayed during a valid SSL connection.
+// SecuirtySyle enumerates these styles, but it is up to the UI elements to
+// adjust their display appropriately.
+enum SecurityStyle {
+ // SECURITY_STYLE_UNKNOWN indicates that we do not know the proper security
+ // style for this object.
+ SECURITY_STYLE_UNKNOWN,
+
+ // SECURITY_STYLE_UNAUTHENTICATED means the authenticity of this object can
+ // not be determined, either because it was retrieved using an unauthenticated
+ // protocol, such as HTTP or FTP, or it was retrieved using a protocol that
+ // supports authentication, such as HTTPS, but there were errors during
+ // transmission that render us uncertain to the object's authenticity.
+ SECURITY_STYLE_UNAUTHENTICATED,
+
+ // SECURITY_STYLE_AUTHENTICATION_BROKEN indicates that we tried to retrieve
+ // this object in an authenticated manner but were unable to do so.
+ SECURITY_STYLE_AUTHENTICATION_BROKEN,
+
+ // SECURITY_STYLE_AUTHENTICATED indicates that we successfully retrieved this
+ // object over an authenticated protocol, such as HTTPS.
+ SECURITY_STYLE_AUTHENTICATED,
+};
+
+#endif // CHROME_COMMON_SECURITY_STYLE_H_
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 427c933..554b5ba 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -174,6 +174,27 @@ const char kLanguageOptionsSubPage[] = "language";
const char kSystemOptionsSubPage[] = "system";
#endif
+const char kPageInfoHelpCenterURL[] =
+#if defined(OS_CHROMEOS)
+ "http://www.google.com/support/chromeos/bin/answer.py?answer=95617";
+#else
+ "http://www.google.com/support/chrome/bin/answer.py?answer=95617";
+#endif
+
+const char kCrashReasonURL[] =
+#if defined(OS_CHROMEOS)
+ "http://www.google.com/support/chromeos/bin/answer.py?answer=1047340";
+#else
+ "http://www.google.com/support/chrome/bin/answer.py?answer=95669";
+#endif
+
+const char kPrivacyLearnMoreURL[] =
+#if defined(OS_CHROMEOS)
+ "http://www.google.com/support/chromeos/bin/answer.py?answer=1047334";
+#else
+ "http://www.google.com/support/chrome/bin/answer.py?answer=114836";
+#endif
+
void RegisterChromeSchemes() {
// Don't need "chrome-internal" which was used in old versions of Chrome for
// the new tab page.
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 05e32e6..14c2b37 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -170,6 +170,15 @@ extern const char kLanguageOptionsSubPage[];
extern const char kSystemOptionsSubPage[];
#endif
+// "What do these mean?" URL for the Page Info bubble.
+extern const char kPageInfoHelpCenterURL[];
+
+// "Learn more" URL for "Aw snap" page.
+extern const char kCrashReasonURL[];
+
+// "Learn more" URL for the Privacy section under Options.
+extern const char kPrivacyLearnMoreURL[];
+
// Call near the beginning of startup to register Chrome's internal URLs that
// should be parsed as "standard" with the googleurl library.
void RegisterChromeSchemes();
diff --git a/chrome/common/web_app_schema.json b/chrome/common/web_app_schema.json
new file mode 100644
index 0000000..fe23966
--- /dev/null
+++ b/chrome/common/web_app_schema.json
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file contains the schema for web app defintion files.
+
+{
+ "type": "object",
+ "properties": {
+ // TODO(aa): Need to figure out what max length the store is using for name
+ // and description.
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 45
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 132,
+ "optional": true
+ },
+ "launch_url": {
+ "type": "string",
+ "minLength": 1
+ },
+ "launch_container": {
+ "enum": ["tab", "panel"],
+ "optional": true
+ },
+ // TODO(aa): We had problems with a simple array of strings in extensions.
+ // Consider something else.
+ "permissions": {
+ "type": "array",
+ "optional": true,
+ "items": {
+ "type": "string",
+ "minLength": 1
+ }
+ },
+ "urls": {
+ "type": "array",
+ "optional": true,
+ "items": {
+ "type": "string",
+ "minLength": 1
+ }
+ },
+ "icons": {
+ "type": "object",
+ "optional": true,
+ "properties": {
+ "16": { "optional": true, "type": "string", "minLength": 1 },
+ "48": { "optional": true, "type": "string", "minLength": 1 },
+ "128": { "optional": true, "type": "string", "minLength": 1 }
+ }
+ }
+ }
+}
diff --git a/chrome/common/web_apps.cc b/chrome/common/web_apps.cc
new file mode 100644
index 0000000..cde9690
--- /dev/null
+++ b/chrome/common/web_apps.cc
@@ -0,0 +1,323 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/web_apps.h"
+
+#include <string>
+#include <vector>
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/json/json_reader.h"
+#include "base/string16.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/json_schema_validator.h"
+#include "gfx/size.h"
+#include "googleurl/src/gurl.h"
+#include "grit/common_resources.h"
+#include "grit/generated_resources.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebElement.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebNode.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebNodeList.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
+#include "webkit/glue/dom_operations.h"
+
+using WebKit::WebDocument;
+using WebKit::WebElement;
+using WebKit::WebFrame;
+using WebKit::WebNode;
+using WebKit::WebNodeList;
+using WebKit::WebString;
+
+namespace {
+
+// Sizes a single size (the width or height) from a 'sizes' attribute. A size
+// matches must match the following regex: [1-9][0-9]*.
+static int ParseSingleIconSize(const string16& text) {
+ // Size must not start with 0, and be between 0 and 9.
+ if (text.empty() || !(text[0] >= L'1' && text[0] <= L'9'))
+ return 0;
+
+ // Make sure all chars are from 0-9.
+ for (size_t i = 1; i < text.length(); ++i) {
+ if (!(text[i] >= L'0' && text[i] <= L'9'))
+ return 0;
+ }
+ int output;
+ if (!base::StringToInt(text, &output))
+ return 0;
+ return output;
+}
+
+void AddInstallIcon(const WebElement& link,
+ std::vector<WebApplicationInfo::IconInfo>* icons) {
+ WebString href = link.getAttribute("href");
+ if (href.isNull() || href.isEmpty())
+ return;
+
+ // Get complete url.
+ GURL url = link.document().completeURL(href);
+ if (!url.is_valid())
+ return;
+
+ if (!link.hasAttribute("sizes"))
+ return;
+
+ bool is_any = false;
+ std::vector<gfx::Size> icon_sizes;
+ if (!web_apps::ParseIconSizes(link.getAttribute("sizes"), &icon_sizes,
+ &is_any) ||
+ is_any ||
+ icon_sizes.size() != 1) {
+ return;
+ }
+ WebApplicationInfo::IconInfo icon_info;
+ icon_info.width = icon_sizes[0].width();
+ icon_info.height = icon_sizes[0].height();
+ icon_info.url = url;
+ icons->push_back(icon_info);
+}
+
+}
+
+const char WebApplicationInfo::kInvalidDefinitionURL[] =
+ "Invalid application definition URL. Must be a valid relative URL or "
+ "an absolute URL with the same origin as the document.";
+const char WebApplicationInfo::kInvalidLaunchURL[] =
+ "Invalid value for property 'launch_url'. Must be a valid relative URL or "
+ "an absolute URL with the same origin as the application definition.";
+const char WebApplicationInfo::kInvalidURL[] =
+ "Invalid value for property 'urls[*]'. Must be a valid relative URL or "
+ "an absolute URL with the same origin as the application definition.";
+const char WebApplicationInfo::kInvalidIconURL[] =
+ "Invalid value for property 'icons.*'. Must be a valid relative URL or "
+ "an absolute URL with the same origin as the application definition.";
+
+WebApplicationInfo::WebApplicationInfo() {
+}
+
+WebApplicationInfo::~WebApplicationInfo() {
+}
+
+
+namespace web_apps {
+
+gfx::Size ParseIconSize(const string16& text) {
+ std::vector<string16> sizes;
+ base::SplitStringDontTrim(text, L'x', &sizes);
+ if (sizes.size() != 2)
+ return gfx::Size();
+
+ return gfx::Size(ParseSingleIconSize(sizes[0]),
+ ParseSingleIconSize(sizes[1]));
+}
+
+bool ParseIconSizes(const string16& text,
+ std::vector<gfx::Size>* sizes,
+ bool* is_any) {
+ *is_any = false;
+ std::vector<string16> size_strings;
+ base::SplitStringAlongWhitespace(text, &size_strings);
+ for (size_t i = 0; i < size_strings.size(); ++i) {
+ if (EqualsASCII(size_strings[i], "any")) {
+ *is_any = true;
+ } else {
+ gfx::Size size = ParseIconSize(size_strings[i]);
+ if (size.width() <= 0 || size.height() <= 0)
+ return false; // Bogus size.
+ sizes->push_back(size);
+ }
+ }
+ if (*is_any && !sizes->empty()) {
+ // If is_any is true, it must occur by itself.
+ return false;
+ }
+ return (*is_any || !sizes->empty());
+}
+
+bool ParseWebAppFromWebDocument(WebFrame* frame,
+ WebApplicationInfo* app_info,
+ string16* error) {
+ WebDocument document = frame->document();
+ if (document.isNull())
+ return true;
+
+ WebElement head = document.head();
+ if (head.isNull())
+ return true;
+
+ GURL frame_url = frame->url();
+ WebNodeList children = head.childNodes();
+ for (unsigned i = 0; i < children.length(); ++i) {
+ WebNode child = children.item(i);
+ if (!child.isElementNode())
+ continue;
+ WebElement elem = child.to<WebElement>();
+
+ if (elem.hasTagName("link")) {
+ std::string rel = elem.getAttribute("rel").utf8();
+ // "rel" attribute may use either "icon" or "shortcut icon".
+ // see also
+ // <http://en.wikipedia.org/wiki/Favicon>
+ // <http://dev.w3.org/html5/spec/Overview.html#rel-icon>
+ if (LowerCaseEqualsASCII(rel, "icon") ||
+ LowerCaseEqualsASCII(rel, "shortcut icon")) {
+ AddInstallIcon(elem, &app_info->icons);
+ } else if (LowerCaseEqualsASCII(rel, "chrome-application-definition")) {
+ std::string definition_url_string(elem.getAttribute("href").utf8());
+ GURL definition_url;
+ if (!(definition_url =
+ frame_url.Resolve(definition_url_string)).is_valid() ||
+ definition_url.GetOrigin() != frame_url.GetOrigin()) {
+ *error = UTF8ToUTF16(WebApplicationInfo::kInvalidDefinitionURL);
+ return false;
+ }
+
+ // If there is a definition file, all attributes come from it.
+ *app_info = WebApplicationInfo();
+ app_info->manifest_url = definition_url;
+ return true;
+ }
+ } else if (elem.hasTagName("meta") && elem.hasAttribute("name")) {
+ std::string name = elem.getAttribute("name").utf8();
+ WebString content = elem.getAttribute("content");
+ if (name == "application-name") {
+ app_info->title = content;
+ } else if (name == "description") {
+ app_info->description = content;
+ } else if (name == "application-url") {
+ std::string url = content.utf8();
+ app_info->app_url = frame_url.is_valid() ?
+ frame_url.Resolve(url) : GURL(url);
+ if (!app_info->app_url.is_valid())
+ app_info->app_url = GURL();
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ParseWebAppFromDefinitionFile(const DictionaryValue& definition,
+ WebApplicationInfo* web_app,
+ string16* error) {
+ CHECK(web_app->manifest_url.is_valid());
+
+ int error_code = 0;
+ std::string error_message;
+ scoped_ptr<Value> schema(
+ base::JSONReader::ReadAndReturnError(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_WEB_APP_SCHEMA).as_string(),
+ false, // disallow trailing comma
+ &error_code,
+ &error_message));
+ CHECK(schema.get())
+ << "Error parsing JSON schema: " << error_code << ": " << error_message;
+ CHECK(schema->IsType(Value::TYPE_DICTIONARY))
+ << "schema root must be dictionary.";
+
+ JSONSchemaValidator validator(static_cast<DictionaryValue*>(schema.get()));
+
+ // We allow extra properties in the schema for easy compat with other systems,
+ // and for forward compat with ourselves.
+ validator.set_default_allow_additional_properties(true);
+
+ if (!validator.Validate(const_cast<DictionaryValue*>(&definition))) {
+ *error = UTF8ToUTF16(
+ validator.errors()[0].path + ": " + validator.errors()[0].message);
+ return false;
+ }
+
+ // Parse launch URL. It must be a valid URL in the same origin as the
+ // manifest.
+ std::string app_url_string;
+ GURL app_url;
+ CHECK(definition.GetString("launch_url", &app_url_string));
+ if (!(app_url = web_app->manifest_url.Resolve(app_url_string)).is_valid() ||
+ app_url.GetOrigin() != web_app->manifest_url.GetOrigin()) {
+ *error = UTF8ToUTF16(WebApplicationInfo::kInvalidLaunchURL);
+ return false;
+ }
+
+ // Parse out the permissions if present.
+ std::vector<std::string> permissions;
+ ListValue* permissions_value = NULL;
+ if (definition.GetList("permissions", &permissions_value)) {
+ for (size_t i = 0; i < permissions_value->GetSize(); ++i) {
+ std::string permission;
+ CHECK(permissions_value->GetString(i, &permission));
+ permissions.push_back(permission);
+ }
+ }
+
+ // Parse out the URLs if present.
+ std::vector<GURL> urls;
+ ListValue* urls_value = NULL;
+ if (definition.GetList("urls", &urls_value)) {
+ for (size_t i = 0; i < urls_value->GetSize(); ++i) {
+ std::string url_string;
+ GURL url;
+ CHECK(urls_value->GetString(i, &url_string));
+ if (!(url = web_app->manifest_url.Resolve(url_string)).is_valid() ||
+ url.GetOrigin() != web_app->manifest_url.GetOrigin()) {
+ *error = UTF8ToUTF16(
+ JSONSchemaValidator::FormatErrorMessage(
+ WebApplicationInfo::kInvalidURL, base::Uint64ToString(i)));
+ return false;
+ }
+ urls.push_back(url);
+ }
+ }
+
+ // Parse out the icons if present.
+ std::vector<WebApplicationInfo::IconInfo> icons;
+ DictionaryValue* icons_value = NULL;
+ if (definition.GetDictionary("icons", &icons_value)) {
+ for (DictionaryValue::key_iterator iter = icons_value->begin_keys();
+ iter != icons_value->end_keys(); ++iter) {
+ // Ignore unknown properties. Better for forward compat.
+ int size = 0;
+ if (!base::StringToInt(*iter, &size) || size < 0 || size > 128)
+ continue;
+
+ std::string icon_url_string;
+ GURL icon_url;
+ if (!icons_value->GetString(*iter, &icon_url_string) ||
+ !(icon_url = web_app->manifest_url.Resolve(
+ icon_url_string)).is_valid()) {
+ *error = UTF8ToUTF16(
+ JSONSchemaValidator::FormatErrorMessage(
+ WebApplicationInfo::kInvalidIconURL, base::IntToString(size)));
+ return false;
+ }
+
+ WebApplicationInfo::IconInfo icon;
+ icon.url = icon_url;
+ icon.width = size;
+ icon.height = size;
+
+ icons.push_back(icon);
+ }
+ }
+
+ CHECK(definition.GetString("name", &web_app->title));
+ definition.GetString("description", &web_app->description);
+ definition.GetString("launch_container", &web_app->launch_container);
+ web_app->app_url = app_url;
+ web_app->urls = urls;
+ web_app->permissions = permissions;
+ web_app->icons = icons;
+
+ return true;
+
+}
+
+} // namespace web_apps
diff --git a/chrome/common/web_apps.h b/chrome/common/web_apps.h
new file mode 100644
index 0000000..6d40883
--- /dev/null
+++ b/chrome/common/web_apps.h
@@ -0,0 +1,109 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_WEB_APPS_H_
+#define CHROME_COMMON_WEB_APPS_H_
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "base/string16.h"
+#include "googleurl/src/gurl.h"
+#include "gfx/size.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace WebKit {
+class WebDocument;
+class WebFrame;
+}
+
+class DictionaryValue;
+
+// Structure used when installing a web page as an app.
+struct WebApplicationInfo {
+ struct IconInfo {
+ GURL url;
+ int width;
+ int height;
+ SkBitmap data;
+ };
+
+ static const char kInvalidDefinitionURL[];
+ static const char kInvalidLaunchURL[];
+ static const char kInvalidURL[];
+ static const char kInvalidIconSize[];
+ static const char kInvalidIconURL[];
+
+ WebApplicationInfo();
+ ~WebApplicationInfo();
+
+ // URL to a manifest that defines the application. If specified, all other
+ // attributes are derived from this manifest, and the manifest is the unique
+ // ID of the application.
+ GURL manifest_url;
+
+ // Title of the application.
+ string16 title;
+
+ // Description of the application.
+ string16 description;
+
+ // The launch URL for the app.
+ GURL app_url;
+
+ // Set of available icons.
+ std::vector<IconInfo> icons;
+
+ // The permissions the app requests. Only supported with manifest-based apps.
+ std::vector<std::string> permissions;
+
+ // Set of URLs that comprise the app. Only supported with manifest-based apps.
+ // All these must be of the same origin as manifest_url.
+ std::vector<GURL> urls;
+
+ // The type of launch container to use with the app. Currently supported
+ // values are 'tab' and 'panel'. Only supported with manifest-based apps.
+ std::string launch_container;
+};
+
+
+namespace web_apps {
+
+// Parses an icon size. An icon size must match the following regex:
+// [1-9][0-9]*x[1-9][0-9]*.
+// If the input couldn't be parsed, a size with a width/height == 0 is returned.
+gfx::Size ParseIconSize(const string16& text);
+
+// Parses the icon's size attribute as defined in the HTML 5 spec. Returns true
+// on success, false on errors. On success either all the sizes specified in
+// the attribute are added to sizes, or is_any is set to true.
+//
+// You shouldn't have a need to invoke this directly, it's public for testing.
+bool ParseIconSizes(const string16& text, std::vector<gfx::Size>* sizes,
+ bool* is_any);
+
+// Parses |web_app| information out of the document in frame. Returns true on
+// success, or false and |error| on failure. Note that the document may contain
+// no web application information, in which case |web_app| is unchanged and the
+// function returns true.
+//
+// Documents can also contain a link to a application 'definition'. In this case
+// web_app will have manifest_url set and nothing else. The caller must fetch
+// this URL and pass the result to ParseWebAppFromDefinitionFile() for further
+// processing.
+bool ParseWebAppFromWebDocument(WebKit::WebFrame* frame,
+ WebApplicationInfo* web_app,
+ string16* error);
+
+// Parses |web_app| information out of |definition|. Returns true on success, or
+// false and |error| on failure. This function assumes that |web_app| has a
+// valid manifest_url.
+bool ParseWebAppFromDefinitionFile(const DictionaryValue& definition,
+ WebApplicationInfo* web_app,
+ string16* error);
+
+} // namespace web_apps
+
+#endif // CHROME_COMMON_WEB_APPS_H_
diff --git a/chrome/common/web_apps_unittest.cc b/chrome/common/web_apps_unittest.cc
new file mode 100644
index 0000000..3a6980e
--- /dev/null
+++ b/chrome/common/web_apps_unittest.cc
@@ -0,0 +1,190 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/web_apps.h"
+
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/scoped_ptr.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/json_schema_validator.h"
+#include "chrome/common/json_value_serializer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+DictionaryValue* LoadDefinitionFile(const std::string& name) {
+ FilePath path;
+ if (!PathService::Get(chrome::DIR_TEST_DATA, &path)) {
+ ADD_FAILURE() << "Could not get test data dir.";
+ return NULL;
+ }
+
+ path = path.AppendASCII("web_app_info").AppendASCII(name.c_str());
+ if (!file_util::PathExists(path)) {
+ ADD_FAILURE() << "Path does not exist: " << path.value();
+ return NULL;
+ }
+
+ std::string error;
+ JSONFileValueSerializer serializer(path);
+ DictionaryValue* result = static_cast<DictionaryValue*>(
+ serializer.Deserialize(NULL, &error));
+ if (!result) {
+ ADD_FAILURE() << "Error parsing " << name << ": " << error;
+ return NULL;
+ }
+
+ return result;
+}
+
+WebApplicationInfo* ParseFromDefinitionAndExpectSuccess(
+ const std::string& name) {
+ scoped_ptr<DictionaryValue> defintion(LoadDefinitionFile(name));
+ if (!defintion.get())
+ return NULL;
+
+ scoped_ptr<WebApplicationInfo> web_app(new WebApplicationInfo());
+ web_app->manifest_url = GURL("http://example.com/");
+
+ string16 error;
+ if (!web_apps::ParseWebAppFromDefinitionFile(*defintion, web_app.get(),
+ &error)) {
+ ADD_FAILURE() << "Error parsing " << name << ": " << UTF16ToUTF8(error);
+ return NULL;
+ }
+
+ return web_app.release();
+}
+
+void ParseFromDefinitionAndExpectFailure(const std::string& name,
+ const string16& expected_error) {
+ scoped_ptr<DictionaryValue> definition(LoadDefinitionFile(name));
+ if (!definition.get())
+ return;
+
+ WebApplicationInfo web_app;
+ web_app.manifest_url = GURL("http://example.com/");
+
+ string16 error;
+ if (web_apps::ParseWebAppFromDefinitionFile(*definition, &web_app, &error)) {
+ ADD_FAILURE() << "Expected error parsing " << name
+ << " but parse succeeded.";
+ return;
+ }
+
+ EXPECT_EQ(UTF16ToUTF8(expected_error), UTF16ToUTF8(error)) << name;
+}
+
+}
+
+TEST(WebAppInfo, ParseFromDefinitionFileErrors) {
+ // Test one definition file with a JSON schema error, just to make sure we're
+ // correctly propagating those. We don't extensively test all the properties
+ // covered by the schema, since we assume JSON schema is working correctly.
+ ParseFromDefinitionAndExpectFailure(
+ "missing_name.json",
+ UTF8ToUTF16(std::string("name: ") +
+ JSONSchemaValidator::kObjectPropertyIsRequired));
+
+ ParseFromDefinitionAndExpectFailure(
+ "invalid_launch_url.json",
+ UTF8ToUTF16(WebApplicationInfo::kInvalidLaunchURL));
+
+ ParseFromDefinitionAndExpectFailure(
+ "invalid_urls.json",
+ UTF8ToUTF16(
+ JSONSchemaValidator::FormatErrorMessage(
+ WebApplicationInfo::kInvalidURL, "2")));
+}
+
+TEST(WebAppInfo, Minimal) {
+ scoped_ptr<WebApplicationInfo> web_app(
+ ParseFromDefinitionAndExpectSuccess("minimal.json"));
+
+ EXPECT_EQ(UTF8ToUTF16("hello"), web_app->title);
+ EXPECT_EQ(UTF8ToUTF16(""), web_app->description);
+ EXPECT_EQ(GURL("http://example.com/launch_url"), web_app->app_url);
+ EXPECT_EQ(0u, web_app->icons.size());
+ EXPECT_EQ(0u, web_app->urls.size());
+ EXPECT_EQ(0u, web_app->permissions.size());
+ EXPECT_EQ("", web_app->launch_container);
+}
+
+TEST(WebAppInfo, Full) {
+ scoped_ptr<WebApplicationInfo> web_app(
+ ParseFromDefinitionAndExpectSuccess("full.json"));
+
+ EXPECT_EQ(UTF8ToUTF16("hello"), web_app->title);
+ EXPECT_EQ(UTF8ToUTF16("This app is super awesome"), web_app->description);
+ EXPECT_EQ(GURL("http://example.com/launch_url"), web_app->app_url);
+ ASSERT_EQ(1u, web_app->icons.size());
+ EXPECT_EQ("http://example.com/16.png", web_app->icons[0].url.spec());
+ EXPECT_EQ(16, web_app->icons[0].width);
+ EXPECT_EQ(16, web_app->icons[0].height);
+ ASSERT_EQ(2u, web_app->urls.size());
+ EXPECT_EQ("http://example.com/foobar", web_app->urls[0].spec());
+ EXPECT_EQ("http://example.com/baz", web_app->urls[1].spec());
+ ASSERT_EQ(2u, web_app->permissions.size());
+ EXPECT_EQ("geolocation", web_app->permissions[0]);
+ EXPECT_EQ("notifications", web_app->permissions[1]);
+ EXPECT_EQ("panel", web_app->launch_container);
+}
+
+// Tests ParseIconSizes with various input.
+TEST(WebAppInfo, ParseIconSizes) {
+ struct TestData {
+ const char* input;
+ const bool expected_result;
+ const bool is_any;
+ const size_t expected_size_count;
+ const int width1;
+ const int height1;
+ const int width2;
+ const int height2;
+ } data[] = {
+ // Bogus input cases.
+ { "10", false, false, 0, 0, 0, 0, 0 },
+ { "10 10", false, false, 0, 0, 0, 0, 0 },
+ { "010", false, false, 0, 0, 0, 0, 0 },
+ { " 010 ", false, false, 0, 0, 0, 0, 0 },
+ { " 10x ", false, false, 0, 0, 0, 0, 0 },
+ { " x10 ", false, false, 0, 0, 0, 0, 0 },
+ { "any 10x10", false, false, 0, 0, 0, 0, 0 },
+ { "", false, false, 0, 0, 0, 0, 0 },
+ { "10ax11", false, false, 0, 0, 0, 0, 0 },
+
+ // Any.
+ { "any", true, true, 0, 0, 0, 0, 0 },
+ { " any", true, true, 0, 0, 0, 0, 0 },
+ { " any ", true, true, 0, 0, 0, 0, 0 },
+
+ // Sizes.
+ { "10x11", true, false, 1, 10, 11, 0, 0 },
+ { " 10x11 ", true, false, 1, 10, 11, 0, 0 },
+ { " 10x11 1x2", true, false, 2, 10, 11, 1, 2 },
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
+ bool is_any;
+ std::vector<gfx::Size> sizes;
+ bool result = web_apps::ParseIconSizes(ASCIIToUTF16(data[i].input), &sizes,
+ &is_any);
+ ASSERT_EQ(result, data[i].expected_result);
+ if (result) {
+ ASSERT_EQ(data[i].is_any, is_any);
+ ASSERT_EQ(data[i].expected_size_count, sizes.size());
+ if (sizes.size() > 0) {
+ ASSERT_EQ(data[i].width1, sizes[0].width());
+ ASSERT_EQ(data[i].height1, sizes[0].height());
+ }
+ if (sizes.size() > 1) {
+ ASSERT_EQ(data[i].width2, sizes[1].width());
+ ASSERT_EQ(data[i].height2, sizes[1].height());
+ }
+ }
+ }
+}