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 base::StringPrintf("chrome-search://thumb/%s", | 69 base::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 base::StringPrintf("chrome-search://favicon/%s", | 75 base::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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 return v8::Boolean::New(base::i18n::IsRTL()); | 553 return v8::Boolean::New(base::i18n::IsRTL()); |
564 } | 554 } |
565 | 555 |
566 // static | 556 // static |
567 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( | 557 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetAutocompleteResults( |
568 const v8::Arguments& args) { | 558 const v8::Arguments& args) { |
569 content::RenderView* render_view = GetRenderView(); | 559 content::RenderView* render_view = GetRenderView(); |
570 if (!render_view) return v8::Undefined(); | 560 if (!render_view) return v8::Undefined(); |
571 | 561 |
572 DVLOG(1) << render_view << " GetAutocompleteResults"; | 562 DVLOG(1) << render_view << " GetAutocompleteResults"; |
573 const std::vector<InstantAutocompleteResult>& results = | 563 std::vector<InstantAutocompleteResultIDPair> results; |
574 SearchBox::Get(render_view)->GetAutocompleteResults(); | 564 SearchBox::Get(render_view)->GetAutocompleteResults(&results); |
575 size_t results_base = SearchBox::Get(render_view)->results_base(); | |
576 | 565 |
577 v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); | 566 v8::Handle<v8::Array> results_array = v8::Array::New(results.size()); |
578 for (size_t i = 0; i < results.size(); ++i) { | 567 for (size_t i = 0; i < results.size(); ++i) { |
579 v8::Handle<v8::Object> result = v8::Object::New(); | 568 v8::Handle<v8::Object> result = v8::Object::New(); |
580 result->Set(v8::String::New("provider"), | 569 result->Set(v8::String::New("provider"), |
581 UTF16ToV8String(results[i].provider)); | 570 UTF16ToV8String(results[i].second.provider)); |
582 result->Set(v8::String::New("type"), UTF16ToV8String(results[i].type)); | 571 result->Set(v8::String::New("type"), |
| 572 UTF16ToV8String(results[i].second.type)); |
583 result->Set(v8::String::New("contents"), | 573 result->Set(v8::String::New("contents"), |
584 UTF16ToV8String(results[i].description)); | 574 UTF16ToV8String(results[i].second.description)); |
585 result->Set(v8::String::New("destination_url"), | 575 result->Set(v8::String::New("destination_url"), |
586 UTF16ToV8String(results[i].destination_url)); | 576 UTF16ToV8String(results[i].second.destination_url)); |
587 result->Set(v8::String::New("rid"), v8::Uint32::New(results_base + i)); | 577 result->Set(v8::String::New("rid"), v8::Uint32::New(results[i].first)); |
588 | 578 |
589 v8::Handle<v8::Object> ranking_data = v8::Object::New(); | 579 v8::Handle<v8::Object> ranking_data = v8::Object::New(); |
590 ranking_data->Set(v8::String::New("relevance"), | 580 ranking_data->Set(v8::String::New("relevance"), |
591 v8::Int32::New(results[i].relevance)); | 581 v8::Int32::New(results[i].second.relevance)); |
592 result->Set(v8::String::New("rankingData"), ranking_data); | 582 result->Set(v8::String::New("rankingData"), ranking_data); |
593 | 583 |
594 results_array->Set(i, result); | 584 results_array->Set(i, result); |
595 } | 585 } |
596 return results_array; | 586 return results_array; |
597 } | 587 } |
598 | 588 |
599 // static | 589 // static |
600 v8::Handle<v8::Value> SearchBoxExtensionWrapper::IsKeyCaptureEnabled( | 590 v8::Handle<v8::Value> SearchBoxExtensionWrapper::IsKeyCaptureEnabled( |
601 const v8::Arguments& args) { | 591 const v8::Arguments& args) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 | 724 |
735 // static | 725 // static |
736 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateSearchBox( | 726 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateSearchBox( |
737 const v8::Arguments& args) { | 727 const v8::Arguments& args) { |
738 content::RenderView* render_view = GetRenderView(); | 728 content::RenderView* render_view = GetRenderView(); |
739 if (!render_view || !args.Length()) return v8::Undefined(); | 729 if (!render_view || !args.Length()) return v8::Undefined(); |
740 | 730 |
741 GURL destination_url; | 731 GURL destination_url; |
742 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; | 732 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; |
743 if (args[0]->IsNumber()) { | 733 if (args[0]->IsNumber()) { |
744 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 734 InstantAutocompleteResult result; |
745 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 735 if (SearchBox::Get(render_view)->GetAutocompleteResultWithID( |
746 if (result) { | 736 args[0]->IntegerValue(), &result)) { |
747 destination_url = GURL(result->destination_url); | 737 destination_url = GURL(result.destination_url); |
748 transition = result->transition; | 738 transition = result.transition; |
749 } | 739 } |
750 } else { | 740 } else { |
751 // Resolve the URL. | 741 // Resolve the URL. |
752 const string16& possibly_relative_url = V8ValueToUTF16(args[0]); | 742 const string16& possibly_relative_url = V8ValueToUTF16(args[0]); |
753 WebKit::WebView* webview = render_view->GetWebView(); | 743 WebKit::WebView* webview = render_view->GetWebView(); |
754 if (!possibly_relative_url.empty() && webview) { | 744 if (!possibly_relative_url.empty() && webview) { |
755 GURL current_url(webview->mainFrame()->document().url()); | 745 GURL current_url(webview->mainFrame()->document().url()); |
756 destination_url = current_url.Resolve(possibly_relative_url); | 746 destination_url = current_url.Resolve(possibly_relative_url); |
757 } | 747 } |
758 } | 748 } |
(...skipping 12 matching lines...) Expand all Loading... |
771 return v8::Undefined(); | 761 return v8::Undefined(); |
772 } | 762 } |
773 | 763 |
774 // static | 764 // static |
775 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateNewTabPage( | 765 v8::Handle<v8::Value> SearchBoxExtensionWrapper::NavigateNewTabPage( |
776 const v8::Arguments& args) { | 766 const v8::Arguments& args) { |
777 content::RenderView* render_view = GetRenderView(); | 767 content::RenderView* render_view = GetRenderView(); |
778 if (!render_view || !args.Length()) return v8::Undefined(); | 768 if (!render_view || !args.Length()) return v8::Undefined(); |
779 | 769 |
780 GURL destination_url; | 770 GURL destination_url; |
781 content::PageTransition transition = content::PAGE_TRANSITION_TYPED; | 771 content::PageTransition transition = content::PAGE_TRANSITION_AUTO_BOOKMARK; |
782 if (args[0]->IsNumber()) { | 772 if (args[0]->IsNumber()) { |
783 destination_url = MostVisitedItemIDToURL( | 773 InstantMostVisitedItem item; |
784 SearchBox::Get(render_view)->GetMostVisitedItems(), | 774 if (SearchBox::Get(render_view)->GetMostVisitedItemWithID( |
785 args[0]->Uint32Value()); | 775 args[0]->IntegerValue(), &item)) { |
786 transition = content::PAGE_TRANSITION_AUTO_BOOKMARK; | 776 destination_url = item.url; |
| 777 } |
787 } else { | 778 } else { |
788 destination_url = GURL(V8ValueToUTF16(args[0])); | 779 destination_url = GURL(V8ValueToUTF16(args[0])); |
789 } | 780 } |
790 | 781 |
791 DVLOG(1) << render_view << " NavigateNewTabPage: " << destination_url; | 782 DVLOG(1) << render_view << " NavigateNewTabPage: " << destination_url; |
792 | 783 |
793 // Navigate the main frame. | 784 // Navigate the main frame. |
794 if (destination_url.is_valid()) { | 785 if (destination_url.is_valid()) { |
795 WindowOpenDisposition disposition = CURRENT_TAB; | 786 WindowOpenDisposition disposition = CURRENT_TAB; |
796 if (args[1]->Uint32Value() == 2) | 787 if (args[1]->Uint32Value() == 2) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 } | 878 } |
888 | 879 |
889 // static | 880 // static |
890 v8::Handle<v8::Value> | 881 v8::Handle<v8::Value> |
891 SearchBoxExtensionWrapper::SetSuggestionFromAutocompleteResult( | 882 SearchBoxExtensionWrapper::SetSuggestionFromAutocompleteResult( |
892 const v8::Arguments& args) { | 883 const v8::Arguments& args) { |
893 content::RenderView* render_view = GetRenderView(); | 884 content::RenderView* render_view = GetRenderView(); |
894 if (!render_view || !args.Length()) return v8::Undefined(); | 885 if (!render_view || !args.Length()) return v8::Undefined(); |
895 | 886 |
896 DVLOG(1) << render_view << " SetSuggestionFromAutocompleteResult"; | 887 DVLOG(1) << render_view << " SetSuggestionFromAutocompleteResult"; |
897 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 888 InstantAutocompleteResult result; |
898 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 889 if (!SearchBox::Get(render_view)->GetAutocompleteResultWithID( |
899 if (!result) return v8::Undefined(); | 890 args[0]->IntegerValue(), &result)) { |
| 891 return v8::Undefined(); |
| 892 } |
900 | 893 |
901 // We only support selecting autocomplete results that are URLs. | 894 // We only support selecting autocomplete results that are URLs. |
902 string16 text = result->destination_url; | 895 string16 text = result.destination_url; |
903 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; | 896 InstantCompleteBehavior behavior = INSTANT_COMPLETE_NOW; |
904 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | 897 InstantSuggestionType type = INSTANT_SUGGESTION_URL; |
905 | 898 |
906 SearchBox* search_box = SearchBox::Get(render_view); | 899 SearchBox* search_box = SearchBox::Get(render_view); |
907 std::vector<InstantSuggestion> suggestions; | 900 std::vector<InstantSuggestion> suggestions; |
908 suggestions.push_back( | 901 suggestions.push_back( |
909 InstantSuggestion(text, behavior, type, search_box->query())); | 902 InstantSuggestion(text, behavior, type, search_box->query())); |
910 search_box->SetSuggestions(suggestions); | 903 search_box->SetSuggestions(suggestions); |
911 | 904 |
912 return v8::Undefined(); | 905 return v8::Undefined(); |
(...skipping 22 matching lines...) Expand all Loading... |
935 return v8::Undefined(); | 928 return v8::Undefined(); |
936 } | 929 } |
937 | 930 |
938 v8::Handle<v8::Value> | 931 v8::Handle<v8::Value> |
939 SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( | 932 SearchBoxExtensionWrapper::SetQueryFromAutocompleteResult( |
940 const v8::Arguments& args) { | 933 const v8::Arguments& args) { |
941 content::RenderView* render_view = GetRenderView(); | 934 content::RenderView* render_view = GetRenderView(); |
942 if (!render_view || !args.Length()) return v8::Undefined(); | 935 if (!render_view || !args.Length()) return v8::Undefined(); |
943 | 936 |
944 DVLOG(1) << render_view << " SetQueryFromAutocompleteResult"; | 937 DVLOG(1) << render_view << " SetQueryFromAutocompleteResult"; |
945 const InstantAutocompleteResult* result = SearchBox::Get(render_view)-> | 938 InstantAutocompleteResult result; |
946 GetAutocompleteResultWithId(args[0]->Uint32Value()); | 939 if (!SearchBox::Get(render_view)->GetAutocompleteResultWithID( |
947 if (!result) return v8::Undefined(); | 940 args[0]->IntegerValue(), &result)) { |
| 941 return v8::Undefined(); |
| 942 } |
948 | 943 |
949 // We only support selecting autocomplete results that are URLs. | 944 // We only support selecting autocomplete results that are URLs. |
950 string16 text = result->destination_url; | 945 string16 text = result.destination_url; |
951 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; | 946 InstantCompleteBehavior behavior = INSTANT_COMPLETE_REPLACE; |
952 // TODO(jered): Distinguish between history URLs and search provider | 947 // TODO(jered): Distinguish between history URLs and search provider |
953 // navsuggest URLs so that we can do proper accounting on history URLs. | 948 // navsuggest URLs so that we can do proper accounting on history URLs. |
954 InstantSuggestionType type = INSTANT_SUGGESTION_URL; | 949 InstantSuggestionType type = INSTANT_SUGGESTION_URL; |
955 | 950 |
956 SearchBox* search_box = SearchBox::Get(render_view); | 951 SearchBox* search_box = SearchBox::Get(render_view); |
957 std::vector<InstantSuggestion> suggestions; | 952 std::vector<InstantSuggestion> suggestions; |
958 suggestions.push_back( | 953 suggestions.push_back( |
959 InstantSuggestion(text, behavior, type, search_box->query())); | 954 InstantSuggestion(text, behavior, type, search_box->query())); |
960 search_box->SetSuggestions(suggestions); | 955 search_box->SetSuggestions(suggestions); |
(...skipping 26 matching lines...) Expand all Loading... |
987 // static | 982 // static |
988 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( | 983 v8::Handle<v8::Value> SearchBoxExtensionWrapper::GetMostVisitedItems( |
989 const v8::Arguments& args) { | 984 const v8::Arguments& args) { |
990 content::RenderView* render_view = GetRenderView(); | 985 content::RenderView* render_view = GetRenderView(); |
991 if (!render_view) | 986 if (!render_view) |
992 return v8::Undefined(); | 987 return v8::Undefined(); |
993 DVLOG(1) << render_view << " GetMostVisitedItems"; | 988 DVLOG(1) << render_view << " GetMostVisitedItems"; |
994 | 989 |
995 const SearchBox* search_box = SearchBox::Get(render_view); | 990 const SearchBox* search_box = SearchBox::Get(render_view); |
996 | 991 |
997 const std::vector<InstantMostVisitedItem>& instant_mv_items = | 992 std::vector<InstantMostVisitedItemIDPair> instant_mv_items; |
998 search_box->GetMostVisitedItems(); | 993 search_box->GetMostVisitedItems(&instant_mv_items); |
999 v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); | 994 v8::Handle<v8::Array> v8_mv_items = v8::Array::New(instant_mv_items.size()); |
1000 for (size_t i = 0; i < instant_mv_items.size(); ++i) { | 995 for (size_t i = 0; i < instant_mv_items.size(); ++i) { |
1001 // We set the "dir" attribute of the title, so that in RTL locales, a LTR | 996 // We set the "dir" attribute of the title, so that in RTL locales, a LTR |
1002 // title is rendered left-to-right and truncated from the right. For | 997 // title is rendered left-to-right and truncated from the right. For |
1003 // example, the title of http://msdn.microsoft.com/en-us/default.aspx is | 998 // example, the title of http://msdn.microsoft.com/en-us/default.aspx is |
1004 // "MSDN: Microsoft developer network". In RTL locales, in the New Tab | 999 // "MSDN: Microsoft developer network". In RTL locales, in the New Tab |
1005 // page, if the "dir" of this title is not specified, it takes Chrome UI's | 1000 // page, if the "dir" of this title is not specified, it takes Chrome UI's |
1006 // directionality. So the title will be truncated as "soft developer | 1001 // directionality. So the title will be truncated as "soft developer |
1007 // network". Setting the "dir" attribute as "ltr" renders the truncated | 1002 // network". Setting the "dir" attribute as "ltr" renders the truncated |
1008 // title as "MSDN: Microsoft D...". As another example, the title of | 1003 // title as "MSDN: Microsoft D...". As another example, the title of |
1009 // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the | 1004 // http://yahoo.com is "Yahoo!". In RTL locales, in the New Tab page, the |
1010 // title will be rendered as "!Yahoo" if its "dir" attribute is not set to | 1005 // title will be rendered as "!Yahoo" if its "dir" attribute is not set to |
1011 // "ltr". | 1006 // "ltr". |
| 1007 const InstantMostVisitedItem& mv_item = instant_mv_items[i].second; |
1012 std::string direction; | 1008 std::string direction; |
1013 if (base::i18n::StringContainsStrongRTLChars(instant_mv_items[i].title)) | 1009 if (base::i18n::StringContainsStrongRTLChars(mv_item.title)) |
1014 direction = kRTLHtmlTextDirection; | 1010 direction = kRTLHtmlTextDirection; |
1015 else | 1011 else |
1016 direction = kLTRHtmlTextDirection; | 1012 direction = kLTRHtmlTextDirection; |
1017 | 1013 |
1018 string16 title = instant_mv_items[i].title; | 1014 string16 title = mv_item.title; |
1019 if (title.empty()) | 1015 if (title.empty()) |
1020 title = UTF8ToUTF16(instant_mv_items[i].url.spec()); | 1016 title = UTF8ToUTF16(mv_item.url.spec()); |
1021 | 1017 |
| 1018 InstantRestrictedID restricted_id = instant_mv_items[i].first; |
1022 v8::Handle<v8::Object> item = v8::Object::New(); | 1019 v8::Handle<v8::Object> item = v8::Object::New(); |
1023 item->Set(v8::String::New("rid"), | 1020 item->Set(v8::String::New("rid"), v8::Int32::New(restricted_id)); |
1024 v8::Int32::New(instant_mv_items[i].most_visited_item_id)); | |
1025 item->Set(v8::String::New("thumbnailUrl"), | 1021 item->Set(v8::String::New("thumbnailUrl"), |
1026 GenerateThumbnailURL(instant_mv_items[i].most_visited_item_id)); | 1022 GenerateThumbnailURL(restricted_id)); |
1027 item->Set(v8::String::New("faviconUrl"), | 1023 item->Set(v8::String::New("faviconUrl"), |
1028 GenerateFaviconURL(instant_mv_items[i].most_visited_item_id)); | 1024 GenerateFaviconURL(restricted_id)); |
1029 item->Set(v8::String::New("title"), | 1025 item->Set(v8::String::New("title"), UTF16ToV8String(title)); |
1030 UTF16ToV8String(title)); | 1026 item->Set(v8::String::New("domain"), UTF8ToV8String(mv_item.url.host())); |
1031 item->Set(v8::String::New("domain"), | |
1032 UTF8ToV8String(instant_mv_items[i].url.host())); | |
1033 item->Set(v8::String::New("direction"), UTF8ToV8String(direction)); | 1027 item->Set(v8::String::New("direction"), UTF8ToV8String(direction)); |
1034 | 1028 |
1035 v8_mv_items->Set(i, item); | 1029 v8_mv_items->Set(i, item); |
1036 } | 1030 } |
1037 return v8_mv_items; | 1031 return v8_mv_items; |
1038 } | 1032 } |
1039 | 1033 |
1040 // static | 1034 // static |
1041 v8::Handle<v8::Value> SearchBoxExtensionWrapper::DeleteMostVisitedItem( | 1035 v8::Handle<v8::Value> SearchBoxExtensionWrapper::DeleteMostVisitedItem( |
1042 const v8::Arguments& args) { | 1036 const v8::Arguments& args) { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 void SearchBoxExtension::DispatchMostVisitedChanged( | 1197 void SearchBoxExtension::DispatchMostVisitedChanged( |
1204 WebKit::WebFrame* frame) { | 1198 WebKit::WebFrame* frame) { |
1205 Dispatch(frame, kDispatchMostVisitedChangedScript); | 1199 Dispatch(frame, kDispatchMostVisitedChangedScript); |
1206 } | 1200 } |
1207 | 1201 |
1208 void SearchBoxExtension::DispatchBarsHidden(WebKit::WebFrame* frame) { | 1202 void SearchBoxExtension::DispatchBarsHidden(WebKit::WebFrame* frame) { |
1209 Dispatch(frame, kDispatchBarsHiddenEventScript); | 1203 Dispatch(frame, kDispatchBarsHiddenEventScript); |
1210 } | 1204 } |
1211 | 1205 |
1212 } // namespace extensions_v8 | 1206 } // namespace extensions_v8 |
OLD | NEW |