OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/searchbox/searchbox_extension.h" | 5 #include "chrome/renderer/searchbox/searchbox_extension.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 StringPrintf("chrome-search://thumb/%s", | 69 StringPrintf("chrome-search://thumb/%s", |
70 base::Uint64ToString(most_visited_item_id).c_str())); | 70 base::Uint64ToString(most_visited_item_id).c_str())); |
71 } | 71 } |
72 | 72 |
73 v8::Handle<v8::String> GenerateFaviconURL(uint64 most_visited_item_id) { | 73 v8::Handle<v8::String> GenerateFaviconURL(uint64 most_visited_item_id) { |
74 return UTF8ToV8String( | 74 return UTF8ToV8String( |
75 StringPrintf("chrome-search://favicon/%s", | 75 StringPrintf("chrome-search://favicon/%s", |
76 base::Uint64ToString(most_visited_item_id).c_str())); | 76 base::Uint64ToString(most_visited_item_id).c_str())); |
77 } | 77 } |
78 | 78 |
79 const GURL MostVisitedItemIDToURL( | |
80 const std::vector<InstantMostVisitedItem>& most_visited_items, | |
81 uint64 most_visited_item_id) { | |
82 for (size_t i = 0; i < most_visited_items.size(); ++i) { | |
83 if (most_visited_items[i].most_visited_item_id == most_visited_item_id) | |
84 return most_visited_items[i].url; | |
85 } | |
86 return GURL(); | |
87 } | |
88 | |
89 } // namespace | 79 } // namespace |
90 | 80 |
91 namespace extensions_v8 { | 81 namespace extensions_v8 { |
92 | 82 |
93 static const char kSearchBoxExtensionName[] = "v8/EmbeddedSearch"; | 83 static const char kSearchBoxExtensionName[] = "v8/EmbeddedSearch"; |
94 | 84 |
95 static const char kDispatchChangeEventScript[] = | 85 static const char kDispatchChangeEventScript[] = |
96 "if (window.chrome &&" | 86 "if (window.chrome &&" |
97 " window.chrome.embeddedSearch &&" | 87 " window.chrome.embeddedSearch &&" |
98 " window.chrome.embeddedSearch.searchBox &&" | 88 " window.chrome.embeddedSearch.searchBox &&" |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 return v8::Boolean::New(base::i18n::IsRTL()); | 533 return v8::Boolean::New(base::i18n::IsRTL()); |
544 } | 534 } |
545 | 535 |
546 // static | 536 // static |
547 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( | 537 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( |
548 const v8::Arguments& args) { | 538 const v8::Arguments& args) { |
549 content::RenderView* render_view = GetRenderView(); | 539 content::RenderView* render_view = GetRenderView(); |
550 if (!render_view) return v8::Undefined(); | 540 if (!render_view) return v8::Undefined(); |
551 | 541 |
552 DVLOG(1) << render_view << " GetAutocompleteResults"; | 542 DVLOG(1) << render_view << " GetAutocompleteResults"; |
553 const std::vector<InstantAutocompleteResult>& results = | 543 std::vector<InstantAutocompleteResultIDPair> results; |
554 SearchBox::Get(render_view)->GetAutocompleteResults(); | 544 SearchBox::Get(render_view)->GetAutocompleteResults(&results); |
555 size_t results_base = SearchBox::Get(render_view)->results_base(); | |
556 | 545 |
557 v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); | 546 v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); |
558 for (size_t i = 0; i < results.size(); ++i) { | 547 for (size_t i = 0; i < results.size(); ++i) { |
559 v8::Handle<v8::Object> result = v8::Object::New(); | 548 v8::Handle<v8::Object> result = v8::Object::New(); |
560 result->Set(v8::String::New("provider"), | 549 result->Set(v8::String::New("provider"), |
561 UTF16ToV8String(results[i].provider)); | 550 UTF16ToV8String(results[i].second.provider)); |
562 result->Set(v8::String::New("type"), UTF16ToV8String(results[i].type)); | 551 result->Set(v8::String::New("type"), |
| 552 UTF16ToV8String(results[i].second.type)); |
563 result->Set(v8::String::New("contents"), | 553 result->Set(v8::String::New("contents"), |
564 UTF16ToV8String(results[i].description)); | 554 UTF16ToV8String(results[i].second.description)); |
565 result->Set(v8::String::New("destination_url"), | 555 result->Set(v8::String::New("destination_url"), |
566 UTF16ToV8String(results[i].destination_url)); | 556 UTF16ToV8String(results[i].second.destination_url)); |
567 result->Set(v8::String::New("rid"), v8::Uint32::New(results_base + i)); | 557 result->Set(v8::String::New("rid"), v8::Uint32::New(results[i].first)); |
568 | 558 |
569 v8::Handle<v8::Object> ranking_data = v8::Object::New(); | 559 v8::Handle<v8::Object> ranking_data = v8::Object::New(); |
570 ranking_data->Set(v8::String::New("relevance"), | 560 ranking_data->Set(v8::String::New("relevance"), |
571 v8::Int32::New(results[i].relevance)); | 561 v8::Int32::New(results[i].second.relevance)); |
572 result->Set(v8::String::New("rankingData"), ranking_data); | 562 result->Set(v8::String::New("rankingData"), ranking_data); |
573 | 563 |
574 results_array->Set(i, result); | 564 results_array->Set(i, result); |
575 } | 565 } |
576 return results_array; | 566 return results_array; |
577 } | 567 } |
578 | 568 |
579 // static | 569 // static |
580 v8::Handle<v8::Value> SearchBoxExtensionWrapper::IsKeyCaptureEnabled( | 570 v8::Handle<v8::Value> SearchBoxExtensionWrapper::IsKeyCaptureEnabled( |
581 const v8::Arguments& args) { | 571 const v8::Arguments& args) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 | 704 |
715 // static | 705 // static |
716 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateSearchBox( | 706 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateSearchBox( |
717 const v8::Arguments& args) { | 707 const v8::Arguments& args) { |
718 content::RenderView* render_view = GetRenderView(); | 708 content::RenderView* render_view = GetRenderView(); |
719 if (!render_view || !args.Length()) return v8::Undefined(); | 709 if (!render_view || !args.Length()) return v8::Undefined(); |
720 | 710 |
721 GURL destination_url; | 711 GURL destination_url; |
722 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; | 712 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; |
723 if (args[0]->IsNumber()) { | 713 if (args[0]->IsNumber()) { |
724 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 714 InstantAutocompleteResult result; |
725 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 715 if (SearchBox::Get(render_view)->GetAutocompleteResultWithId( |
726 if (result) { | 716 args[0]->IntegerValue(), &result)) { |
727 destination_url = GURL(result->destination_url); | 717 destination_url = GURL(result.destination_url); |
728 transition = result->transition; | 718 transition = result.transition; |
729 } | 719 } |
730 } else { | 720 } else { |
731 // Resolve the URL. | 721 // Resolve the URL. |
732 const string16& possibly_relative_url = V8ValueToUTF16(args[0]); | 722 const string16& possibly_relative_url = V8ValueToUTF16(args[0]); |
733 WebKit::WebView* webview = render_view->GetWebView(); | 723 WebKit::WebView* webview = render_view->GetWebView(); |
734 if (!possibly_relative_url.empty() && webview) { | 724 if (!possibly_relative_url.empty() && webview) { |
735 GURL current_url(webview->mainFrame()->document().url()); | 725 GURL current_url(webview->mainFrame()->document().url()); |
736 destination_url = current_url.Resolve(possibly_relative_url); | 726 destination_url = current_url.Resolve(possibly_relative_url); |
737 } | 727 } |
738 } | 728 } |
(...skipping 12 matching lines...) Expand all Loading... |
751 return v8::Undefined(); | 741 return v8::Undefined(); |
752 } | 742 } |
753 | 743 |
754 // static | 744 // static |
755 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateNewTabPage( | 745 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateNewTabPage( |
756 const v8::Arguments& args) { | 746 const v8::Arguments& args) { |
757 content::RenderView* render_view = GetRenderView(); | 747 content::RenderView* render_view = GetRenderView(); |
758 if (!render_view || !args.Length()) return v8::Undefined(); | 748 if (!render_view || !args.Length()) return v8::Undefined(); |
759 | 749 |
760 GURL destination_url; | 750 GURL destination_url; |
761 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; | 751 content::PageTransition transition = content::PAGE_TRANSITION_AUTO_BOOKMARK; |
762 if (args[0]->IsNumber()) { | 752 if (args[0]->IsNumber()) { |
763 destination_url = MostVisitedItemIDToURL( | 753 InstantMostVisitedItem item; |
764 SearchBox::Get(render_view)->GetMostVisitedItems(), | 754 if (SearchBox::Get(render_view)->GetMostVisitedItemWithID( |
765 args[0]->Uint32Value()); | 755 args[0]->IntegerValue(), &item)) { |
766 transition = content::PAGE_TRANSITION_AUTO_BOOKMARK; | 756 destination_url = item.url; |
| 757 } |
767 } else { | 758 } else { |
768 destination_url = GURL(V8ValueToUTF16(args[0])); | 759 destination_url = GURL(V8ValueToUTF16(args[0])); |
769 } | 760 } |
770 | 761 |
771 DVLOG(1) << render_view << " NavigateNewTabPage: " << destination_url; | 762 DVLOG(1) << render_view << " NavigateNewTabPage: " << destination_url; |
772 | 763 |
773 // Navigate the main frame. | 764 // Navigate the main frame. |
774 if (destination_url.is_valid()) { | 765 if (destination_url.is_valid()) { |
775 WindowOpenDisposition disposition = CURRENT_TAB; | 766 WindowOpenDisposition disposition = CURRENT_TAB; |
776 if (args[1]->Uint32Value() == 2) | 767 if (args[1]->Uint32Value() == 2) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
867 } | 858 } |
868 | 859 |
869 // static | 860 // static |
870 v8::Handle<v8::Value> | 861 v8::Handle<v8::Value> |
871 SearchBoxExtensionWrapper::SetSuggestionFromAutocompleteResult( | 862 SearchBoxExtensionWrapper::SetSuggestionFromAutocompleteResult( |
872 const v8::Arguments& args) { | 863 const v8::Arguments& args) { |
873 content::RenderView* render_view = GetRenderView(); | 864 content::RenderView* render_view = GetRenderView(); |
874 if (!render_view || !args.Length()) return v8::Undefined(); | 865 if (!render_view || !args.Length()) return v8::Undefined(); |
875 | 866 |
876 DVLOG(1) << render_view << " SetSuggestionFromAutocompleteResult"; | 867 DVLOG(1) << render_view << " SetSuggestionFromAutocompleteResult"; |
877 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 868 InstantAutocompleteResult result; |
878 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 869 if (!SearchBox::Get(render_view)->GetAutocompleteResultWithId( |
879 if (!result) return v8::Undefined(); | 870 args[0]->IntegerValue(), &result)) { |
| 871 return v8::Undefined(); |
| 872 } |
880 | 873 |
881 // We only support selecting autocomplete results that are URLs. | 874 // We only support selecting autocomplete results that are URLs. |
882 string16 text = result->destination_url; | 875 string16 text = result.destination_url; |
883 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; | 876 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; |
884 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | 877 InstantSuggestionType type = INSTANT_SUGGESTION_URL; |
885 | 878 |
886 SearchBox* search_box = SearchBox::Get(render_view); | 879 SearchBox* search_box = SearchBox::Get(render_view); |
887 std::vector<InstantSuggestion> suggestions; | 880 std::vector<InstantSuggestion> suggestions; |
888 suggestions.push_back( | 881 suggestions.push_back( |
889 InstantSuggestion(text, behavior, type, search_box->query())); | 882 InstantSuggestion(text, behavior, type, search_box->query())); |
890 search_box->SetSuggestions(suggestions); | 883 search_box->SetSuggestions(suggestions); |
891 | 884 |
892 return v8::Undefined(); | 885 return v8::Undefined(); |
(...skipping 22 matching lines...) Expand all Loading... |
915 return v8::Undefined(); | 908 return v8::Undefined(); |
916 } | 909 } |
917 | 910 |
918 v8::Handle<v8::Value> | 911 v8::Handle<v8::Value> |
919 SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( | 912 SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( |
920 const v8::Arguments& args) { | 913 const v8::Arguments& args) { |
921 content::RenderView* render_view = GetRenderView(); | 914 content::RenderView* render_view = GetRenderView(); |
922 if (!render_view || !args.Length()) return v8::Undefined(); | 915 if (!render_view || !args.Length()) return v8::Undefined(); |
923 | 916 |
924 DVLOG(1) << render_view << " SetQueryFromAutocompleteResult"; | 917 DVLOG(1) << render_view << " SetQueryFromAutocompleteResult"; |
925 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 918 InstantAutocompleteResult result; |
926 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 919 if (!SearchBox::Get(render_view)->GetAutocompleteResultWithId( |
927 if (!result) return v8::Undefined(); | 920 args[0]->IntegerValue(), &result)) { |
| 921 return v8::Undefined(); |
| 922 } |
928 | 923 |
929 // We only support selecting autocomplete results that are URLs. | 924 // We only support selecting autocomplete results that are URLs. |
930 string16 text = result->destination_url; | 925 string16 text = result.destination_url; |
931 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; | 926 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; |
932 // TODO(jered): Distinguish between history URLs and search provider | 927 // TODO(jered): Distinguish between history URLs and search provider |
933 // navsuggest URLs so that we can do proper accounting on history URLs. | 928 // navsuggest URLs so that we can do proper accounting on history URLs. |
934 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | 929 InstantSuggestionType type = INSTANT_SUGGESTION_URL; |
935 | 930 |
936 SearchBox* search_box = SearchBox::Get(render_view); | 931 SearchBox* search_box = SearchBox::Get(render_view); |
937 std::vector<InstantSuggestion> suggestions; | 932 std::vector<InstantSuggestion> suggestions; |
938 suggestions.push_back( | 933 suggestions.push_back( |
939 InstantSuggestion(text, behavior, type, search_box->query())); | 934 InstantSuggestion(text, behavior, type, search_box->query())); |
940 search_box->SetSuggestions(suggestions); | 935 search_box->SetSuggestions(suggestions); |
(...skipping 26 matching lines...) Expand all Loading... |
967 // static | 962 // static |
968 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( | 963 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( |
969 const v8::Arguments& args) { | 964 const v8::Arguments& args) { |
970 content::RenderView* render_view = GetRenderView(); | 965 content::RenderView* render_view = GetRenderView(); |
971 if (!render_view) | 966 if (!render_view) |
972 return v8::Undefined(); | 967 return v8::Undefined(); |
973 DVLOG(1) << render_view << " GetMostVisitedItems"; | 968 DVLOG(1) << render_view << " GetMostVisitedItems"; |
974 | 969 |
975 const SearchBox* search_box = SearchBox::Get(render_view); | 970 const SearchBox* search_box = SearchBox::Get(render_view); |
976 | 971 |
977 const std::vector<InstantMostVisitedItem>& instant_mv_items = | 972 std::vector<InstantMostVisitedItemIDPair> instant_mv_items; |
978 search_box->GetMostVisitedItems(); | 973 search_box->GetMostVisitedItems(&instant_mv_items); |
979 v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); | 974 v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); |
980 for (size_t i = 0; i < instant_mv_items.size(); ++i) { | 975 for (size_t i = 0; i < instant_mv_items.size(); ++i) { |
981 // We set the "dir" attribute of the title, so that in RTL locales, a LTR | 976 // We set the "dir" attribute of the title, so that in RTL locales, a LTR |
982 // title is rendered left-to-right and truncated from the right. For | 977 // title is rendered left-to-right and truncated from the right. For |
983 // example, the title of http://msdn.microsoft.com/en-us/default.aspx is | 978 // example, the title of http://msdn.microsoft.com/en-us/default.aspx is |
984 // "MSDN: Microsoft developer network". In RTL locales, in the New Tab | 979 // "MSDN: Microsoft developer network". In RTL locales, in the New Tab |
985 // page, if the "dir" of this title is not specified, it takes Chrome UI's | 980 // page, if the "dir" of this title is not specified, it takes Chrome UI's |
986 // directionality. So the title will be truncated as "soft developer | 981 // directionality. So the title will be truncated as "soft developer |
987 // network". Setting the "dir" attribute as "ltr" renders the truncated | 982 // network". Setting the "dir" attribute as "ltr" renders the truncated |
988 // title as "MSDN: Microsoft D...". As another example, the title of | 983 // title as "MSDN: Microsoft D...". As another example, the title of |
989 // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the | 984 // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the |
990 // title will be rendered as "!Yahoo" if its "dir" attribute is not set to | 985 // title will be rendered as "!Yahoo" if its "dir" attribute is not set to |
991 // "ltr". | 986 // "ltr". |
| 987 const InstantMostVisitedItem& mv_item = instant_mv_items[i].second; |
992 std::string direction; | 988 std::string direction; |
993 if (base::i18n::StringContainsStrongRTLChars(instant_mv_items[i].title)) | 989 if (base::i18n::StringContainsStrongRTLChars(mv_item.title)) |
994 direction = kRTLHtmlTextDirection; | 990 direction = kRTLHtmlTextDirection; |
995 else | 991 else |
996 direction = kLTRHtmlTextDirection; | 992 direction = kLTRHtmlTextDirection; |
997 | 993 |
998 string16 title = instant_mv_items[i].title; | 994 string16 title = mv_item.title; |
999 if (title.empty()) | 995 if (title.empty()) |
1000 title = UTF8ToUTF16(instant_mv_items[i].url.spec()); | 996 title = UTF8ToUTF16(mv_item.url.spec()); |
1001 | 997 |
| 998 InstantRestrictedID restricted_id = instant_mv_items[i].first; |
1002 v8::Handle<v8::Object> item = v8::Object::New(); | 999 v8::Handle<v8::Object> item = v8::Object::New(); |
1003 item->Set(v8::String::New("rid"), | 1000 item->Set(v8::String::New("rid"), v8::Int32::New(restricted_id)); |
1004 v8::Int32::New(instant_mv_items[i].most_visited_item_id)); | |
1005 item->Set(v8::String::New("thumbnailUrl"), | 1001 item->Set(v8::String::New("thumbnailUrl"), |
1006 GenerateThumbnailURL(instant_mv_items[i].most_visited_item_id)); | 1002 GenerateThumbnailURL(restricted_id)); |
1007 item->Set(v8::String::New("faviconUrl"), | 1003 item->Set(v8::String::New("faviconUrl"), |
1008 GenerateFaviconURL(instant_mv_items[i].most_visited_item_id)); | 1004 GenerateFaviconURL(restricted_id)); |
1009 item->Set(v8::String::New("title"), | 1005 item->Set(v8::String::New("title"), UTF16ToV8String(title)); |
1010 UTF16ToV8String(title)); | 1006 item->Set(v8::String::New("domain"), UTF8ToV8String(mv_item.url.host())); |
1011 item->Set(v8::String::New("domain"), | |
1012 UTF8ToV8String(instant_mv_items[i].url.host())); | |
1013 item->Set(v8::String::New("direction"), UTF8ToV8String(direction)); | 1007 item->Set(v8::String::New("direction"), UTF8ToV8String(direction)); |
1014 | 1008 |
1015 v8_mv_items->Set(i, item); | 1009 v8_mv_items->Set(i, item); |
1016 } | 1010 } |
1017 return v8_mv_items; | 1011 return v8_mv_items; |
1018 } | 1012 } |
1019 | 1013 |
1020 // static | 1014 // static |
1021 v8::Handle<v8::Value> SearchBoxExtensionWrapper::DeleteMostVisitedItem( | 1015 v8::Handle<v8::Value> SearchBoxExtensionWrapper::DeleteMostVisitedItem( |
1022 const v8::Arguments& args) { | 1016 const v8::Arguments& args) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 void SearchBoxExtension::DispatchThemeChange(WebKit::WebFrame* frame) { | 1151 void SearchBoxExtension::DispatchThemeChange(WebKit::WebFrame* frame) { |
1158 Dispatch(frame, kDispatchThemeChangeEventScript); | 1152 Dispatch(frame, kDispatchThemeChangeEventScript); |
1159 } | 1153 } |
1160 | 1154 |
1161 // static | 1155 // static |
1162 void SearchBoxExtension::DispatchMostVisitedChanged( | 1156 void SearchBoxExtension::DispatchMostVisitedChanged( |
1163 WebKit::WebFrame* frame) { | 1157 WebKit::WebFrame* frame) { |
1164 Dispatch(frame, kDispatchMostVisitedChangedScript); | 1158 Dispatch(frame, kDispatchMostVisitedChangedScript); |
1165 } | 1159 } |
1166 } // namespace extensions_v8 | 1160 } // namespace extensions_v8 |
OLD | NEW |