Commit 198bcfe9 authored by xji@chromium.org's avatar xji@chromium.org

Added chrome.i18n extension API.

The API proposal doc is 
http://sites.google.com/a/chromium.org/dev/developers/design-documents/extensions/i18n-api

This CL only adds the getter of accept languages: 
chrome.i18n.getAcceptLanguages().

The setter of accept languages will be added in a separate CL.

BUG=http://crbug.com/14574
TEST=TEST=There is an extension in chrome\test\data\extensions\samples\i18n.
Load this extension. It creates a toolstrip button.  Click this button, you
should get chrome's accept languages.
Review URL: http://codereview.chromium.org/174116

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25810 0039d316-1c4b-4281-b951-d872f2087c98
parent bcc9ae95
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "chrome/browser/extensions/extension_bookmarks_module.h" #include "chrome/browser/extensions/extension_bookmarks_module.h"
#include "chrome/browser/extensions/extension_bookmarks_module_constants.h" #include "chrome/browser/extensions/extension_bookmarks_module_constants.h"
#include "chrome/browser/extensions/extension_function.h" #include "chrome/browser/extensions/extension_function.h"
#include "chrome/browser/extensions/extension_i18n_api.h"
#include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extension_page_actions_module.h" #include "chrome/browser/extensions/extension_page_actions_module.h"
#include "chrome/browser/extensions/extension_page_actions_module_constants.h" #include "chrome/browser/extensions/extension_page_actions_module_constants.h"
...@@ -69,6 +70,7 @@ void FactoryRegistry::ResetFunctions() { ...@@ -69,6 +70,7 @@ void FactoryRegistry::ResetFunctions() {
// Register all functions here. // Register all functions here.
namespace bookmarks = extension_bookmarks_module_constants; namespace bookmarks = extension_bookmarks_module_constants;
namespace i18n = extension_i18n_api_functions;
namespace page_actions = extension_page_actions_module_constants; namespace page_actions = extension_page_actions_module_constants;
namespace tabs = extension_tabs_module_constants; namespace tabs = extension_tabs_module_constants;
namespace test = extension_test_api_functions; namespace test = extension_test_api_functions;
...@@ -142,6 +144,10 @@ void FactoryRegistry::ResetFunctions() { ...@@ -142,6 +144,10 @@ void FactoryRegistry::ResetFunctions() {
factories_[toolstrip::kCollapseFunction] = factories_[toolstrip::kCollapseFunction] =
&NewExtensionFunction<ToolstripCollapseFunction>; &NewExtensionFunction<ToolstripCollapseFunction>;
// I18N.
factories_[i18n::kGetAcceptLanguagesFunction] =
&NewExtensionFunction<GetAcceptLanguagesFunction>;
// Test. // Test.
factories_[test::kPassFunction] = factories_[test::kPassFunction] =
&NewExtensionFunction<ExtensionTestPassFunction>; &NewExtensionFunction<ExtensionTestPassFunction>;
......
// 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.
#include "chrome/browser/extensions/extension_i18n_api.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"
namespace extension_i18n_api_functions {
const char kGetAcceptLanguagesFunction[] = "i18n.getAcceptLanguages";
} // namespace extension_i18n_api_functions
namespace {
// Errors.
const char kEmptyAcceptLanguagesError[] = "accept-languages is empty.";
} // namespace
bool GetAcceptLanguagesFunction::RunImpl() {
std::wstring acceptLanguages =
profile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
// Currently, there are 2 ways to set browser's accept-languages: through UI
// or directly modify the preference file. The accept-languages set through
// UI is guranteed to be valid, and the accept-languages string returned from
// profile()->GetPrefs()->GetString(prefs::kAcceptLanguages) is guranteed to
// be valid and well-formed, which means each accept-langauge is a valid
// code, and accept-languages are seperatd by "," without surrrounding
// spaces. But we do not do any validation (either the format or the validity
// of the language code) on accept-languages set through editing preference
// file directly. So, here, we're adding extra checks to be resistant to
// crashes caused by data corruption.
result_.reset(new ListValue());
if (acceptLanguages.empty()) {
error_ = kEmptyAcceptLanguagesError;
return false;
}
size_t begin = 0;
size_t end;
std::wstring acceptLang;
while (1) {
end = acceptLanguages.find(',', begin);
if (end > begin) {
// Guard against a malformed value with multiple "," in a row.
acceptLang = acceptLanguages.substr(begin, end - begin);
static_cast<ListValue*>(result_.get())->
Append(Value::CreateStringValue(acceptLang));
}
begin = end + 1;
// 'begin >= acceptLanguages.length()' to guard against a value
// ending with ','.
if (end == std::wstring::npos || begin >= acceptLanguages.length())
break;
}
if (static_cast<ListValue*>(result_.get())->GetSize() == 0) {
error_ = kEmptyAcceptLanguagesError;
return false;
}
return true;
}
// 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_BROWSER_EXTENSIONS_EXTENSION_I18N_API_H__
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_I18N_API_H__
#include "chrome/browser/extensions/extension_function.h"
namespace extension_i18n_api_functions {
extern const char kGetAcceptLanguagesFunction[];
}; // namespace extension_i18n_api_functions
class GetAcceptLanguagesFunction : public SyncExtensionFunction {
virtual bool RunImpl();
};
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_I18N_API_H__
// 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.
#include "chrome/browser/extensions/extension_apitest.h"
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, I18N) {
ASSERT_TRUE(RunExtensionTest("i18n")) << message_;
}
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
'browser/extensions/extension_startup_unittest.cc', 'browser/extensions/extension_startup_unittest.cc',
'browser/extensions/extension_storage_apitest.cc', 'browser/extensions/extension_storage_apitest.cc',
'browser/extensions/extension_tabs_apitest.cc', 'browser/extensions/extension_tabs_apitest.cc',
'browser/extensions/extension_i18n_apitest.cc',
'browser/views/browser_views_accessibility_browsertest.cc', 'browser/views/browser_views_accessibility_browsertest.cc',
'browser/views/find_bar_win_browsertest.cc', 'browser/views/find_bar_win_browsertest.cc',
# TODO(jam): http://crbug.com/15101 These tests fail on Linux and Mac. # TODO(jam): http://crbug.com/15101 These tests fail on Linux and Mac.
...@@ -1140,6 +1141,8 @@ ...@@ -1140,6 +1141,8 @@
'browser/extensions/extension_message_service.h', 'browser/extensions/extension_message_service.h',
'browser/extensions/extension_browser_event_router.cc', 'browser/extensions/extension_browser_event_router.cc',
'browser/extensions/extension_browser_event_router.h', 'browser/extensions/extension_browser_event_router.h',
'browser/extensions/extension_i18n_api.cc',
'browser/extensions/extension_i18n_api.h',
'browser/extensions/extension_page_actions_module.cc', 'browser/extensions/extension_page_actions_module.cc',
'browser/extensions/extension_page_actions_module.h', 'browser/extensions/extension_page_actions_module.h',
'browser/extensions/extension_page_actions_module_constants.cc', 'browser/extensions/extension_page_actions_module_constants.cc',
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- This comment is only here because changes to resources are not picked up <!-- This comment is only here because changes to resources are not picked up
without changes to the corresponding grd file. rw2 --> without changes to the corresponding grd file. xji -->
<grit latest_public_release="0" current_release="1"> <grit latest_public_release="0" current_release="1">
<outputs> <outputs>
<output filename="grit/common_resources.h" type="rc_header"> <output filename="grit/common_resources.h" type="rc_header">
......
...@@ -1018,6 +1018,28 @@ ...@@ -1018,6 +1018,28 @@
], ],
"events": [] "events": []
}, },
{
"namespace": "i18n",
"types": [],
"functions": [
{
"name": "getAcceptLanguages",
"type": "function",
"description": "Get accept languages of browser",
"parameters": [
{
"type": "function",
"name": "callback",
"parameters": [
{"name": "languages", "type": "array", "items": {"type": "string"}, "description": "Array of the accept languages of the browser, such as en-US,en,zh-CN"}
]
}
]
}
],
"events": [
]
},
{ {
"namespace": "devtools", "namespace": "devtools",
"types": [ "types": [
......
This diff is collapsed.
...@@ -588,3 +588,19 @@ TEST_F(ExtensionAPIClientTest, CollapseToolstrip) { ...@@ -588,3 +588,19 @@ TEST_F(ExtensionAPIClientTest, CollapseToolstrip) {
"Uncaught Error: Invalid value for argument 1. " "Uncaught Error: Invalid value for argument 1. "
"Expected 'function' but got 'integer'."); "Expected 'function' but got 'integer'.");
} }
// I18N API
TEST_F(ExtensionAPIClientTest, GetAcceptLanguages) {
ExpectJsFail("chrome.i18n.getAcceptLanguages(32, function(){})",
"Uncaught Error: Too many arguments.");
ExpectJsFail("chrome.i18n.getAcceptLanguages()",
"Uncaught Error: Parameter 0 is required.");
ExpectJsFail("chrome.i18n.getAcceptLanguages('abc')",
"Uncaught Error: Invalid value for argument 0. "
"Expected 'function' but got 'string'.");
ExpectJsPass("chrome.i18n.getAcceptLanguages(function(){})",
"i18n.getAcceptLanguages", "null");
}
{
"name": "chrome.i18n",
"version": "0.1",
"description": "end-to-end browser test for chrome.i18n API",
"background_page": "test.html"
}
// i18n api test
// browser_tests.exe --gtest_filter=ExtensionApiTest.I18N
var testCallback = chrome.test.testCallback;
chrome.test.runTests([
function getAcceptLanguages() {
chrome.i18n.getAcceptLanguages(chrome.test.callbackPass(function(results) {
chrome.test.assertEq(results.length, 2);
chrome.test.assertEq(results[0], "en-US");
chrome.test.assertEq(results[1], "en");
}));
}
]);
{
"name": "AcceptLanguage",
"description": "Returns accept languages of the browser",
"version": "0.1",
"toolstrips": ["toolstrip.html"]
}
<!--
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.
-->
<html>
<head>
<script>
function getAcceptLanguages() {
chrome.i18n.getAcceptLanguages(function(languageList) {
var languages = "";
for (var i = 0; i < languageList.length; i++) {
if (i == languageList.length - 1)
languages += languageList[i];
else
languages += languageList[i] + ",";
}
document.getElementById("languageSpan").innerHTML = languages;
})
}
</script>
</head>
<body>
<div class="toolstrip-button" onclick="getAcceptLanguages();">
<span id="languageSpan">GetAcceptLanguage</span>
</div>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment