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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 base::StringPrintf("chrome-search://thumb/%s", | 72 base::StringPrintf("chrome-search://thumb/%s", |
73 base::Uint64ToString(most_visited_item_id).c_str())); | 73 base::Uint64ToString(most_visited_item_id).c_str())); |
74 } | 74 } |
75 | 75 |
76 v8::Handle<v8::String> GenerateFaviconURL(uint64 most_visited_item_id) { | 76 v8::Handle<v8::String> GenerateFaviconURL(uint64 most_visited_item_id) { |
77 return UTF8ToV8String( | 77 return UTF8ToV8String( |
78 base::StringPrintf("chrome-search://favicon/%s", | 78 base::StringPrintf("chrome-search://favicon/%s", |
79 base::Uint64ToString(most_visited_item_id).c_str())); | 79 base::Uint64ToString(most_visited_item_id).c_str())); |
80 } | 80 } |
81 | 81 |
82 const GURL MostVisitedItemIDToURL( | |
83 const std::vector<InstantMostVisitedItem>& most_visited_items, | |
84 uint64 most_visited_item_id) { | |
85 for (size_t i = 0; i < most_visited_items.size(); ++i) { | |
86 if (most_visited_items[i].most_visited_item_id == most_visited_item_id) | |
87 return most_visited_items[i].url; | |
88 } | |
89 return GURL(); | |
90 } | |
91 | |
92 } // namespace | 82 } // namespace |
93 | 83 |
94 namespace extensions_v8 { | 84 namespace extensions_v8 { |
95 | 85 |
96 static const char kSearchBoxExtensionName[] = "v8/EmbeddedSearch"; | 86 static const char kSearchBoxExtensionName[] = "v8/EmbeddedSearch"; |
97 | 87 |
98 static const char kDispatchChangeEventScript[] = | 88 static const char kDispatchChangeEventScript[] = |
99 "if (window.chrome &&" | 89 "if (window.chrome &&" |
100 " window.chrome.embeddedSearch &&" | 90 " window.chrome.embeddedSearch &&" |
101 " window.chrome.embeddedSearch.searchBox &&" | 91 " window.chrome.embeddedSearch.searchBox &&" |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 return v8::Boolean::New(base::i18n::IsRTL()); | 556 return v8::Boolean::New(base::i18n::IsRTL()); |
567 } | 557 } |
568 | 558 |
569 // static | 559 // static |
570 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( | 560 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( |
571 const v8::Arguments& args) { | 561 const v8::Arguments& args) { |
572 content::RenderView* render_view = GetRenderView(); | 562 content::RenderView* render_view = GetRenderView(); |
573 if (!render_view) return v8::Undefined(); | 563 if (!render_view) return v8::Undefined(); |
574 | 564 |
575 DVLOG(1) << render_view << " GetAutocompleteResults"; | 565 DVLOG(1) << render_view << " GetAutocompleteResults"; |
576 const std::vector<InstantAutocompleteResult>& results = | 566 std::vector<InstantAutocompleteResultIDPair> results; |
577 SearchBox::Get(render_view)->GetAutocompleteResults(); | 567 SearchBox::Get(render_view)->GetAutocompleteResults(&results); |
578 size_t results_base = SearchBox::Get(render_view)->results_base(); | |
579 | 568 |
580 v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); | 569 v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); |
581 for (size_t i = 0; i < results.size(); ++i) { | 570 for (size_t i = 0; i < results.size(); ++i) { |
582 v8::Handle<v8::Object> result = v8::Object::New(); | 571 v8::Handle<v8::Object> result = v8::Object::New(); |
583 result->Set(v8::String::New("provider"), | 572 result->Set(v8::String::New("provider"), |
584 UTF16ToV8String(results[i].provider)); | 573 UTF16ToV8String(results[i].second.provider)); |
585 result->Set(v8::String::New("type"), UTF16ToV8String(results[i].type)); | 574 result->Set(v8::String::New("type"), |
| 575 UTF16ToV8String(results[i].second.type)); |
586 result->Set(v8::String::New("contents"), | 576 result->Set(v8::String::New("contents"), |
587 UTF16ToV8String(results[i].description)); | 577 UTF16ToV8String(results[i].second.description)); |
588 result->Set(v8::String::New("destination_url"), | 578 result->Set(v8::String::New("destination_url"), |
589 UTF16ToV8String(results[i].destination_url)); | 579 UTF16ToV8String(results[i].second.destination_url)); |
590 result->Set(v8::String::New("rid"), v8::Uint32::New(results_base + i)); | 580 result->Set(v8::String::New("rid"), v8::Uint32::New(results[i].first)); |
591 | 581 |
592 v8::Handle<v8::Object> ranking_data = v8::Object::New(); | 582 v8::Handle<v8::Object> ranking_data = v8::Object::New(); |
593 ranking_data->Set(v8::String::New("relevance"), | 583 ranking_data->Set(v8::String::New("relevance"), |
594 v8::Int32::New(results[i].relevance)); | 584 v8::Int32::New(results[i].second.relevance)); |
595 result->Set(v8::String::New("rankingData"), ranking_data); | 585 result->Set(v8::String::New("rankingData"), ranking_data); |
596 | 586 |
597 results_array->Set(i, result); | 587 results_array->Set(i, result); |
598 } | 588 } |
599 return results_array; | 589 return results_array; |
600 } | 590 } |
601 | 591 |
602 // static | 592 // static |
603 v8::Handle<v8::Value> SearchBoxExtensionWrapper::IsKeyCaptureEnabled( | 593 v8::Handle<v8::Value> SearchBoxExtensionWrapper::IsKeyCaptureEnabled( |
604 const v8::Arguments& args) { | 594 const v8::Arguments& args) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 | 733 |
744 // static | 734 // static |
745 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateSearchBox( | 735 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateSearchBox( |
746 const v8::Arguments& args) { | 736 const v8::Arguments& args) { |
747 content::RenderView* render_view = GetRenderView(); | 737 content::RenderView* render_view = GetRenderView(); |
748 if (!render_view || !args.Length()) return v8::Undefined(); | 738 if (!render_view || !args.Length()) return v8::Undefined(); |
749 | 739 |
750 GURL destination_url; | 740 GURL destination_url; |
751 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; | 741 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; |
752 if (args[0]->IsNumber()) { | 742 if (args[0]->IsNumber()) { |
753 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 743 InstantAutocompleteResult result; |
754 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 744 if (SearchBox::Get(render_view)->GetAutocompleteResultWithID( |
755 if (result) { | 745 args[0]->IntegerValue(), &result)) { |
756 destination_url = GURL(result->destination_url); | 746 destination_url = GURL(result.destination_url); |
757 transition = result->transition; | 747 transition = result.transition; |
758 } | 748 } |
759 } else { | 749 } else { |
760 // Resolve the URL. | 750 // Resolve the URL. |
761 const string16& possibly_relative_url = V8ValueToUTF16(args[0]); | 751 const string16& possibly_relative_url = V8ValueToUTF16(args[0]); |
762 WebKit::WebView* webview = render_view->GetWebView(); | 752 WebKit::WebView* webview = render_view->GetWebView(); |
763 if (!possibly_relative_url.empty() && webview) { | 753 if (!possibly_relative_url.empty() && webview) { |
764 GURL current_url(webview->mainFrame()->document().url()); | 754 GURL current_url(webview->mainFrame()->document().url()); |
765 destination_url = current_url.Resolve(possibly_relative_url); | 755 destination_url = current_url.Resolve(possibly_relative_url); |
766 } | 756 } |
767 } | 757 } |
(...skipping 12 matching lines...) Expand all Loading... |
780 return v8::Undefined(); | 770 return v8::Undefined(); |
781 } | 771 } |
782 | 772 |
783 // static | 773 // static |
784 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateNewTabPage( | 774 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateNewTabPage( |
785 const v8::Arguments& args) { | 775 const v8::Arguments& args) { |
786 content::RenderView* render_view = GetRenderView(); | 776 content::RenderView* render_view = GetRenderView(); |
787 if (!render_view || !args.Length()) return v8::Undefined(); | 777 if (!render_view || !args.Length()) return v8::Undefined(); |
788 | 778 |
789 GURL destination_url; | 779 GURL destination_url; |
790 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; | 780 content::PageTransition transition = content::PAGE_TRANSITION_AUTO_BOOKMARK; |
791 if (args[0]->IsNumber()) { | 781 if (args[0]->IsNumber()) { |
792 destination_url = MostVisitedItemIDToURL( | 782 InstantMostVisitedItem item; |
793 SearchBox::Get(render_view)->GetMostVisitedItems(), | 783 if (SearchBox::Get(render_view)->GetMostVisitedItemWithID( |
794 args[0]->Uint32Value()); | 784 args[0]->IntegerValue(), &item)) { |
795 transition = content::PAGE_TRANSITION_AUTO_BOOKMARK; | 785 destination_url = item.url; |
| 786 } |
796 } else { | 787 } else { |
797 destination_url = GURL(V8ValueToUTF16(args[0])); | 788 destination_url = GURL(V8ValueToUTF16(args[0])); |
798 } | 789 } |
799 | 790 |
800 DVLOG(1) << render_view << " NavigateNewTabPage: " << destination_url; | 791 DVLOG(1) << render_view << " NavigateNewTabPage: " << destination_url; |
801 | 792 |
802 // Navigate the main frame. | 793 // Navigate the main frame. |
803 if (destination_url.is_valid()) { | 794 if (destination_url.is_valid()) { |
804 WindowOpenDisposition disposition = CURRENT_TAB; | 795 WindowOpenDisposition disposition = CURRENT_TAB; |
805 if (args[1]->Uint32Value() == 2) | 796 if (args[1]->Uint32Value() == 2) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 } | 887 } |
897 | 888 |
898 // static | 889 // static |
899 v8::Handle<v8::Value> | 890 v8::Handle<v8::Value> |
900 SearchBoxExtensionWrapper::SetSuggestionFromAutocompleteResult( | 891 SearchBoxExtensionWrapper::SetSuggestionFromAutocompleteResult( |
901 const v8::Arguments& args) { | 892 const v8::Arguments& args) { |
902 content::RenderView* render_view = GetRenderView(); | 893 content::RenderView* render_view = GetRenderView(); |
903 if (!render_view || !args.Length()) return v8::Undefined(); | 894 if (!render_view || !args.Length()) return v8::Undefined(); |
904 | 895 |
905 DVLOG(1) << render_view << " SetSuggestionFromAutocompleteResult"; | 896 DVLOG(1) << render_view << " SetSuggestionFromAutocompleteResult"; |
906 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 897 InstantAutocompleteResult result; |
907 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 898 if (!SearchBox::Get(render_view)->GetAutocompleteResultWithID( |
908 if (!result) return v8::Undefined(); | 899 args[0]->IntegerValue(), &result)) { |
| 900 return v8::Undefined(); |
| 901 } |
909 | 902 |
910 // We only support selecting autocomplete results that are URLs. | 903 // We only support selecting autocomplete results that are URLs. |
911 string16 text = result->destination_url; | 904 string16 text = result.destination_url; |
912 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; | 905 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; |
913 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | 906 InstantSuggestionType type = INSTANT_SUGGESTION_URL; |
914 | 907 |
915 SearchBox* search_box = SearchBox::Get(render_view); | 908 SearchBox* search_box = SearchBox::Get(render_view); |
916 std::vector<InstantSuggestion> suggestions; | 909 std::vector<InstantSuggestion> suggestions; |
917 suggestions.push_back( | 910 suggestions.push_back( |
918 InstantSuggestion(text, behavior, type, search_box->query())); | 911 InstantSuggestion(text, behavior, type, search_box->query())); |
919 search_box->SetSuggestions(suggestions); | 912 search_box->SetSuggestions(suggestions); |
920 | 913 |
921 return v8::Undefined(); | 914 return v8::Undefined(); |
(...skipping 22 matching lines...) Expand all Loading... |
944 return v8::Undefined(); | 937 return v8::Undefined(); |
945 } | 938 } |
946 | 939 |
947 v8::Handle<v8::Value> | 940 v8::Handle<v8::Value> |
948 SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( | 941 SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( |
949 const v8::Arguments& args) { | 942 const v8::Arguments& args) { |
950 content::RenderView* render_view = GetRenderView(); | 943 content::RenderView* render_view = GetRenderView(); |
951 if (!render_view || !args.Length()) return v8::Undefined(); | 944 if (!render_view || !args.Length()) return v8::Undefined(); |
952 | 945 |
953 DVLOG(1) << render_view << " SetQueryFromAutocompleteResult"; | 946 DVLOG(1) << render_view << " SetQueryFromAutocompleteResult"; |
954 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 947 InstantAutocompleteResult result; |
955 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 948 if (!SearchBox::Get(render_view)->GetAutocompleteResultWithID( |
956 if (!result) return v8::Undefined(); | 949 args[0]->IntegerValue(), &result)) { |
| 950 return v8::Undefined(); |
| 951 } |
957 | 952 |
958 // We only support selecting autocomplete results that are URLs. | 953 // We only support selecting autocomplete results that are URLs. |
959 string16 text = result->destination_url; | 954 string16 text = result.destination_url; |
960 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; | 955 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; |
961 // TODO(jered): Distinguish between history URLs and search provider | 956 // TODO(jered): Distinguish between history URLs and search provider |
962 // navsuggest URLs so that we can do proper accounting on history URLs. | 957 // navsuggest URLs so that we can do proper accounting on history URLs. |
963 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | 958 InstantSuggestionType type = INSTANT_SUGGESTION_URL; |
964 | 959 |
965 SearchBox* search_box = SearchBox::Get(render_view); | 960 SearchBox* search_box = SearchBox::Get(render_view); |
966 std::vector<InstantSuggestion> suggestions; | 961 std::vector<InstantSuggestion> suggestions; |
967 suggestions.push_back( | 962 suggestions.push_back( |
968 InstantSuggestion(text, behavior, type, search_box->query())); | 963 InstantSuggestion(text, behavior, type, search_box->query())); |
969 search_box->SetSuggestions(suggestions); | 964 search_box->SetSuggestions(suggestions); |
(...skipping 26 matching lines...) Expand all Loading... |
996 // static | 991 // static |
997 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( | 992 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( |
998 const v8::Arguments& args) { | 993 const v8::Arguments& args) { |
999 content::RenderView* render_view = GetRenderView(); | 994 content::RenderView* render_view = GetRenderView(); |
1000 if (!render_view) | 995 if (!render_view) |
1001 return v8::Undefined(); | 996 return v8::Undefined(); |
1002 DVLOG(1) << render_view << " GetMostVisitedItems"; | 997 DVLOG(1) << render_view << " GetMostVisitedItems"; |
1003 | 998 |
1004 const SearchBox* search_box = SearchBox::Get(render_view); | 999 const SearchBox* search_box = SearchBox::Get(render_view); |
1005 | 1000 |
1006 const std::vector<InstantMostVisitedItem>& instant_mv_items = | 1001 std::vector<InstantMostVisitedItemIDPair> instant_mv_items; |
1007 search_box->GetMostVisitedItems(); | 1002 search_box->GetMostVisitedItems(&instant_mv_items); |
1008 v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); | 1003 v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); |
1009 for (size_t i = 0; i < instant_mv_items.size(); ++i) { | 1004 for (size_t i = 0; i < instant_mv_items.size(); ++i) { |
1010 // We set the "dir" attribute of the title, so that in RTL locales, a LTR | 1005 // We set the "dir" attribute of the title, so that in RTL locales, a LTR |
1011 // title is rendered left-to-right and truncated from the right. For | 1006 // title is rendered left-to-right and truncated from the right. For |
1012 // example, the title of http://msdn.microsoft.com/en-us/default.aspx is | 1007 // example, the title of http://msdn.microsoft.com/en-us/default.aspx is |
1013 // "MSDN: Microsoft developer network". In RTL locales, in the New Tab | 1008 // "MSDN: Microsoft developer network". In RTL locales, in the New Tab |
1014 // page, if the "dir" of this title is not specified, it takes Chrome UI's | 1009 // page, if the "dir" of this title is not specified, it takes Chrome UI's |
1015 // directionality. So the title will be truncated as "soft developer | 1010 // directionality. So the title will be truncated as "soft developer |
1016 // network". Setting the "dir" attribute as "ltr" renders the truncated | 1011 // network". Setting the "dir" attribute as "ltr" renders the truncated |
1017 // title as "MSDN: Microsoft D...". As another example, the title of | 1012 // title as "MSDN: Microsoft D...". As another example, the title of |
1018 // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the | 1013 // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the |
1019 // title will be rendered as "!Yahoo" if its "dir" attribute is not set to | 1014 // title will be rendered as "!Yahoo" if its "dir" attribute is not set to |
1020 // "ltr". | 1015 // "ltr". |
| 1016 const InstantMostVisitedItem& mv_item = instant_mv_items[i].second; |
1021 std::string direction; | 1017 std::string direction; |
1022 if (base::i18n::StringContainsStrongRTLChars(instant_mv_items[i].title)) | 1018 if (base::i18n::StringContainsStrongRTLChars(mv_item.title)) |
1023 direction = kRTLHtmlTextDirection; | 1019 direction = kRTLHtmlTextDirection; |
1024 else | 1020 else |
1025 direction = kLTRHtmlTextDirection; | 1021 direction = kLTRHtmlTextDirection; |
1026 | 1022 |
1027 string16 title = instant_mv_items[i].title; | 1023 string16 title = mv_item.title; |
1028 if (title.empty()) | 1024 if (title.empty()) |
1029 title = UTF8ToUTF16(instant_mv_items[i].url.spec()); | 1025 title = UTF8ToUTF16(mv_item.url.spec()); |
1030 | 1026 |
| 1027 InstantRestrictedID restricted_id = instant_mv_items[i].first; |
1031 v8::Handle<v8::Object> item = v8::Object::New(); | 1028 v8::Handle<v8::Object> item = v8::Object::New(); |
1032 item->Set(v8::String::New("rid"), | 1029 item->Set(v8::String::New("rid"), v8::Int32::New(restricted_id)); |
1033 v8::Int32::New(instant_mv_items[i].most_visited_item_id)); | |
1034 item->Set(v8::String::New("thumbnailUrl"), | 1030 item->Set(v8::String::New("thumbnailUrl"), |
1035 GenerateThumbnailURL(instant_mv_items[i].most_visited_item_id)); | 1031 GenerateThumbnailURL(restricted_id)); |
1036 item->Set(v8::String::New("faviconUrl"), | 1032 item->Set(v8::String::New("faviconUrl"), |
1037 GenerateFaviconURL(instant_mv_items[i].most_visited_item_id)); | 1033 GenerateFaviconURL(restricted_id)); |
1038 item->Set(v8::String::New("title"), | 1034 item->Set(v8::String::New("title"), UTF16ToV8String(title)); |
1039 UTF16ToV8String(title)); | 1035 item->Set(v8::String::New("domain"), UTF8ToV8String(mv_item.url.host())); |
1040 item->Set(v8::String::New("domain"), | |
1041 UTF8ToV8String(instant_mv_items[i].url.host())); | |
1042 item->Set(v8::String::New("direction"), UTF8ToV8String(direction)); | 1036 item->Set(v8::String::New("direction"), UTF8ToV8String(direction)); |
1043 | 1037 |
1044 v8_mv_items->Set(i, item); | 1038 v8_mv_items->Set(i, item); |
1045 } | 1039 } |
1046 return v8_mv_items; | 1040 return v8_mv_items; |
1047 } | 1041 } |
1048 | 1042 |
1049 // static | 1043 // static |
1050 v8::Handle<v8::Value> SearchBoxExtensionWrapper::DeleteMostVisitedItem( | 1044 v8::Handle<v8::Value> SearchBoxExtensionWrapper::DeleteMostVisitedItem( |
1051 const v8::Arguments& args) { | 1045 const v8::Arguments& args) { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1212 void SearchBoxExtension::DispatchMostVisitedChanged( | 1206 void SearchBoxExtension::DispatchMostVisitedChanged( |
1213 WebKit::WebFrame* frame) { | 1207 WebKit::WebFrame* frame) { |
1214 Dispatch(frame, kDispatchMostVisitedChangedScript); | 1208 Dispatch(frame, kDispatchMostVisitedChangedScript); |
1215 } | 1209 } |
1216 | 1210 |
1217 void SearchBoxExtension::DispatchBarsHidden(WebKit::WebFrame* frame) { | 1211 void SearchBoxExtension::DispatchBarsHidden(WebKit::WebFrame* frame) { |
1218 Dispatch(frame, kDispatchBarsHiddenEventScript); | 1212 Dispatch(frame, kDispatchBarsHiddenEventScript); |
1219 } | 1213 } |
1220 | 1214 |
1221 } // namespace extensions_v8 | 1215 } // namespace extensions_v8 |
OLD | NEW |