Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4614)

Unified Diff: chrome/browser/webshare/share_service_impl.cc

Issue 2564483003: Default share to Share Target: Partial impl. of Web Share for Desktop. (Closed)
Patch Set: Updated documentation Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/webshare/share_service_impl.cc
diff --git a/chrome/browser/webshare/share_service_impl.cc b/chrome/browser/webshare/share_service_impl.cc
index 9f8bb0b690e52854f780fdcc5373e8efd5062a3b..01ba0908c7a12e46ce6fefe0f0cb36306fdc6e59 100644
--- a/chrome/browser/webshare/share_service_impl.cc
+++ b/chrome/browser/webshare/share_service_impl.cc
@@ -4,7 +4,17 @@
#include "chrome/browser/webshare/share_service_impl.h"
+#include <algorithm>
+#include <functional>
+#include <utility>
+
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "net/base/escape.h"
// static
void ShareServiceImpl::Create(blink::mojom::ShareServiceRequest request) {
@@ -12,11 +22,131 @@ void ShareServiceImpl::Create(blink::mojom::ShareServiceRequest request) {
std::move(request));
}
+// static
+int ShareServiceImpl::ReplacePlaceholders(const std::string& url_template,
+ const std::string& title,
+ const std::string& text,
+ const GURL& share_url,
+ std::string* url_template_filled) {
+ std::string title_escaped = net::EscapeQueryParamValue(title, false);
+ std::string text_escaped = net::EscapeQueryParamValue(text, false);
+ std::string share_url_escaped =
+ net::EscapeQueryParamValue(share_url.spec(), false);
+
+ constexpr char kTitlePlaceholder[] = "%{title}";
Matt Giuca 2017/01/05 03:09:25 It would be much nicer I think if we could avoid h
constantina 2017/01/09 02:12:43 Done.
+ constexpr char kTextPlaceholder[] = "%{text}";
+ constexpr char kUrlPlaceholder[] = "%{url}";
+
+ std::vector<base::StringPiece> placeholders = {
+ kTitlePlaceholder, kTextPlaceholder, kUrlPlaceholder};
+
+ std::vector<base::StringPiece> share_data = {title_escaped, text_escaped,
+ share_url_escaped};
+
+ std::map<base::StringPiece, base::StringPiece> placeholder_to_data;
+ for (size_t i = 0; i < placeholders.size(); ++i) {
Matt Giuca 2017/01/05 03:09:25 I think this would read much clearer if it was jus
constantina 2017/01/09 02:12:42 Done.
+ placeholder_to_data[placeholders[i]] = share_data[i];
+ }
+
+ // Find open ("%{") and close ("}") identifiers, and record indices.
+ // If two opens occur before a close, or a close occurs with no preceding
+ // open, return an error code.
Matt Giuca 2017/01/05 03:09:25 I think we could change this rule to *only* allow
constantina 2017/01/09 02:12:43 Done. Not sure if this is the way you wanted it im
+ std::vector<int> placeholder_open_indices;
Matt Giuca 2017/01/05 03:09:25 Can we make this a std::vector<std::pair<int, int>
Sam McNally 2017/01/05 04:08:37 std::vector<base::StringPiece> is a nice way to mo
Matt Giuca 2017/01/05 05:00:13 I agree, that sounds good, as long as you can figu
constantina 2017/01/09 02:12:42 Reimplemented algo to allow for this.
+ std::vector<int> placeholder_close_indices;
+ bool last_saw_open = false;
+ for (size_t i = 0; i < url_template.size(); ++i) {
+ if (url_template[i] == '%' && i < url_template.size() &&
Matt Giuca 2017/01/05 03:09:25 i + 1 < url_template.size() ^^^
constantina 2017/01/09 02:12:42 Done.
+ url_template[i + 1] == '{') {
+ if (last_saw_open) {
+ *url_template_filled = url_template;
Matt Giuca 2017/01/05 03:09:25 Why populate |url_template_filled| at all on error
Sam McNally 2017/01/05 04:08:37 Don't change |*url_template_filled| on failure.
constantina 2017/01/09 02:12:42 Done.
+ return 1;
Matt Giuca 2017/01/05 03:09:25 Please comment each error case why it is an error.
constantina 2017/01/09 02:12:43 Done.
+ }
+ last_saw_open = true;
+ placeholder_open_indices.push_back(i);
+ } else if (url_template[i] == '}') {
+ if (!last_saw_open) {
Matt Giuca 2017/01/05 03:09:25 We could just not make this an error. It isn't nec
constantina 2017/01/09 02:12:43 Done.
+ *url_template_filled = url_template;
+ return 1;
+ }
+ last_saw_open = false;
+ placeholder_close_indices.push_back(i);
+ }
+ }
+ if (last_saw_open) {
+ *url_template_filled = url_template;
+ return 1;
Matt Giuca 2017/01/05 03:09:25 Comment why this is an error.
constantina 2017/01/09 02:12:42 Done.
+ }
+
+ // Reserve memory for filled template, assuming all placeholders are replaced
Matt Giuca 2017/01/05 03:09:25 This function is getting pretty big. Maybe break o
Sam McNally 2017/01/05 04:08:37 Use the real sizes.
Matt Giuca 2017/01/05 05:00:13 Do you mean actually calculate the final size befo
Sam McNally 2017/01/05 05:41:49 Yes. The mapping from placeholder to value can be
constantina 2017/01/09 02:12:42 Incorporated as part of the new implementation.
+ // with the largest share data field.
+ int placeholder_char_count = 0;
Matt Giuca 2017/01/05 03:09:25 I would suggest not to worry about this. You don't
constantina 2017/01/09 02:12:43 New implementation means this is easily accounted
+ for (size_t i = 0; i < placeholder_open_indices.size(); ++i) {
+ placeholder_char_count +=
+ placeholder_close_indices[i] - placeholder_open_indices[i] + 1;
+ }
+ size_t largest_share_datum = 0;
Matt Giuca 2017/01/05 03:09:25 Comment here to explain why you're doing this.
constantina 2017/01/09 02:12:43 Gone with new impl.
+ for (base::StringPiece datum : share_data) {
+ if (datum.size() >= largest_share_datum) {
+ largest_share_datum = datum.size();
+ }
+ }
+ *url_template_filled = "";
Sam McNally 2017/01/05 04:08:37 ->clear();
constantina 2017/01/09 02:12:42 Done.
+ url_template_filled->reserve(url_template.size() - placeholder_char_count +
+ largest_share_datum *
+ placeholder_open_indices.size());
+
+ // Look at each placeholder, and check if it is valid.
Matt Giuca 2017/01/05 03:09:25 What does "valid" mean? You mean one of the recogn
constantina 2017/01/09 02:12:42 Gone.
+ // If it is, replace the placeholder with its corresponding share datum.
+ // Otherwise, replace it with an empty string.
+ int start_index_to_copy = 0;
+ for (size_t i = 0; i < placeholder_open_indices.size(); ++i) {
+ int placeholder_open = placeholder_open_indices[i];
+ int placeholder_close = placeholder_close_indices[i];
+
+ *url_template_filled += url_template.substr(
+ start_index_to_copy, placeholder_open - start_index_to_copy);
+
+ base::StringPiece placeholder = url_template.substr(
Sam McNally 2017/01/05 04:08:37 This is dangling unless |url_template| is a String
constantina 2017/01/09 02:12:43 Gone.
+ placeholder_open, placeholder_close + 1 - placeholder_open);
+
+ std::map<base::StringPiece, base::StringPiece>::iterator it =
+ placeholder_to_data.find(placeholder);
+ if (it != placeholder_to_data.end()) {
+ it->second.AppendToString(url_template_filled);
+ }
+ start_index_to_copy = placeholder_close + 1;
+ }
+ *url_template_filled += url_template.substr(start_index_to_copy);
+ return 0;
+}
+
+void ShareServiceImpl::OpenTargetURL(const GURL& target_url) {
+ Browser* browser = BrowserList::GetInstance()->GetLastActive();
+ chrome::AddTabAt(browser, target_url,
+ browser->tab_strip_model()->active_index() + 1, true);
+}
+
void ShareServiceImpl::Share(const std::string& title,
const std::string& text,
- const GURL& url,
+ const GURL& share_url,
const ShareCallback& callback) {
- // TODO(constantina): Implement Web Share Target here.
- NOTIMPLEMENTED();
- callback.Run(base::Optional<std::string>("Not implemented: navigator.share"));
+ bool error_occured = false;
+
+ const char kUrlBase[] = "https://wicg.github.io/web-share-target/";
+ std::string url_template =
Sam McNally 2017/01/05 04:08:37 constexpr char kUrlTemplate[] =
constantina 2017/01/09 02:12:42 Done.
Matt Giuca 2017/01/09 03:56:54 You still need to rename to kUrlTemplate.
constantina 2017/01/09 23:51:03 Done.
+ "demos/sharetarget.html?title=%{title}&text=%{text}&url=%{url}";
+
+ std::string url_template_filled;
+ int error = ReplacePlaceholders(url_template, title, text, share_url,
+ &url_template_filled);
+ error_occured |= error;
Matt Giuca 2017/01/05 03:09:25 No point having error_occurred if it only gets set
constantina 2017/01/09 02:12:43 Done.
+
+ GURL target_url(kUrlBase + url_template_filled);
+ OpenTargetURL(target_url);
Sam McNally 2017/01/05 04:08:37 Why open the URL if substitution fails?
constantina 2017/01/09 02:12:42 Done.
+
+ if (error_occured) {
+ callback.Run(base::Optional<std::string>("Error"));
+ } else {
+ callback.Run(base::Optional<std::string>());
+ }
}

Powered by Google App Engine
This is Rietveld 408576698