OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/browser/webshare/share_service_impl.h" | 5 #include "chrome/browser/webshare/share_service_impl.h" |
6 | 6 |
7 #include <algorithm> | |
8 #include <functional> | |
9 #include <utility> | |
10 | |
11 #include "chrome/browser/ui/browser.h" | |
12 #include "chrome/browser/ui/browser_commands.h" | |
13 #include "chrome/browser/ui/browser_list.h" | |
14 #include "chrome/browser/ui/browser_tabstrip.h" | |
15 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
7 #include "mojo/public/cpp/bindings/strong_binding.h" | 16 #include "mojo/public/cpp/bindings/strong_binding.h" |
17 #include "net/base/escape.h" | |
8 | 18 |
9 // static | 19 // static |
10 void ShareServiceImpl::Create(blink::mojom::ShareServiceRequest request) { | 20 void ShareServiceImpl::Create(blink::mojom::ShareServiceRequest request) { |
11 mojo::MakeStrongBinding(base::MakeUnique<ShareServiceImpl>(), | 21 mojo::MakeStrongBinding(base::MakeUnique<ShareServiceImpl>(), |
12 std::move(request)); | 22 std::move(request)); |
13 } | 23 } |
14 | 24 |
25 // static | |
26 std::string ShareServiceImpl::ReplacePlaceholders( | |
27 const std::string url_template, | |
28 const std::string title, | |
29 const std::string text, | |
30 const GURL& share_url, | |
31 int* error) { | |
32 std::string title_escaped = net::EscapeQueryParamValue(title, false); | |
33 std::string text_escaped = net::EscapeQueryParamValue(text, false); | |
34 std::string share_url_escaped = | |
35 net::EscapeQueryParamValue(share_url.spec(), false); | |
36 | |
37 constexpr char kTitlePlaceholder[] = "%{title}"; | |
38 constexpr char kTextPlaceholder[] = "%{text}"; | |
39 constexpr char kUrlPlaceholder[] = "%{url}"; | |
40 | |
41 std::vector<base::StringPiece> placeholders; | |
42 placeholders.push_back(kTitlePlaceholder); | |
43 placeholders.push_back(kTextPlaceholder); | |
44 placeholders.push_back(kUrlPlaceholder); | |
45 | |
46 std::vector<base::StringPiece> share_data; | |
47 share_data.push_back(title_escaped); | |
48 share_data.push_back(text_escaped); | |
49 share_data.push_back(share_url_escaped); | |
50 | |
51 std::map<base::StringPiece, base::StringPiece> placeholder_to_data; | |
Sam McNally
2017/01/04 09:15:46
You could use an initializer list to initialise th
constantina
2017/01/05 00:34:38
I will keep it like this, in case we expand the AP
| |
52 for (unsigned long i = 0; i < placeholders.size(); ++i) { | |
53 placeholder_to_data[placeholders[i]] = share_data[i]; | |
54 } | |
55 | |
56 // Find open ("%{") and close ("}") identifiers, and record indices. | |
57 // If two opens occur before a close, or a close occurs with no preceding | |
58 // open, return an error code. | |
59 std::vector<int> placeholder_open_indices; | |
Sam McNally
2017/01/04 09:15:46
Consider building a std::vector<base::StringPiece>
constantina
2017/01/05 00:34:38
Acknowledged.
| |
60 std::vector<int> placeholder_close_indices; | |
61 bool lastSawOpen = false; | |
Sam McNally
2017/01/04 09:15:46
last_saw_open
constantina
2017/01/05 00:34:38
Done.
| |
62 for (unsigned long i = 0; i < url_template.size(); ++i) { | |
Sam McNally
2017/01/04 09:15:46
size_t
constantina
2017/01/05 00:34:38
Done.
| |
63 if (url_template[i] == '%' && i < url_template.size() && | |
64 url_template[i + 1] == '{') { | |
65 if (lastSawOpen) { | |
66 *error = 1; | |
67 return url_template; | |
68 } | |
69 lastSawOpen = true; | |
70 placeholder_open_indices.push_back(i); | |
71 } else if (url_template[i] == '}') { | |
72 if (!lastSawOpen) { | |
73 *error = 1; | |
74 return url_template; | |
75 } | |
76 lastSawOpen = false; | |
77 placeholder_close_indices.push_back(i); | |
78 } | |
79 } | |
80 if (lastSawOpen) { | |
81 *error = 1; | |
82 return url_template; | |
83 } | |
84 | |
85 // Look at each placeholder, and check if it is valid. | |
86 // If it is, replace the placeholder with its corresponding share datum. | |
87 // Otherwise, replace it with an empty string. | |
88 std::string url_template_filled = ""; | |
Sam McNally
2017/01/04 09:15:46
The default constructor is fine. It's probably wor
constantina
2017/01/05 00:34:38
Done.
| |
89 int start_index_to_copy = 0; | |
Sam McNally
2017/01/04 09:15:46
size_t
constantina
2017/01/05 00:34:38
Done.
| |
90 for (unsigned long i = 0; i < placeholder_open_indices.size(); ++i) { | |
91 int placeholder_open = placeholder_open_indices[i]; | |
92 int placeholder_close = placeholder_close_indices[i]; | |
93 | |
94 url_template_filled += url_template.substr( | |
95 start_index_to_copy, placeholder_open - start_index_to_copy); | |
96 | |
97 base::StringPiece placeholder = url_template.substr( | |
98 placeholder_open, placeholder_close + 1 - placeholder_open); | |
99 | |
100 if (placeholder_to_data.count(placeholder)) { | |
Sam McNally
2017/01/04 09:15:46
Use placeholder_to_data.find(). This avoids a seco
constantina
2017/01/05 00:34:38
Done.
| |
101 url_template_filled += placeholder_to_data[placeholder].as_string(); | |
Sam McNally
2017/01/04 09:15:46
Use placeholder_to_data[placeholder].AppendToStrin
constantina
2017/01/05 00:34:38
Done.
| |
102 } | |
103 start_index_to_copy = placeholder_close + 1; | |
104 } | |
105 url_template_filled += url_template.substr(start_index_to_copy); | |
106 *error = 0; | |
107 return url_template_filled; | |
108 } | |
109 | |
110 void ShareServiceImpl::OpenTargetURL(const GURL& target_url) { | |
111 Browser* browser = BrowserList::GetInstance()->GetLastActive(); | |
112 chrome::AddTabAt(browser, target_url, | |
113 browser->tab_strip_model()->active_index() + 1, true); | |
114 } | |
115 | |
15 void ShareServiceImpl::Share(const std::string& title, | 116 void ShareServiceImpl::Share(const std::string& title, |
16 const std::string& text, | 117 const std::string& text, |
17 const GURL& url, | 118 const GURL& share_url, |
18 const ShareCallback& callback) { | 119 const ShareCallback& callback) { |
19 // TODO(constantina): Implement Web Share Target here. | 120 bool error_occured = false; |
20 NOTIMPLEMENTED(); | 121 |
21 callback.Run(base::Optional<std::string>("Not implemented: navigator.share")); | 122 const char kUrlBase[] = "https://wicg.github.io/web-share-target/"; |
123 std::string url_template = | |
124 "demos/sharetarget.html?title=%{title}&text=%{text}&url=%{url}"; | |
125 | |
126 int error = 0; | |
127 std::string url_template_filled = | |
128 ReplacePlaceholders(url_template, title, text, share_url, &error); | |
129 error_occured |= error; | |
130 | |
131 GURL target_url(kUrlBase + url_template_filled); | |
132 OpenTargetURL(target_url); | |
133 | |
134 if (error_occured) { | |
135 callback.Run(base::Optional<std::string>("Error")); | |
136 } else { | |
137 callback.Run(base::Optional<std::string>()); | |
138 } | |
22 } | 139 } |
OLD | NEW |