diff options
author | jered@chromium.org <jered@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-02 18:39:53 +0000 |
---|---|---|
committer | jered@chromium.org <jered@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-02 18:39:53 +0000 |
commit | 9959eeb989af5ebebfa28a37284446c528c7fecf (patch) | |
tree | 2887bcb72a91576b1d5d12ee8fa14541e9a2d806 /chrome | |
parent | 065499f70249cd46f7c04e727e90207179e39408 (diff) | |
download | chromium_src-9959eeb989af5ebebfa28a37284446c528c7fecf.zip chromium_src-9959eeb989af5ebebfa28a37284446c528c7fecf.tar.gz chromium_src-9959eeb989af5ebebfa28a37284446c528c7fecf.tar.bz2 |
MV iframes: Add searchbox support for querying MV data.
BUG=228940
TEST=Make sure existing Shadow DOM NTP still works just fine.
Review URL: https://chromiumcodereview.appspot.com/14592003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197948 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/renderer/resources/extensions/searchbox_api.js | 18 | ||||
-rw-r--r-- | chrome/renderer/searchbox/searchbox_extension.cc | 147 |
2 files changed, 114 insertions, 51 deletions
diff --git a/chrome/renderer/resources/extensions/searchbox_api.js b/chrome/renderer/resources/extensions/searchbox_api.js index 7e74460..af7e4f1 100644 --- a/chrome/renderer/resources/extensions/searchbox_api.js +++ b/chrome/renderer/resources/extensions/searchbox_api.js @@ -108,6 +108,7 @@ if (!chrome.embeddedSearch) { native function ShowBars(); native function HideBars(); native function GetSuggestionData(); + native function GetMostVisitedItemData(); function SafeWrapSuggestion(restrictedText) { return SafeWrap(restrictedText, 22); @@ -239,6 +240,12 @@ if (!chrome.embeddedSearch) { return GetSuggestionData(restrictedId); }; + // This method is restricted to chrome-search://most-visited pages by + // checking the invoking context's origin in searchbox_extension.cc. + this.getMostVisitedItemData = function(restrictedId) { + return GetMostVisitedItemData(restrictedId); + }; + this.setSuggestions = function(text) { SetSuggestions(text); }; @@ -322,11 +329,16 @@ if (!chrome.embeddedSearch) { for (var i = 0, item; item = mostVisitedItems[i]; ++i) { var title = escapeHTML(item.title); var domain = escapeHTML(item.domain); + // TODO(jered): Delete these Shadow DOM elements once the + // Google-provided NTP no longer depends on them. item.titleElement = SafeWrapMostVisited(title, 140, item.direction); item.domainElement = SafeWrapMostVisited(domain, 123); - delete item.title; - delete item.domain; - delete item.direction; + // These properties are private data and should not be returned to + // the page. They are only accessible via getMostVisitedItemData(). + item.url = null; + item.title = null; + item.domain = null; + item.direction = null; } return mostVisitedItems; } diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index 7eb3aca..29b77a9 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc @@ -163,6 +163,69 @@ v8::Handle<v8::Object> GenerateNativeSuggestion( return obj; } +// Populates a Javascript MostVisitedItem object from |mv_item|. +// NOTE: Includes "url", "title" and "domain" which are private data, so should +// not be returned to the Instant page. These should be erased before returning +// the object. See GetMostVisitedItemsWrapper() in searchbox_api.js. +v8::Handle<v8::Object> GenerateMostVisitedItem( + InstantRestrictedID restricted_id, + const InstantMostVisitedItem &mv_item) { + // We set the "dir" attribute of the title, so that in RTL locales, a LTR + // title is rendered left-to-right and truncated from the right. For + // example, the title of http://msdn.microsoft.com/en-us/default.aspx is + // "MSDN: Microsoft developer network". In RTL locales, in the New Tab + // page, if the "dir" of this title is not specified, it takes Chrome UI's + // directionality. So the title will be truncated as "soft developer + // network". Setting the "dir" attribute as "ltr" renders the truncated + // title as "MSDN: Microsoft D...". As another example, the title of + // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the + // title will be rendered as "!Yahoo" if its "dir" attribute is not set to + // "ltr". + std::string direction; + if (base::i18n::StringContainsStrongRTLChars(mv_item.title)) + direction = kRTLHtmlTextDirection; + else + direction = kLTRHtmlTextDirection; + + string16 title = mv_item.title; + if (title.empty()) + title = UTF8ToUTF16(mv_item.url.spec()); + + v8::Handle<v8::Object> obj = v8::Object::New(); + obj->Set(v8::String::New("rid"), v8::Int32::New(restricted_id)); + obj->Set(v8::String::New("thumbnailUrl"), + GenerateThumbnailURL(restricted_id)); + obj->Set(v8::String::New("faviconUrl"), + GenerateFaviconURL(restricted_id)); + obj->Set(v8::String::New("title"), UTF16ToV8String(title)); + obj->Set(v8::String::New("domain"), UTF8ToV8String(mv_item.url.host())); + obj->Set(v8::String::New("direction"), UTF8ToV8String(direction)); + obj->Set(v8::String::New("url"), UTF8ToV8String(mv_item.url.spec())); + return obj; +} + +// Returns the render view for the current JS context if it matches |origin|, +// otherwise returns NULL. Used to restrict methods that access suggestions and +// most visited data to pages with origin chrome-search://most-visited and +// chrome-search://suggestions. +content::RenderView* GetRenderViewWithCheckedOrigin(const GURL& origin) { + WebKit::WebFrame* webframe = WebKit::WebFrame::frameForCurrentContext(); + if (!webframe) + return NULL; + WebKit::WebView* webview = webframe->view(); + if (!webview) + return NULL; // Can happen during closing. + content::RenderView* render_view = content::RenderView::FromWebView(webview); + if (!render_view) + return NULL; + + GURL url(webframe->document().url()); + if (url.GetOrigin() != origin.GetOrigin()) + return NULL; + + return render_view; +} + } // namespace namespace internal { // for testing. @@ -508,10 +571,17 @@ class SearchBoxExtensionWrapper : public v8::Extension { // event is fired to notify the page. static v8::Handle<v8::Value> HideBars(const v8::Arguments& args); - // Gets the raw data for a suggestion including its content. Only callable - // by chrome-search://suggestion pages. + // Gets the raw data for a suggestion including its content. + // GetRenderViewWithCheckedOrigin() enforces that only code in the origin + // chrome-search://suggestion can call this function. static v8::Handle<v8::Value> GetSuggestionData(const v8::Arguments& args); + // Gets the raw data for a most visited item including its raw URL. + // GetRenderViewWithCheckedOrigin() enforces that only code in the origin + // chrome-search://most-visited can call this function. + static v8::Handle<v8::Value> GetMostVisitedItemData( + const v8::Arguments& args); + private: DISALLOW_COPY_AND_ASSIGN(SearchBoxExtensionWrapper); }; @@ -593,6 +663,8 @@ v8::Handle<v8::FunctionTemplate> SearchBoxExtensionWrapper::GetNativeFunction( return v8::FunctionTemplate::New(HideBars); if (name->Equals(v8::String::New("GetSuggestionData"))) return v8::FunctionTemplate::New(GetSuggestionData); + if (name->Equals(v8::String::New("GetMostVisitedItemData"))) + return v8::FunctionTemplate::New(GetMostVisitedItemData); return v8::Handle<v8::FunctionTemplate>(); } @@ -1148,40 +1220,8 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( search_box->GetMostVisitedItems(&instant_mv_items); v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); for (size_t i = 0; i < instant_mv_items.size(); ++i) { - // We set the "dir" attribute of the title, so that in RTL locales, a LTR - // title is rendered left-to-right and truncated from the right. For - // example, the title of http://msdn.microsoft.com/en-us/default.aspx is - // "MSDN: Microsoft developer network". In RTL locales, in the New Tab - // page, if the "dir" of this title is not specified, it takes Chrome UI's - // directionality. So the title will be truncated as "soft developer - // network". Setting the "dir" attribute as "ltr" renders the truncated - // title as "MSDN: Microsoft D...". As another example, the title of - // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the - // title will be rendered as "!Yahoo" if its "dir" attribute is not set to - // "ltr". - const InstantMostVisitedItem& mv_item = instant_mv_items[i].second; - std::string direction; - if (base::i18n::StringContainsStrongRTLChars(mv_item.title)) - direction = kRTLHtmlTextDirection; - else - direction = kLTRHtmlTextDirection; - - string16 title = mv_item.title; - if (title.empty()) - title = UTF8ToUTF16(mv_item.url.spec()); - - InstantRestrictedID restricted_id = instant_mv_items[i].first; - v8::Handle<v8::Object> item = v8::Object::New(); - item->Set(v8::String::New("rid"), v8::Int32::New(restricted_id)); - item->Set(v8::String::New("thumbnailUrl"), - GenerateThumbnailURL(restricted_id)); - item->Set(v8::String::New("faviconUrl"), - GenerateFaviconURL(restricted_id)); - item->Set(v8::String::New("title"), UTF16ToV8String(title)); - item->Set(v8::String::New("domain"), UTF8ToV8String(mv_item.url.host())); - item->Set(v8::String::New("direction"), UTF8ToV8String(direction)); - - v8_mv_items->Set(i, item); + v8_mv_items->Set(i, GenerateMostVisitedItem(instant_mv_items[i].first, + instant_mv_items[i].second)); } return v8_mv_items; } @@ -1292,20 +1332,10 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::HideBars( // static v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSuggestionData( const v8::Arguments& args) { - WebKit::WebFrame* webframe = WebKit::WebFrame::frameForCurrentContext(); - if (!webframe) return v8::Undefined(); - WebKit::WebView* webview = webframe->view(); - if (!webview) return v8::Undefined(); // Can happen during closing. - content::RenderView* render_view = content::RenderView::FromWebView(webview); + content::RenderView* render_view = GetRenderViewWithCheckedOrigin( + GURL(chrome::kChromeSearchSuggestionUrl)); if (!render_view) return v8::Undefined(); - // If origin does not match, return undefined. - GURL url(webframe->document().url()); - if (!url.SchemeIs(chrome::kChromeSearchScheme) || - url.host() != chrome::kChromeSearchSuggestionHost) { - return v8::Undefined(); - } - // Need an rid argument. if (args.Length() < 1 || !args[0]->IsNumber()) return v8::Undefined(); @@ -1322,6 +1352,27 @@ v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetSuggestionData( } // static +v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItemData( + const v8::Arguments& args) { + content::RenderView* render_view = GetRenderViewWithCheckedOrigin( + GURL(chrome::kChromeSearchMostVisitedUrl)); + if (!render_view) return v8::Undefined(); + + // Need an rid argument. + if (args.Length() < 1 || !args[0]->IsNumber()) + return v8::Undefined(); + + DVLOG(1) << render_view << " GetMostVisitedItem"; + InstantRestrictedID restricted_id = args[0]->IntegerValue(); + InstantMostVisitedItem mv_item; + if (!SearchBox::Get(render_view)->GetMostVisitedItemWithID( + restricted_id, &mv_item)) { + return v8::Undefined(); + } + return GenerateMostVisitedItem(restricted_id, mv_item); +} + +// static void SearchBoxExtension::DispatchChange(WebKit::WebFrame* frame) { Dispatch(frame, kDispatchChangeEventScript); } |