Skip to content

Commit

Permalink
Merge pull request #8159 from brave/pr8152_cosmetic_filters_extension…
Browse files Browse the repository at this point in the history
…_1.21.x

adds a flag to use native/extension cosmetic filters approach on desktop(1.21.x)
  • Loading branch information
kjozwiak authored Mar 6, 2021
2 parents d37d9ea + 42c9f1b commit a586e00
Show file tree
Hide file tree
Showing 21 changed files with 1,035 additions and 7 deletions.
4 changes: 0 additions & 4 deletions browser/brave_shields/ad_block_service_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -937,11 +937,7 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringSimple) {

// Test cosmetic filtering ignores content determined to be 1st party
// This is disabled due to https://github.com/brave/brave-browser/issues/13882
#if defined(OS_WIN)
#define MAYBE_CosmeticFilteringProtect1p DISABLED_CosmeticFilteringProtect1p
#else
#define MAYBE_CosmeticFilteringProtect1p CosmeticFilteringProtect1p
#endif
IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, MAYBE_CosmeticFilteringProtect1p) {
UpdateAdBlockInstanceWithRules("b.com##.fpsponsored\n");

Expand Down
92 changes: 92 additions & 0 deletions browser/extensions/api/brave_shields_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@

#include <utility>

#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
#include "brave/browser/brave_browser_process_impl.h"
#include "brave/browser/extensions/api/brave_action_api.h"
#include "brave/browser/webcompat_reporter/webcompat_reporter_dialog.h"
#include "brave/common/extensions/api/brave_shields.h"
#include "brave/components/brave_shields/browser/ad_block_service.h"
#include "brave/components/brave_shields/browser/brave_shields_p3a.h"
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "brave/components/brave_shields/browser/brave_shields_web_contents_observer.h"
#include "brave/components/brave_shields/common/brave_shield_constants.h"
#include "brave/components/brave_shields/common/features.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
Expand All @@ -41,6 +44,90 @@ const char kInvalidControlTypeError[] = "Invalid ControlType.";

} // namespace

ExtensionFunction::ResponseAction
BraveShieldsUrlCosmeticResourcesFunction::Run() {
std::unique_ptr<brave_shields::UrlCosmeticResources::Params> params(
brave_shields::UrlCosmeticResources::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
g_brave_browser_process->ad_block_service()
->GetTaskRunner()
->PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(&BraveShieldsUrlCosmeticResourcesFunction::
GetUrlCosmeticResourcesOnTaskRunner,
this, params->url),
base::BindOnce(&BraveShieldsUrlCosmeticResourcesFunction::
GetUrlCosmeticResourcesOnUI,
this));
return RespondLater();
}

std::unique_ptr<base::ListValue>
BraveShieldsUrlCosmeticResourcesFunction::GetUrlCosmeticResourcesOnTaskRunner(
const std::string& url) {
base::Optional<base::Value> resources =
g_brave_browser_process->ad_block_service()->UrlCosmeticResources(url);

if (!resources || !resources->is_dict()) {
return std::unique_ptr<base::ListValue>();
}

auto result_list = std::make_unique<base::ListValue>();
result_list->Append(std::move(*resources));
return result_list;
}

void BraveShieldsUrlCosmeticResourcesFunction::GetUrlCosmeticResourcesOnUI(
std::unique_ptr<base::ListValue> resources) {
if (!resources) {
Respond(Error("Url-specific cosmetic resources could not be returned"));
return;
}
Respond(ArgumentList(std::move(resources)));
}

ExtensionFunction::ResponseAction
BraveShieldsHiddenClassIdSelectorsFunction::Run() {
std::unique_ptr<brave_shields::HiddenClassIdSelectors::Params> params(
brave_shields::HiddenClassIdSelectors::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
g_brave_browser_process->ad_block_service()
->GetTaskRunner()
->PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(&BraveShieldsHiddenClassIdSelectorsFunction::
GetHiddenClassIdSelectorsOnTaskRunner,
this, params->classes, params->ids,
params->exceptions),
base::BindOnce(&BraveShieldsHiddenClassIdSelectorsFunction::
GetHiddenClassIdSelectorsOnUI,
this));
return RespondLater();
}

