diff options
author | sidchat@google.com <sidchat@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-10 16:41:27 +0000 |
---|---|---|
committer | sidchat@google.com <sidchat@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-10 16:41:27 +0000 |
commit | 5c4266928220b850dc96474953f0b3a29739e0d3 (patch) | |
tree | 0981198815b7d83ab1ccdb0fc358db8637618c05 /chrome | |
parent | 479d5bc48969f6de924471de27638409db848229 (diff) | |
download | chromium_src-5c4266928220b850dc96474953f0b3a29739e0d3.zip chromium_src-5c4266928220b850dc96474953f0b3a29739e0d3.tar.gz chromium_src-5c4266928220b850dc96474953f0b3a29739e0d3.tar.bz2 |
Add getLanguage function to tab extension.
BUG=none
TEST=enable extensions using the toolstip.html code (added with this CL) and load pages in different languages. The corresponding language should appear in the bottom left after the page is loadedm or when the button is clicked, or when you navigate back to that tab after visiting some other tab.
Review URL: http://codereview.chromium.org/150062
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20378 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
23 files changed, 265 insertions, 9 deletions
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index a18a7a56..d5be2b8 100755 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -17,6 +17,7 @@ include_rules = [ "+media/audio", # Chrome's lightweight audio library. "+third_party/sqlite", "+third_party/libevent", # For the remote V8 debugging server + "+third_party/cld", "+v8/include", # Browser uses V8 to get the version and run the debugger. # FIXME: this should probably not be here, we need to find a better diff --git a/chrome/browser/extensions/extension_browsertests_misc.cc b/chrome/browser/extensions/extension_browsertests_misc.cc index f17e5d5..4b8fb8f 100644 --- a/chrome/browser/extensions/extension_browsertests_misc.cc +++ b/chrome/browser/extensions/extension_browsertests_misc.cc @@ -43,10 +43,10 @@ static ExtensionHost* FindHostWithPath(ExtensionProcessManager* manager, // Tests that toolstrips initializes properly and can run basic extension js. IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, Toolstrip) { - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("good").AppendASCII("Extensions") - .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") - .AppendASCII("1.0.0.0"))); + FilePath extension_test_data_dir = test_data_dir_.AppendASCII("good"). + AppendASCII("Extensions").AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj"). + AppendASCII("1.0.0.0"); + ASSERT_TRUE(LoadExtension(extension_test_data_dir)); // At this point, there should be two ExtensionHosts loaded because this // extension has two toolstrips. Find the one that is hosting toolstrip1.html. @@ -59,6 +59,22 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, Toolstrip) { ui_test_utils::ExecuteJavaScriptAndExtractBool( host->render_view_host(), L"", L"testTabsAPI()", &result); EXPECT_TRUE(result); + +#if defined(OS_WIN) + // Test for compact language detection API. First navigate to a (static) html + // file with a French sentence. Then, run the test API in toolstrip1.html to + // actually call the language detection API through the existing extension, + // and verify that the language returned is indeed French. + FilePath language_url = extension_test_data_dir.AppendASCII( + "french_sentence.html"); + ui_test_utils::NavigateToURL( + browser(), + GURL(language_url.ToWStringHack())); + + ui_test_utils::ExecuteJavaScriptAndExtractBool( + host->render_view_host(), L"", L"testTabsLanguageAPI()", &result); + EXPECT_TRUE(result); +#endif } // Tests that the ExtensionShelf initializes properly, notices that diff --git a/chrome/browser/extensions/extension_function.h b/chrome/browser/extensions/extension_function.h index 7798a19..ed2f9d0 100644 --- a/chrome/browser/extensions/extension_function.h +++ b/chrome/browser/extensions/extension_function.h @@ -93,7 +93,14 @@ class AsyncExtensionFunction : public ExtensionFunction { virtual void SetArgs(const std::string& args); virtual const std::string GetResult(); virtual const std::string GetError() { return error_; } - virtual void Run() = 0; + virtual void Run() { + if (!RunImpl()) + SendResponse(false); + } + + // Derived classes should implement this method to do their work and return + // success/failure. + virtual bool RunImpl() = 0; protected: void SendResponse(bool success); @@ -107,7 +114,7 @@ class AsyncExtensionFunction : public ExtensionFunction { Value* args_; // The result of the API. This should be populated by the derived class before - // Run() returns. + // SendResponse() is called. scoped_ptr<Value> result_; // Any detailed error from the API. This should be populated by the derived diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 70cb59e..8238595 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -98,6 +98,8 @@ void FactoryRegistry::ResetFunctions() { &NewExtensionFunction<MoveTabFunction>; factories_[tabs::kRemoveTabFunction] = &NewExtensionFunction<RemoveTabFunction>; + factories_[tabs::kGetTabLanguageFunction] = + &NewExtensionFunction<GetTabLanguageFunction>; // Page Actions. factories_[page_actions::kEnablePageActionFunction] = diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index b92677d..57248d7 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -615,6 +615,52 @@ bool RemoveTabFunction::RunImpl() { return true; } +bool GetTabLanguageFunction::RunImpl() { + int tab_id = 0; + Browser* browser = NULL; + TabContents* contents = NULL; + + // If |tab_id| is specified, look for it. Otherwise default to selected tab + // in the current window. + if (!args_->IsType(Value::TYPE_NULL)) { + EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&tab_id)); + if (!GetTabById(tab_id, profile(), &browser, NULL, &contents, NULL, + &error_)) { + return false; + } + if (!browser || !contents) + return false; + } else { + browser = dispatcher()->GetBrowser(); + if (!browser) + return false; + contents = browser->tabstrip_model()->GetSelectedTabContents(); + if (!contents) + return false; + } + + // Figure out what language |contents| contains. This sends an async call via + // the browser to the renderer to determine the language of the tab the + // renderer has. The renderer sends back the language of the tab after the + // tab loads (it may be delayed) to the browser, which in turn notifies this + // object that the language has been received. + contents->GetPageLanguage(); + registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED, + NotificationService::AllSources()); + AddRef(); // balanced in Observe() + return true; +} + +void GetTabLanguageFunction::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::TAB_LANGUAGE_DETERMINED); + std::string language(*Details<std::string>(details).ptr()); + result_.reset(Value::CreateStringValue(language.c_str())); + SendResponse(true); + Release(); // balanced in Run() +} + // static helpers // if |populate| is true, each window gets a list property |tabs| which contains diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h index cb8b3d3..1b7c307 100644 --- a/chrome/browser/extensions/extension_tabs_module.h +++ b/chrome/browser/extensions/extension_tabs_module.h @@ -8,6 +8,8 @@ #include <string> #include "chrome/browser/extensions/extension_function.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_registrar.h" class Browser; class DictionaryValue; @@ -86,5 +88,15 @@ class MoveTabFunction : public SyncExtensionFunction { class RemoveTabFunction : public SyncExtensionFunction { virtual bool RunImpl(); }; +class GetTabLanguageFunction : public AsyncExtensionFunction, + public NotificationObserver { + virtual bool RunImpl(); + + private: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + NotificationRegistrar registrar_; +}; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_TABS_MODULE_H__ diff --git a/chrome/browser/extensions/extension_tabs_module_constants.cc b/chrome/browser/extensions/extension_tabs_module_constants.cc index 049f36a..69676e7 100755 --- a/chrome/browser/extensions/extension_tabs_module_constants.cc +++ b/chrome/browser/extensions/extension_tabs_module_constants.cc @@ -56,6 +56,6 @@ const char kCreateTabFunction[] = "CreateTab"; const char kUpdateTabFunction[] = "UpdateTab"; const char kMoveTabFunction[] = "MoveTab"; const char kRemoveTabFunction[] = "RemoveTab"; - +const char kGetTabLanguageFunction[] = "GetTabLanguage"; } // namespace extension_tabs_module_constants diff --git a/chrome/browser/extensions/extension_tabs_module_constants.h b/chrome/browser/extensions/extension_tabs_module_constants.h index 10abcf7..4df84c8 100755 --- a/chrome/browser/extensions/extension_tabs_module_constants.h +++ b/chrome/browser/extensions/extension_tabs_module_constants.h @@ -64,6 +64,7 @@ extern const char kCreateTabFunction[]; extern const char kUpdateTabFunction[]; extern const char kMoveTabFunction[]; extern const char kRemoveTabFunction[]; +extern const char kGetTabLanguageFunction[]; }; // namespace extension_tabs_module_constants diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 8e8f161..b41c04c 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -41,6 +41,8 @@ #if defined(OS_WIN) // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. #include "chrome/browser/browser_accessibility_manager.h" +// TODO(port): The compact language detection library works only for Windows. +#include "third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/win/cld_unicodetext.h" #endif using base::TimeDelta; @@ -410,6 +412,10 @@ void RenderViewHost::StopFinding(bool clear_selection) { Send(new ViewMsg_StopFinding(routing_id(), clear_selection)); } +void RenderViewHost::GetPageLanguage() { + Send(new ViewMsg_DeterminePageText(routing_id())); +} + void RenderViewHost::Zoom(PageZoom::Function function) { Send(new ViewMsg_Zoom(routing_id(), function)); } @@ -726,6 +732,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_DidFailProvisionalLoadWithError, OnMsgDidFailProvisionalLoadWithError) IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnMsgFindReply) + IPC_MESSAGE_HANDLER(ViewMsg_DeterminePageText_Reply, + OnDeterminePageTextReply) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFavIconURL, OnMsgUpdateFavIconURL) IPC_MESSAGE_HANDLER(ViewHostMsg_DidDownloadFavIcon, OnMsgDidDownloadFavIcon) IPC_MESSAGE_HANDLER(ViewHostMsg_ContextMenu, OnMsgContextMenu) @@ -1058,6 +1066,21 @@ void RenderViewHost::OnMsgFindReply(int request_id, Send(new ViewMsg_FindReplyACK(routing_id())); } +void RenderViewHost::OnDeterminePageTextReply( + const std::wstring& page_text) { +#if defined(OS_WIN) // Only for windows. + int num_languages = 0; + bool is_reliable = false; + const char* language_char = LanguageName(DetectLanguageOfUnicodeText( + page_text.c_str(), true, &is_reliable, &num_languages, NULL)); + std::string language(language_char); + NotificationService::current()->Notify( + NotificationType::TAB_LANGUAGE_DETERMINED, + Source<RenderViewHost>(this), + Details<std::string>(&language)); +#endif +} + void RenderViewHost::OnMsgUpdateFavIconURL(int32 page_id, const GURL& icon_url) { RenderViewHostDelegate::FavIcon* favicon_delegate = diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index de4c70c..a43c5a2 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -206,6 +206,12 @@ class RenderViewHost : public RenderWidgetHost, // clear the selection on the focused frame. void StopFinding(bool clear_selection); + // Get the most probable language of the text content in the tab. This sends + // a message to the render view to get the content of the page as text. The + // caller gets the language via the NotificationService by registering to the + // NotificationType TAB_LANGUAGE_DETERMINED. + void GetPageLanguage(); + // Change the zoom level of a page. void Zoom(PageZoom::Function function); @@ -460,6 +466,7 @@ class RenderViewHost : public RenderWidgetHost, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update); + void OnDeterminePageTextReply(const std::wstring& tab_text); void OnMsgUpdateFavIconURL(int32 page_id, const GURL& icon_url); void OnMsgDidDownloadFavIcon(int id, const GURL& image_url, diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 001be58..9832fa4 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -976,6 +976,10 @@ void TabContents::StopFinding(bool clear_selection) { render_view_host()->StopFinding(clear_selection); } +void TabContents::GetPageLanguage() { + render_view_host()->GetPageLanguage(); +} + void TabContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, bool success, const std::wstring& prompt) { diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 99e99a1..e974f8e 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -493,6 +493,9 @@ class TabContents : public PageNavigator, return last_search_result_; } + // Get the most probable language of the text content in the tab. + void GetPageLanguage(); + // Misc state & callbacks ---------------------------------------------------- // Set whether the contents should block javascript message boxes or not. diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index d2c8fca..93cbbaf 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -204,6 +204,10 @@ class NotificationType { // is the InfoBubble. INFO_BUBBLE_CREATED, + // Sent after a call to RenderViewHost::DeterminePageLanguage. The details + // are Details<std::string> and the source is Source<RenderViewHost>. + TAB_LANGUAGE_DETERMINED, + // The user has changed the browser theme. BROWSER_THEME_CHANGED, diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 5205bf6..ee3d154 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -191,6 +191,14 @@ IPC_BEGIN_MESSAGES(View) string16 /* search_text */, WebKit::WebFindOptions) + // Send from the browser to the rendered to get the text content of the page. + IPC_MESSAGE_ROUTED0(ViewMsg_DeterminePageText) + + // Send from the renderer to the browser to return the text content of the + // page. + IPC_MESSAGE_ROUTED1(ViewMsg_DeterminePageText_Reply, + std::wstring /* the language */) + // Sent when the headers are available for a resource request. IPC_MESSAGE_ROUTED2(ViewMsg_Resource_ReceivedResponse, int /* request_id */, diff --git a/chrome/renderer/extensions/extension_api_client_unittest.cc b/chrome/renderer/extensions/extension_api_client_unittest.cc index 663a892..0cb2876 100644 --- a/chrome/renderer/extensions/extension_api_client_unittest.cc +++ b/chrome/renderer/extensions/extension_api_client_unittest.cc @@ -275,6 +275,24 @@ TEST_F(ExtensionAPIClientTest, GetTab) { "GetTab", "2"); } +#if defined(OS_WIN) +TEST_F(ExtensionAPIClientTest, GetTabLanguage) { + ExpectJsFail("chrome.tabs.getLanguage(32, function(){}, 20);", + "Uncaught Error: Too many arguments."); + + ExpectJsFail("chrome.tabs.getLanguage('abc', function(){});", + "Uncaught Error: Invalid value for argument 0. " + "Expected 'integer' but got 'string'."); + + ExpectJsFail("chrome.tabs.getLanguage(1, 1);", + "Uncaught Error: Invalid value for argument 1. " + "Expected 'function' but got 'integer'."); + + ExpectJsPass("chrome.tabs.getLanguage(null, function(){})", + "GetTabLanguage", "null"); +} +#endif + TEST_F(ExtensionAPIClientTest, GetSelectedTab) { ExpectJsFail("chrome.tabs.getSelected(32, function(){}, 20);", "Uncaught Error: Too many arguments."); diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 5f72843..f08ad79e 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -192,7 +192,8 @@ RenderView::RenderView(RenderThreadBase* render_thread) popup_notification_visible_(false), delay_seconds_for_form_state_sync_(kDefaultDelaySecondsForFormStateSync), preferred_width_(0), - send_preferred_width_changes_(false) { + send_preferred_width_changes_(false), + determine_page_text_after_loading_stops_(false) { } RenderView::~RenderView() { @@ -355,6 +356,7 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt) IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand) IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind) + IPC_MESSAGE_HANDLER(ViewMsg_DeterminePageText, OnDeterminePageText) IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom) IPC_MESSAGE_HANDLER(ViewMsg_InsertText, OnInsertText) IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding) @@ -497,6 +499,12 @@ void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) { Send(new ViewHostMsg_PageContents(url, load_id, contents)); } + // Send over text content of this page to the browser. + if (determine_page_text_after_loading_stops_) { + determine_page_text_after_loading_stops_ = false; + Send(new ViewMsg_DeterminePageText_Reply(routing_id_, contents)); + } + // thumbnail SendThumbnail(); } @@ -2199,6 +2207,23 @@ void RenderView::OnFind(int request_id, } } +void RenderView::OnDeterminePageText() { + if (!is_loading_) { + if (!webview()) + return; + WebFrame* main_frame = webview()->GetMainFrame(); + std::wstring contents; + CaptureText(main_frame, &contents); + Send(new ViewMsg_DeterminePageText_Reply(routing_id_, contents)); + determine_page_text_after_loading_stops_ = false; + return; + } + + // We set |determine_page_text_after_loading_stops_| true here so that, + // after page has been loaded completely, the text in the page is captured. + determine_page_text_after_loading_stops_ = true; +} + void RenderView::ReportFindInPageMatchCount(int count, int request_id, bool final_update) { // If we have a message that has been queued up, then we should just replace diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index bc44ac9..24621a4 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -478,6 +478,7 @@ class RenderView : public RenderWidget, void OnSetupDevToolsClient(); void OnCancelDownload(int32 download_id); void OnFind(int request_id, const string16&, const WebKit::WebFindOptions&); + void OnDeterminePageText(); void OnZoom(int function); void OnInsertText(const string16& text); void OnSetPageEncoding(const std::wstring& encoding_name); @@ -778,6 +779,9 @@ class RenderView : public RenderWidget, // The text selection the last time DidChangeSelection got called. std::string last_selection_; + // Set to true if request for capturing page text has been made. + bool determine_page_text_after_loading_stops_; + // Holds state pertaining to a navigation that we initiated. This is held by // the WebDataSource::ExtraData attribute. We use pending_navigation_state_ // as a temporary holder for the state until the WebDataSource corresponding diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd index ed66407..8acec84 100644 --- a/chrome/renderer/renderer_resources.grd +++ b/chrome/renderer/renderer_resources.grd @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- This comment is only here because changes to resources are not picked up -without changes to the corresponding grd file. mp12 --> +without changes to the corresponding grd file. mp13 --> <grit latest_public_release="0" current_release="1"> <outputs> <output filename="grit/renderer_resources.h" type="rc_header"> diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index f3893fb..51756d0 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -24,6 +24,7 @@ var chrome = chrome || {}; native function UpdateTab(); native function MoveTab(); native function RemoveTab(); + native function GetTabLanguage(); native function EnablePageAction(); native function DisablePageAction(); native function GetBookmarks(); @@ -313,6 +314,16 @@ var chrome = chrome || {}; chrome.types.optFun ]; + chrome.tabs.getLanguage = function(tabId, callback) { + validate(arguments, arguments.callee.params); + sendRequest(GetTabLanguage, tabId, callback); + }; + + chrome.tabs.getLanguage.params = [ + chrome.types.optPInt, + chrome.types.optFun + ]; + // Sends ({Tab}). // Will *NOT* be followed by tab-attached - it is implied. // *MAY* be followed by tab-selection-changed. diff --git a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/french_sentence.html b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/french_sentence.html new file mode 100644 index 0000000..3d3c2e8 --- /dev/null +++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/french_sentence.html @@ -0,0 +1,12 @@ +<!-- +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> +<body> +<p> +Ceci est une phrase complète est en français, rédigé en anglais puis traduits +</p> +</body> +</html> diff --git a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html index d0a1f21..cf87fe5 100644 --- a/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html +++ b/chrome/test/data/extensions/good/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/toolstrip1.html @@ -8,6 +8,16 @@ function testTabsAPI() { window.domAutomationController.send(tabs.length == 1); }); } + +// This function is called from the C++ browser test. It tests the getLanguage +// function to make sure it can be used as an extension API. This will pass if +// the browser navigates to a page in French language before this is called. +function testTabsLanguageAPI() { + chrome.tabs.getLanguage(null, function(language) { + window.domAutomationController.send(language == 'FRENCH'); + }); +} + </script> <select> <option>one</option> diff --git a/chrome/test/data/extensions/samples/cld/manifest.json b/chrome/test/data/extensions/samples/cld/manifest.json new file mode 100644 index 0000000..c0f20f2 --- /dev/null +++ b/chrome/test/data/extensions/samples/cld/manifest.json @@ -0,0 +1,6 @@ +{ + "name": "CLD", + "description": "Returns language of a tab", + "version": "0.1", + "toolstrips": ["toolstrip.html"] +} diff --git a/chrome/test/data/extensions/samples/cld/toolstrip.html b/chrome/test/data/extensions/samples/cld/toolstrip.html new file mode 100644 index 0000000..726a030 --- /dev/null +++ b/chrome/test/data/extensions/samples/cld/toolstrip.html @@ -0,0 +1,36 @@ +<!-- +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> + +var selectedId = -1; +function refreshLanguage() { + console.log("refeshing..."); + chrome.tabs.getLanguage(null, function(language) { + document.getElementById("languageDiv").innerHTML = language; + }); +} + +chrome.tabs.onUpdated.addListener(function(tabId, props) { + console.log("updated: " + tabId); + if (prop.status == "complete" && tabId == selectedId) + refreshLanguage(); +}); + +chrome.tabs.onSelectionChanged.addListener(function(tabId, props) { + console.log("selection: " + tabId); + selectedId = tabId; + refreshLanguage(); +}); + </script> + </head> + <body onload="refreshLanguage();"> + <div id="languageDiv" class="toolstrip-button" onclick="refreshLanguage();"> + </div> + </body> +</html>
\ No newline at end of file |