Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: Added Copy Clean URL item #14234

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/brave_command_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define IDC_APP_MENU_IPFS_OPEN_FILES 56037
#define IDC_APP_MENU_IPFS_UPDATE_IPNS 56038
#define IDC_CONTENT_CONTEXT_FORCE_PASTE 56039
#define IDC_CONTENT_CONTEXT_COPYCLEANLINKLOCATION 56040

#define IDC_CONTENT_CONTEXT_IMPORT_IPNS_KEYS_START 56100
#define IDC_CONTENT_CONTEXT_IMPORT_IPNS_KEYS_END 56199
Expand Down
4 changes: 3 additions & 1 deletion app/brave_generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,9 @@ Or change later at <ph name="SETTINGS_EXTENIONS_LINK">$2<ex>brave://settings/ext
<message name="IDS_IMPORTED_FROM_BOOKMARK_FOLDER" desc="Name for bookmark panel folder imported from another browser">
Imported from <ph name="BROWSER_NAME">$1<ex>Chrome</ex></ph>.
</message>

<message name="IDS_CONTENT_CONTEXT_COPYCLEANLINKLOCATION" desc="The name of the context menu item to copy clean address location">
Copy clean link address
</message>
<!--Add new items to the appropriate sections above -->
</messages>
</release>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ bool BraveRenderViewContextMenu::IsCommandIdEnabled(int id) const {
// IsPasteAndMatchStyleEnabled checks internally, but IsPasteEnabled
// allows non text types
return IsPasteAndMatchStyleEnabled();
case IDC_CONTENT_CONTEXT_COPYCLEANLINKLOCATION:
return params_.unfiltered_link_url.is_valid();
#if BUILDFLAG(ENABLE_IPFS)
case IDC_CONTENT_CONTEXT_IMPORT_IPFS:
case IDC_CONTENT_CONTEXT_IMPORT_IPFS_PAGE:
Expand Down Expand Up @@ -221,8 +223,18 @@ void BraveRenderViewContextMenu::ExecuteIPFSCommand(int id, int event_flags) {
}
#endif

void BraveRenderViewContextMenu::WriteCleanURLToClipboard(const GURL& url) {
GURL::Replacements replacements;
replacements.SetPathStr(url.path_piece());
WriteURLToClipboard(url.GetWithEmptyPath().ReplaceComponents(replacements));
}

void BraveRenderViewContextMenu::ExecuteCommand(int id, int event_flags) {
switch (id) {
case IDC_CONTENT_CONTEXT_COPYCLEANLINKLOCATION:
WriteCleanURLToClipboard(params_.unfiltered_link_url);
break;

case IDC_CONTENT_CONTEXT_FORCE_PASTE: {
std::u16string result;
ui::Clipboard::GetForCurrentThread()->ReadText(
Expand Down Expand Up @@ -370,6 +382,16 @@ void BraveRenderViewContextMenu::BuildIPFSMenu() {
}
#endif

void BraveRenderViewContextMenu::AddCleanCopyLinkItem() {
int index =
menu_model_.GetIndexOfCommandId(IDC_CONTENT_CONTEXT_COPYLINKLOCATION);
if (index != -1) {
menu_model_.InsertItemWithStringIdAt(
index + 1, IDC_CONTENT_CONTEXT_COPYCLEANLINKLOCATION,
IDS_CONTENT_CONTEXT_COPYCLEANLINKLOCATION);
}
}

void BraveRenderViewContextMenu::InitMenu() {
RenderViewContextMenu_Chromium::InitMenu();

Expand Down Expand Up @@ -406,6 +428,7 @@ void BraveRenderViewContextMenu::InitMenu() {
#if BUILDFLAG(ENABLE_IPFS)
BuildIPFSMenu();
#endif
AddCleanCopyLinkItem();

#if BUILDFLAG(ENABLE_BRAVE_TRANSLATE_GO)
const bool remove_translate =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class BraveRenderViewContextMenu : public RenderViewContextMenu_Chromium {
static void AddSpellCheckServiceItem(ui::SimpleMenuModel* menu,
bool is_checked);
void AddAccessibilityLabelsServiceItem(bool is_checked) override;
void AddCleanCopyLinkItem();
void WriteCleanURLToClipboard(const GURL& url);

private:
// RenderViewContextMenuBase:
Expand Down
22 changes: 22 additions & 0 deletions components/url_sanitizer/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

source_set("url_sanitizer") {
sources = [
"url_sanitizer.cc",
"url_sanitizer.h"
]
deps = [
"//base",
"//third_party/re2"
]
}

source_set("unittests") {
testonly = true

sources = [ "url_sanitizer_unittest.cc" ]

deps = [
":url_sanitizer",
"//testing/gtest"
]
}
3 changes: 3 additions & 0 deletions components/url_sanitizer/DEPS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include_rules = [
"+third_party/re2"
]
97 changes: 97 additions & 0 deletions components/url_sanitizer/url_sanitizer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "brave/components/url_sanitizer/url_sanitizer.h"

#include "base/containers/fixed_flat_map.h"
#include "base/containers/fixed_flat_set.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "third_party/re2/src/re2/re2.h"

namespace brave {

namespace {
static constexpr auto kSimpleQueryStringTrackers =
base::MakeFixedFlatSet<base::StringPiece>(
{// https://github.com/brave/brave-browser/issues/4239
"fbclid", "gclid", "msclkid", "mc_eid",
// https://github.com/brave/brave-browser/issues/9879
"dclid",
// https://github.com/brave/brave-browser/issues/13644
"oly_anon_id", "oly_enc_id",
// https://github.com/brave/brave-browser/issues/11579
"_openstat",
// https://github.com/brave/brave-browser/issues/11817
"vero_conv", "vero_id",
// https://github.com/brave/brave-browser/issues/13647
"wickedid",
// https://github.com/brave/brave-browser/issues/11578
"yclid",
// https://github.com/brave/brave-browser/issues/8975
"__s",
// https://github.com/brave/brave-browser/issues/17451
"rb_clickid",
// https://github.com/brave/brave-browser/issues/17452
"s_cid",
// https://github.com/brave/brave-browser/issues/17507
"ml_subscriber", "ml_subscriber_hash",
// https://github.com/brave/brave-browser/issues/18020
"twclid",
// https://github.com/brave/brave-browser/issues/18758
"gbraid", "wbraid",
// https://github.com/brave/brave-browser/issues/9019
"_hsenc", "__hssc", "__hstc", "__hsfp", "hsCtaTracking",
// https://github.com/brave/brave-browser/issues/22082
"oft_id", "oft_k", "oft_lk", "oft_d", "oft_c", "oft_ck", "oft_ids",
"oft_sk",
// https://github.com/brave/brave-browser/issues/11580
"igshid"});

static constexpr auto kConditionalQueryStringTrackers =
base::MakeFixedFlatMap<base::StringPiece, base::StringPiece>(
{// https://github.com/brave/brave-browser/issues/9018
{"mkt_tok", "[uU]nsubscribe"}});

}

// Remove tracking query parameters from a GURL, leaving all
// other parts untouched.
// static
std::string URLSanitizer::StripQueryParameter(const std::string& query,
const std::string& spec) {
// We are using custom query string parsing code here. See
// https://github.com/brave/brave-core/pull/13726#discussion_r897712350
// for more information on why this approach was selected.
//
// Split query string by ampersands, remove tracking parameters,
// then join the remaining query parameters, untouched, back into
// a single query string.
const std::vector<std::string> input_kv_strings =
SplitString(query, "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
std::vector<std::string> output_kv_strings;
int disallowed_count = 0;
for (const std::string& kv_string : input_kv_strings) {
const std::vector<std::string> pieces = SplitString(
kv_string, "=", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
const std::string& key = pieces.empty() ? "" : pieces[0];
if (pieces.size() >= 2 &&
(kSimpleQueryStringTrackers.count(key) == 1 ||
(kConditionalQueryStringTrackers.count(key) == 1 &&
!re2::RE2::PartialMatch(
spec, kConditionalQueryStringTrackers.at(key).data())))) {
++disallowed_count;
} else {
output_kv_strings.push_back(kv_string);
}
}
if (disallowed_count > 0) {
return base::JoinString(output_kv_strings, "&");
} else {
return query;
}
}

} // namespace brave
28 changes: 28 additions & 0 deletions components/url_sanitizer/url_sanitizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_COMPONENTS_URL_SANITIZER_URL_SANITIZER_H_
#define BRAVE_COMPONENTS_URL_SANITIZER_URL_SANITIZER_H_

#include <string>

namespace brave {

class URLSanitizer {
public:
URLSanitizer() = default;
~URLSanitizer() = default;


// Remove tracking query parameters from a GURL, leaving all
// other parts untouched.
static std::string StripQueryParameter(const std::string& query,
const std::string& spec);

};

} // namesapce brave

#endif // BRAVE_COMPONENTS_URL_SANITIZER_URL_SANITIZER_H_
13 changes: 13 additions & 0 deletions components/url_sanitizer/url_sanitizer_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "brave/components/url_sanitizer/url_sanitizer.h"

#include "url/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace brave {

TEST(URLSanitizer, StripQueryParameter) {
GURL initial_url("https://some.url/path?fbclid=11&param1=1");
EXPECT_EQ(URLSanitizer::StripQueryParameter(initial_url.query(), initial_url.spec()), "param1=1");
}

} // namespace brave
1 change: 1 addition & 0 deletions test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ test("brave_unit_tests") {
"//brave/components/sync/engine:unit_tests",
"//brave/components/time_period_storage",
"//brave/components/tor:tor_unit_tests",
"//brave/components/url_sanitizer:unittests",
"//brave/components/tor/buildflags",
"//brave/components/translate/core/common:buildflags",
"//brave/extensions:common",
Expand Down