std::unique_ptr<base::ListValue> BraveShieldsHiddenClassIdSelectorsFunction::
GetHiddenClassIdSelectorsOnTaskRunner(
const std::vector<std::string>& classes,
const std::vector<std::string>& ids,
const std::vector<std::string>& exceptions) {
base::Optional<base::Value> hide_selectors =
g_brave_browser_process->ad_block_service()->HiddenClassIdSelectors(
classes, ids, exceptions);

if (!hide_selectors || !hide_selectors->is_list())
return std::make_unique<base::ListValue>();

auto result_list =
std::make_unique<base::ListValue>(hide_selectors->GetList());

return result_list;
}

void BraveShieldsHiddenClassIdSelectorsFunction::GetHiddenClassIdSelectorsOnUI(
std::unique_ptr<base::ListValue> selectors) {
Respond(ArgumentList(std::move(selectors)));
}

ExtensionFunction::ResponseAction BraveShieldsAllowScriptsOnceFunction::Run() {
std::unique_ptr<brave_shields::AllowScriptsOnce::Params> params(
brave_shields::AllowScriptsOnce::Params::Create(*args_));
Expand Down Expand Up @@ -124,6 +211,11 @@ BraveShieldsGetBraveShieldsEnabledFunction::Run() {

ExtensionFunction::ResponseAction
BraveShieldsShouldDoCosmeticFilteringFunction::Run() {
#if !defined(OS_ANDROID) && !defined(CHROME_OS)
if (base::FeatureList::IsEnabled(
::brave_shields::features::kBraveAdblockCosmeticFilteringNative))
return RespondNow(OneArgument(base::Value(false)));
#endif
std::unique_ptr<brave_shields::ShouldDoCosmeticFiltering::Params>
params(
brave_shields::ShouldDoCosmeticFiltering::Params::Create(*args_));
Expand Down
33 changes: 33 additions & 0 deletions browser/extensions/api/brave_shields_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,39 @@
namespace extensions {
namespace api {

class BraveShieldsUrlCosmeticResourcesFunction : public ExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("braveShields.urlCosmeticResources", UNKNOWN)

protected:
~BraveShieldsUrlCosmeticResourcesFunction() override {}

ResponseAction Run() override;

private:
std::unique_ptr<base::ListValue> GetUrlCosmeticResourcesOnTaskRunner(
const std::string& url);
void GetUrlCosmeticResourcesOnUI(std::unique_ptr<base::ListValue> resources);
};

class BraveShieldsHiddenClassIdSelectorsFunction : public ExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("braveShields.hiddenClassIdSelectors", UNKNOWN)

protected:
~BraveShieldsHiddenClassIdSelectorsFunction() override {}

ResponseAction Run() override;

private:
std::unique_ptr<base::ListValue> GetHiddenClassIdSelectorsOnTaskRunner(
const std::vector<std::string>& classes,
const std::vector<std::string>& ids,
const std::vector<std::string>& exceptions);
void GetHiddenClassIdSelectorsOnUI(
std::unique_ptr<base::ListValue> selectors);
};

class BraveShieldsAllowScriptsOnceFunction : public ExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("braveShields.allowScriptsOnce", UNKNOWN)
Expand Down
6 changes: 6 additions & 0 deletions chromium_src/chrome/browser/about_flags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "net/base/features.h"

using brave_shields::features::kBraveAdblockCosmeticFiltering;
using brave_shields::features::kBraveAdblockCosmeticFilteringNative;
using ntp_background_images::features::kBraveNTPBrandedWallpaper;
using ntp_background_images::features::kBraveNTPBrandedWallpaperDemo;
using ntp_background_images::features::kBraveNTPSuperReferralWallpaper;
Expand Down Expand Up @@ -81,6 +82,11 @@ using ntp_background_images::features::kBraveNTPSuperReferralWallpaper;
flag_descriptions::kBraveAdblockCosmeticFilteringName, \
flag_descriptions::kBraveAdblockCosmeticFilteringDescription, kOsAll, \
FEATURE_VALUE_TYPE(kBraveAdblockCosmeticFiltering)}, \
{"brave-adblock-cosmetic-filtering-native", \
flag_descriptions::kBraveAdblockCosmeticFilteringNativeName, \
flag_descriptions::kBraveAdblockCosmeticFilteringNativeDescription, \
kOsMac | kOsWin | kOsLinux, \
FEATURE_VALUE_TYPE(kBraveAdblockCosmeticFilteringNative)}, \
SPEEDREADER_FEATURE_ENTRIES \
BRAVE_SYNC_FEATURE_ENTRIES \
BRAVE_IPFS_FEATURE_ENTRIES \
Expand Down
4 changes: 4 additions & 0 deletions chromium_src/chrome/browser/flag_descriptions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ const char kBraveNTPBrandedWallpaperDemoDescription[] =
const char kBraveAdblockCosmeticFilteringName[] = "Enable cosmetic filtering";
const char kBraveAdblockCosmeticFilteringDescription[] =
"Enable support for cosmetic filtering";
const char kBraveAdblockCosmeticFilteringNativeName[] =
"Use native implementation for cosmetic filtering";
const char kBraveAdblockCosmeticFilteringNativeDescription[] =
"Uses native implementation for cosmetic filtering instead of extension";
const char kBraveSpeedreaderName[] = "Enable SpeedReader";
const char kBraveSpeedreaderDescription[] =
"Enables faster loading of simplified article-style web pages.";
Expand Down
2 changes: 2 additions & 0 deletions chromium_src/chrome/browser/flag_descriptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ extern const char kBraveNTPBrandedWallpaperDescription[];
extern const char kBraveNTPBrandedWallpaperDemoName[];
extern const char kBraveNTPBrandedWallpaperDemoDescription[];
extern const char kBraveAdblockCosmeticFilteringName[];
extern const char kBraveAdblockCosmeticFilteringNativeName[];
extern const char kBraveAdblockCosmeticFilteringDescription[];
extern const char kBraveAdblockCosmeticFilteringNativeDescription[];
extern const char kBraveSpeedreaderName[];
extern const char kBraveSpeedreaderDescription[];
extern const char kBraveSyncName[];
Expand Down
67 changes: 67 additions & 0 deletions common/extensions/api/brave_shields.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,73 @@
"description": "Notifies the browser about the fact of showing the panel",
"parameters": []
},
{
"name": "urlCosmeticResources",
"type": "function",
"description": "Get a cosmetic adblocking stylesheet, generic style exceptions, script injections, and whether or not a generichide rule was present, all specific for the given URL",
"parameters": [
{
"name": "url",
"type": "string"
},
{
"type": "function",
"name": "callback",
"parameters": [
{
"name": "urlSpecificResources",
"type": "object",
"properties": {
"hide_selectors": {"type": "array", "items": {"type": "string"}, "description": "URL-specific CSS selectors that should be hidden from the page if they are determined to not include 1st party content"},
"style_selectors": {"type": "object", "additionalProperties": {"type": "array", "items": {"type": "string"}}, "description": "URL-specific CSS selectors that should be restyled, with their associated CSS style rules"},
"exceptions": {"type": "array", "items": {"type": "string"}, "description": "URL-specific overrides for generic cosmetic blocking selectors"},
"injected_script": {"type": "string", "description": "A script to inject as the page is loading"},
"force_hide_selectors": {"type": "array", "items": {"type": "string"}, "description": "URL-specific CSS selectors that should be hidden from the page"},
"generichide": {"type": "boolean", "description": "Indicates whether or not the URL matched a generichide exception rule"}
}
}
]
}
]
},
{
"name": "hiddenClassIdSelectors",
"type": "function",
"description": "Get a stylesheet of generic rules that may apply to the given set of classes and ids without any of the given excepted selectors",
"parameters": [
{
"name": "classes",
"type": "array",
"items": {"type": "string"}
},
{
"name": "ids",
"type": "array",
"items": {"type": "string"}
},
{
"name": "exceptions",
"type": "array",
"items": {"type": "string"}
},
{
"type": "function",
"name": "callback",
"parameters": [
{
"name": "selectors",
"type": "array",
"items": {"type": "string"}
},
{
"name": "forceHideSelectors",
"type": "array",
"items": {"type": "string"}
}
]
}
]
},
{
"name": "getBraveShieldsEnabled",
"type": "function",
Expand Down
4 changes: 4 additions & 0 deletions components/brave_extension/extension/brave_extension/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ transpile_web_ui("brave_extension") {
"content_dapps",
rebase_path("content_dapps.ts"),
],
[
"content_cosmetic",
rebase_path("content_cosmetic.ts"),
],
[
"webstore",
rebase_path("webstore.ts"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ export const generateClassIdStylesheet = (tabId: number, classes: string[], ids:
}
}

export const cosmeticFilterRuleExceptions: actions.CosmeticFilterRuleExceptions = (tabId: number, frameId: number, exceptions: string[], scriptlet: string, generichide: boolean) => {
return {
type: types.COSMETIC_FILTER_RULE_EXCEPTIONS,
tabId,
frameId,
exceptions,
scriptlet,
generichide
}
}

export const contentScriptsLoaded: actions.ContentScriptsLoaded = (tabId: number, frameId: number, url: string) => {
return {
type: types.CONTENT_SCRIPTS_LOADED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,75 @@
* 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/. */

import shieldsPanelActions from '../actions/shieldsPanelActions'

const informTabOfCosmeticRulesToConsider = (tabId: number, selectors: string[]) => {
if (selectors.length !== 0) {
const message = {
type: 'cosmeticFilterConsiderNewSelectors',
selectors
}
const options = {
frameId: 0
}
chrome.tabs.sendMessage(tabId, message, options)
}
}

// Fires when content-script calls hiddenClassIdSelectors
export const injectClassIdStylesheet = (tabId: number, classes: string[], ids: string[], exceptions: string[], hide1pContent: boolean) => {
chrome.braveShields.hiddenClassIdSelectors(classes, ids, exceptions, (selectors, forceHideSelectors) => {
if (hide1pContent) {
forceHideSelectors.push(...selectors)
} else {
informTabOfCosmeticRulesToConsider(tabId, selectors)
}

if (forceHideSelectors.length > 0) {
const forceHideStylesheet = forceHideSelectors.join(',') + '{display:none!important;}\n'

chrome.tabs.insertCSS(tabId, {
code: forceHideStylesheet,
cssOrigin: 'user',
runAt: 'document_start'
})
}
})
}

// Fires on content-script loaded
export const applyAdblockCosmeticFilters = (tabId: number, frameId: number, url: string, hide1pContent: boolean) => {
chrome.braveShields.urlCosmeticResources(url, async (resources) => {
if (chrome.runtime.lastError) {
console.warn('Unable to get cosmetic filter data for the current host', chrome.runtime.lastError)
return
}

if (frameId === 0) {
if (hide1pContent) {
resources.force_hide_selectors.push(...resources.hide_selectors)
} else {
informTabOfCosmeticRulesToConsider(tabId, resources.hide_selectors)
}

let styledStylesheet = ''
if (resources.force_hide_selectors.length > 0) {
styledStylesheet += resources.force_hide_selectors.join(',') + '{display:none!important;}\n'
}
for (const selector in resources.style_selectors) {
styledStylesheet += selector + '{' + resources.style_selectors[selector].join(';') + ';}\n'
}
chrome.tabs.insertCSS(tabId, {
code: styledStylesheet,
cssOrigin: 'user',
runAt: 'document_start'
})
}

shieldsPanelActions.cosmeticFilterRuleExceptions(tabId, frameId, resources.exceptions, resources.injected_script || '', resources.generichide)
})
}

// User generated cosmetic filtering below
export const applyCSSCosmeticFilters = (tabId: number, hostname: string) => {
chrome.storage.local.get('cosmeticFilterList', (storeData = {}) => {
Expand Down
Loading

0 comments on commit a586e00

Please sign in to comment.