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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 StringPrintf("chrome-search://thumb/%s", | 68 StringPrintf("chrome-search://thumb/%s", |
69 base::Uint64ToString(most_visited_item_id).c_str())); | 69 base::Uint64ToString(most_visited_item_id).c_str())); |
70 } | 70 } |
71 | 71 |
72 v8::Handle<v8::String> GenerateFaviconURL(uint64 most_visited_item_id) { | 72 v8::Handle<v8::String> GenerateFaviconURL(uint64 most_visited_item_id) { |
73 return UTF8ToV8String( | 73 return UTF8ToV8String( |
74 StringPrintf("chrome-search://favicon/%s", | 74 StringPrintf("chrome-search://favicon/%s", |
75 base::Uint64ToString(most_visited_item_id).c_str())); | 75 base::Uint64ToString(most_visited_item_id).c_str())); |
76 } | 76 } |
77 | 77 |
78 const GURL MostVisitedItemIDToURL( | |
79 const std::vector<InstantMostVisitedItem>& most_visited_items, | |
80 uint64 most_visited_item_id) { | |
81 for (size_t i = 0; i < most_visited_items.size(); ++i) { | |
82 if (most_visited_items[i].most_visited_item_id == most_visited_item_id) | |
83 return most_visited_items[i].url; | |
84 } | |
85 return GURL(); | |
86 } | |
87 | |
88 } // namespace | 78 } // namespace |
89 | 79 |
90 namespace extensions_v8 { | 80 namespace extensions_v8 { |
91 | 81 |
92 static const char kSearchBoxExtensionName[] = "v8/EmbeddedSearch"; | 82 static const char kSearchBoxExtensionName[] = "v8/EmbeddedSearch"; |
93 | 83 |
94 static const char kDispatchChangeEventScript[] = | 84 static const char kDispatchChangeEventScript[] = |
95 "if (window.chrome &&" | 85 "if (window.chrome &&" |
96 " window.chrome.embeddedSearch &&" | 86 " window.chrome.embeddedSearch &&" |
97 " window.chrome.embeddedSearch.searchBox &&" | 87 " window.chrome.embeddedSearch.searchBox &&" |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 return v8::Boolean::New(base::i18n::IsRTL()); | 532 return v8::Boolean::New(base::i18n::IsRTL()); |
543 } | 533 } |
544 | 534 |
545 // static | 535 // static |
546 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( | 536 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( |
547 const v8::Arguments& args) { | 537 const v8::Arguments& args) { |
548 content::RenderView* render_view = GetRenderView(); | 538 content::RenderView* render_view = GetRenderView(); |
549 if (!render_view) return v8::Undefined(); | 539 if (!render_view) return v8::Undefined(); |
550 | 540 |
551 DVLOG(1) << render_view << " GetAutocompleteResults"; | 541 DVLOG(1) << render_view << " GetAutocompleteResults"; |
552 const std::vector<InstantAutocompleteResult>& results = | 542 std::vector<InstantAutocompleteResultIDPair> results; |
553 SearchBox::Get(render_view)->GetAutocompleteResults(); | 543 SearchBox::Get(render_view)->GetAutocompleteResults(&results); |
554 size_t results_base = SearchBox::Get(render_view)->results_base(); | |
555 | 544 |
556 v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); | 545 v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); |
557 for (size_t i = 0; i < results.size(); ++i) { | 546 for (size_t i = 0; i < results.size(); ++i) { |
558 v8::Handle<v8::Object> result = v8::Object::New(); | 547 v8::Handle<v8::Object> result = v8::Object::New(); |
559 result->Set(v8::String::New("provider"), | 548 result->Set(v8::String::New("provider"), |
560 UTF16ToV8String(results[i].provider)); | 549 UTF16ToV8String(results[i].second.provider)); |
561 result->Set(v8::String::New("type"), UTF16ToV8String(results[i].type)); | 550 result->Set(v8::String::New("type"), |
| 551 UTF16ToV8String(results[i].second.type)); |
562 result->Set(v8::String::New("contents"), | 552 result->Set(v8::String::New("contents"), |
563 UTF16ToV8String(results[i].description)); | 553 UTF16ToV8String(results[i].second.description)); |
564 result->Set(v8::String::New("destination_url"), | 554 result->Set(v8::String::New("destination_url"), |
565 UTF16ToV8String(results[i].destination_url)); | 555 UTF16ToV8String(results[i].second.destination_url)); |
566 result->Set(v8::String::New("rid"), v8::Uint32::New(results_base + i)); | 556 result->Set(v8::String::New("rid"), v8::Uint32::New(results[i].first)); |
567 | 557 |
568 v8::Handle<v8::Object> ranking_data = v8::Object::New(); | 558 v8::Handle<v8::Object> ranking_data = v8::Object::New(); |
569 ranking_data->Set(v8::String::New("relevance"), | 559 ranking_data->Set(v8::String::New("relevance"), |
570 v8::Int32::New(results[i].relevance)); | 560 v8::Int32::New(results[i].second.relevance)); |
571 result->Set(v8::String::New("rankingData"), ranking_data); | 561 result->Set(v8::String::New("rankingData"), ranking_data); |
572 | 562 |
573 results_array->Set(i, result); | 563 results_array->Set(i, result); |
574 } | 564 } |
575 return results_array; | 565 return results_array; |
576 } | 566 } |
577 | 567 |
578 // static | 568 // static |
579 v8::Handle<v8::Value> SearchBoxExtensionWrapper::IsKeyCaptureEnabled( | 569 v8::Handle<v8::Value> SearchBoxExtensionWrapper::IsKeyCaptureEnabled( |
580 const v8::Arguments& args) { | 570 const v8::Arguments& args) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 | 703 |
714 // static | 704 // static |
715 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateSearchBox( | 705 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateSearchBox( |
716 const v8::Arguments& args) { | 706 const v8::Arguments& args) { |
717 content::RenderView* render_view = GetRenderView(); | 707 content::RenderView* render_view = GetRenderView(); |
718 if (!render_view || !args.Length()) return v8::Undefined(); | 708 if (!render_view || !args.Length()) return v8::Undefined(); |
719 | 709 |
720 GURL destination_url; | 710 GURL destination_url; |
721 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; | 711 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; |
722 if (args[0]->IsNumber()) { | 712 if (args[0]->IsNumber()) { |
723 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 713 InstantAutocompleteResult result; |
724 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 714 if (SearchBox::Get(render_view)->GetAutocompleteResultWithId( |
725 if (result) { | 715 args[0]->IntegerValue(), &result)) { |
726 destination_url = GURL(result->destination_url); | 716 destination_url = GURL(result.destination_url); |
727 transition = result->transition; | 717 transition = result.transition; |
728 } | 718 } |
729 } else { | 719 } else { |
730 destination_url = GURL(V8ValueToUTF16(args[0])); | 720 destination_url = GURL(V8ValueToUTF16(args[0])); |
731 } | 721 } |
732 | 722 |
733 DVLOG(1) << render_view << " NavigateSearchBox: " << destination_url; | 723 DVLOG(1) << render_view << " NavigateSearchBox: " << destination_url; |
734 | 724 |
735 // Navigate the main frame. | 725 // Navigate the main frame. |
736 if (destination_url.is_valid()) { | 726 if (destination_url.is_valid()) { |
737 WindowOpenDisposition disposition = CURRENT_TAB; | 727 WindowOpenDisposition disposition = CURRENT_TAB; |
738 if (args[1]->Uint32Value() == 2) | 728 if (args[1]->Uint32Value() == 2) |
739 disposition = NEW_BACKGROUND_TAB; | 729 disposition = NEW_BACKGROUND_TAB; |
740 SearchBox::Get(render_view)->NavigateToURL( | 730 SearchBox::Get(render_view)->NavigateToURL( |
741 destination_url, transition, disposition); | 731 destination_url, transition, disposition); |
742 } | 732 } |
743 return v8::Undefined(); | 733 return v8::Undefined(); |
744 } | 734 } |
745 | 735 |
746 // static | 736 // static |
747 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateNewTabPage( | 737 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateNewTabPage( |
748 const v8::Arguments& args) { | 738 const v8::Arguments& args) { |
749 content::RenderView* render_view = GetRenderView(); | 739 content::RenderView* render_view = GetRenderView(); |
750 if (!render_view || !args.Length()) return v8::Undefined(); | 740 if (!render_view || !args.Length()) return v8::Undefined(); |
751 | 741 |
752 GURL destination_url; | 742 GURL destination_url; |
753 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; | 743 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; |
754 if (args[0]->IsNumber()) { | 744 if (args[0]->IsNumber()) { |
755 destination_url = MostVisitedItemIDToURL( | 745 InstantMostVisitedItem item; |
756 SearchBox::Get(render_view)->GetMostVisitedItems(), | 746 if (SearchBox::Get(render_view)->GetMostVisitedItemWithID( |
757 args[0]->Uint32Value()); | 747 args[0]->IntegerValue(), &item)) { |
| 748 destination_url = item.url; |
| 749 } |
758 } else { | 750 } else { |
759 destination_url = GURL(V8ValueToUTF16(args[0])); | 751 destination_url = GURL(V8ValueToUTF16(args[0])); |
760 } | 752 } |
761 | 753 |
762 DVLOG(1) << render_view << " NavigateNewTabPage: " << destination_url; | 754 DVLOG(1) << render_view << " NavigateNewTabPage: " << destination_url; |
763 | 755 |
764 // Navigate the main frame. | 756 // Navigate the main frame. |
765 if (destination_url.is_valid()) { | 757 if (destination_url.is_valid()) { |
766 WindowOpenDisposition disposition = CURRENT_TAB; | 758 WindowOpenDisposition disposition = CURRENT_TAB; |
767 if (args[1]->Uint32Value() == 2) | 759 if (args[1]->Uint32Value() == 2) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 } | 846 } |
855 | 847 |
856 // static | 848 // static |
857 v8::Handle<v8::Value> | 849 v8::Handle<v8::Value> |
858 SearchBoxExtensionWrapper::SetQuerySuggestionFromAutocompleteResult( | 850 SearchBoxExtensionWrapper::SetQuerySuggestionFromAutocompleteResult( |
859 const v8::Arguments& args) { | 851 const v8::Arguments& args) { |
860 content::RenderView* render_view = GetRenderView(); | 852 content::RenderView* render_view = GetRenderView(); |
861 if (!render_view || !args.Length()) return v8::Undefined(); | 853 if (!render_view || !args.Length()) return v8::Undefined(); |
862 | 854 |
863 DVLOG(1) << render_view << " SetQuerySuggestionFromAutocompleteResult"; | 855 DVLOG(1) << render_view << " SetQuerySuggestionFromAutocompleteResult"; |
864 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 856 InstantAutocompleteResult result; |
865 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 857 if (!SearchBox::Get(render_view)->GetAutocompleteResultWithId( |
866 if (!result) return v8::Undefined(); | 858 args[0]->IntegerValue(), &result)) { |
| 859 return v8::Undefined(); |
| 860 } |
867 | 861 |
868 // We only support selecting autocomplete results that are URLs. | 862 // We only support selecting autocomplete results that are URLs. |
869 string16 text = result->destination_url; | 863 string16 text = result.destination_url; |
870 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; | 864 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; |
871 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | 865 InstantSuggestionType type = INSTANT_SUGGESTION_URL; |
872 | 866 |
873 std::vector<InstantSuggestion> suggestions; | 867 std::vector<InstantSuggestion> suggestions; |
874 suggestions.push_back(InstantSuggestion(text, behavior, type)); | 868 suggestions.push_back(InstantSuggestion(text, behavior, type)); |
875 SearchBox::Get(render_view)->SetSuggestions(suggestions); | 869 SearchBox::Get(render_view)->SetSuggestions(suggestions); |
876 | 870 |
877 return v8::Undefined(); | 871 return v8::Undefined(); |
878 } | 872 } |
879 | 873 |
(...skipping 18 matching lines...) Expand all Loading... |
898 return v8::Undefined(); | 892 return v8::Undefined(); |
899 } | 893 } |
900 | 894 |
901 v8::Handle<v8::Value> | 895 v8::Handle<v8::Value> |
902 SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( | 896 SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( |
903 const v8::Arguments& args) { | 897 const v8::Arguments& args) { |
904 content::RenderView* render_view = GetRenderView(); | 898 content::RenderView* render_view = GetRenderView(); |
905 if (!render_view || !args.Length()) return v8::Undefined(); | 899 if (!render_view || !args.Length()) return v8::Undefined(); |
906 | 900 |
907 DVLOG(1) << render_view << " SetQueryFromAutocompleteResult"; | 901 DVLOG(1) << render_view << " SetQueryFromAutocompleteResult"; |
908 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 902 InstantAutocompleteResult result; |
909 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 903 if (!SearchBox::Get(render_view)->GetAutocompleteResultWithId( |
910 if (!result) return v8::Undefined(); | 904 args[0]->IntegerValue(), &result)) { |
| 905 return v8::Undefined(); |
| 906 } |
911 | 907 |
912 // We only support selecting autocomplete results that are URLs. | 908 // We only support selecting autocomplete results that are URLs. |
913 string16 text = result->destination_url; | 909 string16 text = result.destination_url; |
914 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; | 910 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; |
915 // TODO(jered): Distinguish between history URLs and search provider | 911 // TODO(jered): Distinguish between history URLs and search provider |
916 // navsuggest URLs so that we can do proper accounting on history URLs. | 912 // navsuggest URLs so that we can do proper accounting on history URLs. |
917 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | 913 InstantSuggestionType type = INSTANT_SUGGESTION_URL; |
918 | 914 |
919 std::vector<InstantSuggestion> suggestions; | 915 std::vector<InstantSuggestion> suggestions; |
920 suggestions.push_back(InstantSuggestion(text, behavior, type)); | 916 suggestions.push_back(InstantSuggestion(text, behavior, type)); |
921 SearchBox::Get(render_view)->SetSuggestions(suggestions); | 917 SearchBox::Get(render_view)->SetSuggestions(suggestions); |
922 | 918 |
923 return v8::Undefined(); | 919 return v8::Undefined(); |
(...skipping 29 matching lines...) Expand all Loading... |
953 // static | 949 // static |
954 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( | 950 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( |
955 const v8::Arguments& args) { | 951 const v8::Arguments& args) { |
956 content::RenderView* render_view = GetRenderView(); | 952 content::RenderView* render_view = GetRenderView(); |
957 if (!render_view) | 953 if (!render_view) |
958 return v8::Undefined(); | 954 return v8::Undefined(); |
959 DVLOG(1) << render_view << " GetMostVisitedItems"; | 955 DVLOG(1) << render_view << " GetMostVisitedItems"; |
960 | 956 |
961 const SearchBox* search_box = SearchBox::Get(render_view); | 957 const SearchBox* search_box = SearchBox::Get(render_view); |
962 | 958 |
963 const std::vector<InstantMostVisitedItem>& instant_mv_items = | 959 std::vector<InstantMostVisitedItemIDPair> instant_mv_items; |
964 search_box->GetMostVisitedItems(); | 960 search_box->GetMostVisitedItems(&instant_mv_items); |
965 v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); | 961 v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); |
966 for (size_t i = 0; i < instant_mv_items.size(); ++i) { | 962 for (size_t i = 0; i < instant_mv_items.size(); ++i) { |
967 // We set the "dir" attribute of the title, so that in RTL locales, a LTR | 963 // We set the "dir" attribute of the title, so that in RTL locales, a LTR |
968 // title is rendered left-to-right and truncated from the right. For | 964 // title is rendered left-to-right and truncated from the right. For |
969 // example, the title of http://msdn.microsoft.com/en-us/default.aspx is | 965 // example, the title of http://msdn.microsoft.com/en-us/default.aspx is |
970 // "MSDN: Microsoft developer network". In RTL locales, in the New Tab | 966 // "MSDN: Microsoft developer network". In RTL locales, in the New Tab |
971 // page, if the "dir" of this title is not specified, it takes Chrome UI's | 967 // page, if the "dir" of this title is not specified, it takes Chrome UI's |
972 // directionality. So the title will be truncated as "soft developer | 968 // directionality. So the title will be truncated as "soft developer |
973 // network". Setting the "dir" attribute as "ltr" renders the truncated | 969 // network". Setting the "dir" attribute as "ltr" renders the truncated |
974 // title as "MSDN: Microsoft D...". As another example, the title of | 970 // title as "MSDN: Microsoft D...". As another example, the title of |
975 // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the | 971 // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the |
976 // title will be rendered as "!Yahoo" if its "dir" attribute is not set to | 972 // title will be rendered as "!Yahoo" if its "dir" attribute is not set to |
977 // "ltr". | 973 // "ltr". |
| 974 const InstantMostVisitedItem& mv_item = instant_mv_items[i].second; |
978 std::string direction; | 975 std::string direction; |
979 if (base::i18n::StringContainsStrongRTLChars(instant_mv_items[i].title)) | 976 if (base::i18n::StringContainsStrongRTLChars(mv_item.title)) |
980 direction = kRTLHtmlTextDirection; | 977 direction = kRTLHtmlTextDirection; |
981 else | 978 else |
982 direction = kLTRHtmlTextDirection; | 979 direction = kLTRHtmlTextDirection; |
983 | 980 |
984 string16 title = instant_mv_items[i].title; | 981 string16 title = mv_item.title; |
985 if (title.empty()) | 982 if (title.empty()) |
986 title = UTF8ToUTF16(instant_mv_items[i].url.spec()); | 983 title = UTF8ToUTF16(mv_item.url.spec()); |
987 | 984 |
| 985 InstantRestrictedID restricted_id = instant_mv_items[i].first; |
988 v8::Handle<v8::Object> item = v8::Object::New(); | 986 v8::Handle<v8::Object> item = v8::Object::New(); |
989 item->Set(v8::String::New("rid"), | 987 item->Set(v8::String::New("rid"), v8::Int32::New(restricted_id)); |
990 v8::Int32::New(instant_mv_items[i].most_visited_item_id)); | |
991 item->Set(v8::String::New("thumbnailUrl"), | 988 item->Set(v8::String::New("thumbnailUrl"), |
992 GenerateThumbnailURL(instant_mv_items[i].most_visited_item_id)); | 989 GenerateThumbnailURL(restricted_id)); |
993 item->Set(v8::String::New("faviconUrl"), | 990 item->Set(v8::String::New("faviconUrl"), |
994 GenerateFaviconURL(instant_mv_items[i].most_visited_item_id)); | 991 GenerateFaviconURL(restricted_id)); |
995 item->Set(v8::String::New("title"), | 992 item->Set(v8::String::New("title"), UTF16ToV8String(title)); |
996 UTF16ToV8String(title)); | 993 item->Set(v8::String::New("domain"), UTF8ToV8String(mv_item.url.host())); |
997 item->Set(v8::String::New("domain"), | |
998 UTF8ToV8String(instant_mv_items[i].url.host())); | |
999 item->Set(v8::String::New("direction"), UTF8ToV8String(direction)); | 994 item->Set(v8::String::New("direction"), UTF8ToV8String(direction)); |
1000 | 995 |
1001 v8_mv_items->Set(i, item); | 996 v8_mv_items->Set(i, item); |
1002 } | 997 } |
1003 return v8_mv_items; | 998 return v8_mv_items; |
1004 } | 999 } |
1005 | 1000 |
1006 // static | 1001 // static |
1007 v8::Handle<v8::Value> SearchBoxExtensionWrapper::DeleteMostVisitedItem( | 1002 v8::Handle<v8::Value> SearchBoxExtensionWrapper::DeleteMostVisitedItem( |
1008 const v8::Arguments& args) { | 1003 const v8::Arguments& args) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 void SearchBoxExtension::DispatchThemeChange(WebKit::WebFrame* frame) { | 1138 void SearchBoxExtension::DispatchThemeChange(WebKit::WebFrame* frame) { |
1144 Dispatch(frame, kDispatchThemeChangeEventScript); | 1139 Dispatch(frame, kDispatchThemeChangeEventScript); |
1145 } | 1140 } |
1146 | 1141 |
1147 // static | 1142 // static |
1148 void SearchBoxExtension::DispatchMostVisitedChanged( | 1143 void SearchBoxExtension::DispatchMostVisitedChanged( |
1149 WebKit::WebFrame* frame) { | 1144 WebKit::WebFrame* frame) { |
1150 Dispatch(frame, kDispatchMostVisitedChangedScript); | 1145 Dispatch(frame, kDispatchMostVisitedChangedScript); |
1151 } | 1146 } |
1152 } // namespace extensions_v8 | 1147 } // namespace extensions_v8 |
OLD | NEW |