From a36b8a00aa74c72ef8881ddc5e5cd8756a218789 Mon Sep 17 00:00:00 2001 From: Serg Date: Tue, 10 Nov 2020 13:17:01 -0500 Subject: [PATCH 01/45] android cosmetic filters css injections --- browser/android/BUILD.gn | 2 + .../brave_cosmetic_resources_tab_helper.cc | 379 +++++++++++++++++- .../brave_cosmetic_resources_tab_helper.h | 40 +- browser/brave_cosmetic_resources_tab_helper.h | 75 ++++ .../content/renderer/BUILD.gn | 27 ++ .../renderer/cosmetic_filters_js_handler.cc | 96 +++++ .../renderer/cosmetic_filters_js_handler.h | 48 +++ ...smetic_filters_js_render_frame_observer.cc | 43 ++ ...osmetic_filters_js_render_frame_observer.h | 44 ++ .../cosmetic_filters_communication_impl.cc | 82 ++++ .../cosmetic_filters_communication_impl.h | 45 +++ content/browser/cosmetic_filters_observer.h | 27 ++ content/browser/mojom/BUILD.gn | 5 + .../cosmetic_filters_communication.mojom | 6 + .../public/browser/brave_render_frame_host.cc | 16 + ...browser-browser_interface_binders.cc.patch | 25 ++ ...derer_host-render_frame_host_impl.cc.patch | 30 ++ ...nderer_host-render_frame_host_impl.h.patch | 25 ++ patches/content-public-browser-BUILD.gn.patch | 16 + ...t-public-browser-render_frame_host.h.patch | 32 ++ renderer/BUILD.gn | 7 + renderer/brave_content_renderer_client.cc | 15 + renderer/brave_content_renderer_client.h | 3 + renderer/sources.gni | 12 +- 24 files changed, 1077 insertions(+), 23 deletions(-) create mode 100644 browser/brave_cosmetic_resources_tab_helper.h create mode 100644 components/cosmetic_filters/content/renderer/BUILD.gn create mode 100644 components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc create mode 100644 components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h create mode 100644 components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.cc create mode 100644 components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h create mode 100644 content/browser/cosmetic_filters_communication_impl.cc create mode 100644 content/browser/cosmetic_filters_communication_impl.h create mode 100644 content/browser/cosmetic_filters_observer.h create mode 100644 content/browser/mojom/BUILD.gn create mode 100644 content/browser/mojom/cosmetic_filters_communication.mojom create mode 100644 content/public/browser/brave_render_frame_host.cc create mode 100644 patches/content-browser-browser_interface_binders.cc.patch create mode 100644 patches/content-browser-renderer_host-render_frame_host_impl.cc.patch create mode 100644 patches/content-browser-renderer_host-render_frame_host_impl.h.patch create mode 100644 patches/content-public-browser-BUILD.gn.patch create mode 100644 patches/content-public-browser-render_frame_host.h.patch diff --git a/browser/android/BUILD.gn b/browser/android/BUILD.gn index bde60ad02d48..6b6991c37b02 100644 --- a/browser/android/BUILD.gn +++ b/browser/android/BUILD.gn @@ -16,6 +16,7 @@ source_set("android_browser_process") { deps = [ "//base", + "//brave/content/browser/mojom", "//brave/browser/android/preferences", "//brave/browser/brave_stats:stats_updater", "//brave/build/android:jni_headers", @@ -26,6 +27,7 @@ source_set("android_browser_process") { "//components/flags_ui", "//components/ntp_tiles", "//components/translate/core/browser", + "//mojo/public/cpp/bindings", ] if (brave_ads_enabled) { diff --git a/browser/android/brave_cosmetic_resources_tab_helper.cc b/browser/android/brave_cosmetic_resources_tab_helper.cc index 7d6278143953..7facd1d23ac8 100644 --- a/browser/android/brave_cosmetic_resources_tab_helper.cc +++ b/browser/android/brave_cosmetic_resources_tab_helper.cc @@ -15,6 +15,7 @@ #include "brave/components/brave_shields/browser/ad_block_service.h" #include "brave/components/brave_shields/browser/ad_block_service_helper.h" #include "brave/components/brave_shields/browser/brave_shields_util.h" +#include "brave/content/browser/cosmetic_filters_communication_impl.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_isolated_world_ids.h" @@ -25,6 +26,111 @@ namespace { +const char k_observing_script[] = + "(function() {" + "const queriedIds = new Set();" + "const queriedClasses = new Set();" + "var notYetQueriedClasses;" + "var notYetQueriedIds;" + "var cosmeticObserver;" + "if (window.cosmeticStyleSheet === undefined) {" + "window.cosmeticStyleSheet = new CSSStyleSheet();}" + "const fetchNewClassIdRules = function () {" + "if ((!notYetQueriedClasses || notYetQueriedClasses.length === 0) &&" + "(!notYetQueriedIds || notYetQueriedIds.length === 0)) {" + "return;" + "};" + "cf_worker.hiddenClassIdSelectors(JSON.stringify({classes: notYetQueriedClasses, ids: notYetQueriedIds}));" + "/*chrome.runtime.sendMessage({" + "type: 'hiddenClassIdSelectors'," + "classes: notYetQueriedClasses || []," + "ids: notYetQueriedIds || []" + "})*/" + "notYetQueriedClasses = [];" + "notYetQueriedIds = [];" +"};" + +"function isElement (node) {" + "return (node.nodeType === 1);" +"};" + +"function asElement (node) {" + "return isElement(node) ? node : null;" +"};" + +"const handleMutations = MutationCallback = function (mutations) {" + "for (const aMutation of mutations) {" + "if (aMutation.type === 'attributes') {" + "const changedElm = aMutation.target;" + "switch (aMutation.attributeName) {" + "case 'class':" + "for (const aClassName of changedElm.classList.values()) {" + "if (queriedClasses.has(aClassName) === false) {" + "notYetQueriedClasses.push(aClassName);" + "queriedClasses.add(aClassName);" + "};" + "};" + "break;" + "case 'id':" + "const mutatedId = changedElm.id;" + "if (queriedIds.has(mutatedId) === false) {" + "notYetQueriedIds.push(mutatedId);" + "queriedIds.add(mutatedId);" + "};" + "break;" + "};" + "} else if (aMutation.addedNodes.length > 0) {" + "for (const node of aMutation.addedNodes) {" + "const element = asElement(node);" + "if (!element) {" + "continue;" + "};" + "const id = element.id;" + "if (id && !queriedIds.has(id)) {" + "notYetQueriedIds.push(id);" + "queriedIds.add(id);" + "};" + "const classList = element.classList;" + "if (classList) {" + "for (const className of classList.values()) {" + "if (className && !queriedClasses.has(className)) {" + "notYetQueriedClasses.push(className);" + "queriedClasses.add(className);" + "};" + "};" + "};" + "};" + "};" + "};" + "fetchNewClassIdRules();" +"};" + + "const startObserving = () => {" + " const elmWithClassOrId = document.querySelectorAll('[class],[id]');" + " for (const elm of elmWithClassOrId) {" + " for (const aClassName of elm.classList.values()) {" + " queriedClasses.add(aClassName);" + " /*console.log('!!!aClassName == ' + aClassName);*/" + "}" + " const elmId = elm.getAttribute('id');" + " if (elmId) {" + " queriedIds.add(elmId);" + " }" + "};" + "notYetQueriedClasses = Array.from(queriedClasses);" + "notYetQueriedIds = Array.from(queriedIds);" + "fetchNewClassIdRules();" + "cosmeticObserver = new MutationObserver(handleMutations);" + "let observerConfig = {" + "subtree: true," + "childList: true," + "attributeFilter: ['id', 'class']" + "};" + "cosmeticObserver.observe(document.documentElement, observerConfig);" + "};" + "startObserving();" + "})();"; + bool ShouldDoCosmeticFiltering(content::WebContents* contents, const GURL& url) { Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); @@ -32,9 +138,21 @@ bool ShouldDoCosmeticFiltering(content::WebContents* contents, return ::brave_shields::ShouldDoCosmeticFiltering(map, url); } +} // namespace + + +BraveCosmeticResourcesTabHelper::BraveCosmeticResourcesTabHelper( + content::WebContents* contents) + : WebContentsObserver(contents), + enabled_1st_party_cf_filtering_(false) { +} + +BraveCosmeticResourcesTabHelper::~BraveCosmeticResourcesTabHelper() { +} -std::unique_ptr GetUrlCosmeticResourcesOnTaskRunner( - const std::string& url) { +std::unique_ptr + BraveCosmeticResourcesTabHelper::GetUrlCosmeticResourcesOnTaskRunner( + const std::string& url) { auto result_list = std::make_unique(); base::Optional resources = g_brave_browser_process-> @@ -65,8 +183,9 @@ std::unique_ptr GetUrlCosmeticResourcesOnTaskRunner( return result_list; } -void GetUrlCosmeticResourcesOnUI(content::GlobalFrameRoutingId frame_id, - std::unique_ptr resources) { +void BraveCosmeticResourcesTabHelper::GetUrlCosmeticResourcesOnUI( + content::GlobalFrameRoutingId frame_id, const std::string& url, + bool main_frame, std::unique_ptr resources) { if (!resources) { return; } @@ -86,45 +205,267 @@ void GetUrlCosmeticResourcesOnUI(content::GlobalFrameRoutingId frame_id, base::UTF8ToUTF16(to_inject), base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); } + // Working on css rules + if (!main_frame) + return; + + CSSRulesRoutine(url, resources_dict, frame_id); } } -} // namespace +void BraveCosmeticResourcesTabHelper::CSSRulesRoutine( + const std::string& url_string, base::DictionaryValue* resources_dict, + content::GlobalFrameRoutingId frame_id) { + // Check are first party cosmetic filters enabled + const GURL url(url_string); + if (url.is_empty() || !url.is_valid()) { + return; + } -BraveCosmeticResourcesTabHelper::BraveCosmeticResourcesTabHelper( - content::WebContents* contents) - : WebContentsObserver(contents) { + Profile* profile = Profile::FromBrowserContext( + web_contents()->GetBrowserContext()); + enabled_1st_party_cf_filtering_ = + brave_shields::IsFirstPartyCosmeticFilteringEnabled( + HostContentSettingsMapFactory::GetForProfile(profile), url); + base::ListValue* cf_exceptions_list; + if (resources_dict->GetList("exceptions", &cf_exceptions_list)) { + for (size_t i = 0; i < cf_exceptions_list->GetSize(); i++) { + exceptions_.push_back(cf_exceptions_list->GetList()[i].GetString()); + } + } + base::ListValue* hide_selectors_list; + base::ListValue* force_hide_selectors_list = nullptr; + if (resources_dict->GetList("hide_selectors", &hide_selectors_list)) { + if (enabled_1st_party_cf_filtering_) { + // TODO + // resources.force_hide_selectors.push(...resources.hide_selectors) + force_hide_selectors_list = hide_selectors_list; + } else { + std::string cosmeticFilterConsiderNewSelectors_script = + "(function() {" + "let nextIndex = window.cosmeticStyleSheet.rules.length;"; + for (size_t i = 0; i < hide_selectors_list->GetSize(); i++) { + std::string rule = hide_selectors_list->GetList()[i].GetString() + + "{display:none !important;}"; + cosmeticFilterConsiderNewSelectors_script += + "window.cosmeticStyleSheet.insertRule(`" + rule + + "`,nextIndex);" + "nextIndex++;"; + } + cosmeticFilterConsiderNewSelectors_script += + "if (!document.adoptedStyleSheets.includes(" + "window.cosmeticStyleSheet)){" + "document.adoptedStyleSheets = [window.cosmeticStyleSheet];" + "};"; + cosmeticFilterConsiderNewSelectors_script += "})();"; + if (hide_selectors_list->GetSize() != 0) { + auto* frame_host = content::RenderFrameHost::FromID(frame_id); + if (!frame_host) + return; + frame_host->ExecuteJavaScriptInIsolatedWorld( + base::UTF8ToUTF16(cosmeticFilterConsiderNewSelectors_script), + base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); + } + } + } + + std::string styled_stylesheet = ""; + if (force_hide_selectors_list!= nullptr && + force_hide_selectors_list->GetSize() != 0) { + for (size_t i = 0; i < force_hide_selectors_list->GetSize(); i++) { + if (i != 0) { + styled_stylesheet += ","; + } + styled_stylesheet += force_hide_selectors_list->GetList()[i].GetString(); + } + styled_stylesheet += "{display:none!important;}\n"; + } + base::DictionaryValue* style_selectors_dictionary = nullptr; + if (resources_dict->GetDictionary("style_selectors", + &style_selectors_dictionary)) { + for (const auto& it : style_selectors_dictionary->DictItems()) { + base::ListValue* style_selectors_list = nullptr; + if (!style_selectors_dictionary->GetList(it.first, + &style_selectors_list) || style_selectors_list->GetSize() == 0) { + continue; + } + styled_stylesheet += it.first + "{"; + for (size_t i = 0; i < style_selectors_list->GetSize(); i++) { + if (i != 0) { + styled_stylesheet += ";"; + } + styled_stylesheet += style_selectors_list->GetList()[i].GetString(); + } + styled_stylesheet += ";}\n"; + } + std::string cosmeticFilterConsiderNewSelectors_script = + "(function() {"; + cosmeticFilterConsiderNewSelectors_script += + "window.cosmeticStyleSheet.insertRule(`" + styled_stylesheet + + "`,window.cosmeticStyleSheet.rules.length);"; + cosmeticFilterConsiderNewSelectors_script += + "if (!document.adoptedStyleSheets.includes(" + "window.cosmeticStyleSheet)){" + "document.adoptedStyleSheets = [window.cosmeticStyleSheet];" + "};"; + cosmeticFilterConsiderNewSelectors_script += "})();"; + auto* frame_host = content::RenderFrameHost::FromID(frame_id); + if (!frame_host) + return; + frame_host->ExecuteJavaScriptInIsolatedWorld( + base::UTF8ToUTF16(cosmeticFilterConsiderNewSelectors_script), + base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); + } + // } -BraveCosmeticResourcesTabHelper::~BraveCosmeticResourcesTabHelper() { +std::unique_ptr + BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnTaskRunner( + const std::vector& classes, + const std::vector& ids) { + base::Optional hide_selectors = g_brave_browser_process-> + ad_block_service()->HiddenClassIdSelectors(classes, ids, exceptions_); + + base::Optional regional_selectors = g_brave_browser_process-> + ad_block_regional_service_manager()-> + HiddenClassIdSelectors(classes, ids, exceptions_); + + base::Optional custom_selectors = g_brave_browser_process-> + ad_block_custom_filters_service()-> + HiddenClassIdSelectors(classes, ids, exceptions_); + + if (hide_selectors && hide_selectors->is_list()) { + if (regional_selectors && regional_selectors->is_list()) { + for (auto i = regional_selectors->GetList().begin(); + i < regional_selectors->GetList().end(); i++) { + hide_selectors->Append(std::move(*i)); + } + } + } else { + hide_selectors = std::move(regional_selectors); + } + + auto result_list = std::make_unique(); + if (hide_selectors && hide_selectors->is_list()) { + result_list->Append(std::move(*hide_selectors)); + } + if (custom_selectors && custom_selectors->is_list()) { + result_list->Append(std::move(*custom_selectors)); + } + + return result_list; +} + +void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( + content::RenderFrameHost* render_frame_host, + std::unique_ptr selectors) { + if (!selectors) { + return; + } + if (enabled_1st_party_cf_filtering_) { + // TODO + // resources.force_hide_selectors.push(...resources.hide_selectors) + //force_hide_selectors_list = selectors; + } else { + std::string cosmeticFilterConsiderNewSelectors_script = + "(function() {" + "let nextIndex = window.cosmeticStyleSheet.rules.length;"; + bool execute_script = false; + for (size_t i = 0; i < selectors->GetSize(); i++) { + base::ListValue* selectors_list = nullptr; + if (!selectors->GetList()[i].GetAsList(&selectors_list) || + selectors_list->GetSize() == 0) { + continue; + } + for (size_t j = 0; j < selectors_list->GetSize(); j++) { + std::string rule = selectors_list->GetList()[i].GetString() + + "{display:none !important;}"; + cosmeticFilterConsiderNewSelectors_script += + "window.cosmeticStyleSheet.insertRule(`" + rule + + "`,nextIndex);" + "nextIndex++;"; + execute_script = true; + } + } + if (execute_script) { + cosmeticFilterConsiderNewSelectors_script += + "if (!document.adoptedStyleSheets.includes(" + "window.cosmeticStyleSheet)){" + "document.adoptedStyleSheets = [window.cosmeticStyleSheet];" + "};"; + cosmeticFilterConsiderNewSelectors_script += "})();"; + render_frame_host->ExecuteJavaScriptInIsolatedWorld( + base::UTF8ToUTF16(cosmeticFilterConsiderNewSelectors_script), + base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); + } + } } void BraveCosmeticResourcesTabHelper::ProcessURL( - content::WebContents* contents, - content::RenderFrameHost* render_frame_host, const GURL& url) { - if (!render_frame_host || !ShouldDoCosmeticFiltering(contents, url)) { + content::RenderFrameHost* render_frame_host, const GURL& url, + const bool& main_frame) { + content::CosmeticFiltersCommunicationImpl::CreateInstance(render_frame_host, + this); + if (!render_frame_host || !ShouldDoCosmeticFiltering(web_contents(), url)) { return; } g_brave_browser_process->ad_block_service()->GetTaskRunner()-> PostTaskAndReplyWithResult(FROM_HERE, - base::BindOnce(&GetUrlCosmeticResourcesOnTaskRunner, url.spec()), - base::BindOnce(&GetUrlCosmeticResourcesOnUI, - content::GlobalFrameRoutingId( + base::BindOnce(&BraveCosmeticResourcesTabHelper:: + GetUrlCosmeticResourcesOnTaskRunner, base::Unretained(this), + url.spec()), + base::BindOnce(&BraveCosmeticResourcesTabHelper:: + GetUrlCosmeticResourcesOnUI, base::Unretained(this), + content::GlobalFrameRoutingId( render_frame_host->GetProcess()->GetID(), - render_frame_host->GetRoutingID()))); + render_frame_host->GetRoutingID()), + url.spec(), main_frame)); + if (!main_frame) + return; + // Non-scriptlet cosmetic filters are only applied on the top-level frame + if (web_contents()->GetMainFrame()) { + web_contents()->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld( + base::UTF8ToUTF16(k_observing_script), + base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); + } } void BraveCosmeticResourcesTabHelper::DidFinishNavigation( content::NavigationHandle* navigation_handle) { - ProcessURL(web_contents(), web_contents()->GetMainFrame(), - web_contents()->GetLastCommittedURL()); + ProcessURL(web_contents()->GetMainFrame(), + web_contents()->GetLastCommittedURL(), true); } void BraveCosmeticResourcesTabHelper::ResourceLoadComplete( content::RenderFrameHost* render_frame_host, const content::GlobalRequestID& request_id, const blink::mojom::ResourceLoadInfo& resource_load_info) { - ProcessURL(web_contents(), render_frame_host, resource_load_info.final_url); + ProcessURL(render_frame_host, resource_load_info.final_url, false); +} + +bool BraveCosmeticResourcesTabHelper::OnMessageReceived( + const IPC::Message& message, + content::RenderFrameHost* render_frame_host) { + return false; +} + +bool BraveCosmeticResourcesTabHelper::OnMessageReceived( + const IPC::Message& message) { + return false; +} + +void BraveCosmeticResourcesTabHelper::HiddenClassIdSelectors( + content::RenderFrameHost* render_frame_host, + const std::vector& classes, + const std::vector& ids) { + g_brave_browser_process->ad_block_service()->GetTaskRunner()-> + PostTaskAndReplyWithResult(FROM_HERE, + base::BindOnce(&BraveCosmeticResourcesTabHelper:: + GetHiddenClassIdSelectorsOnTaskRunner, base::Unretained(this), + classes, ids), + base::BindOnce(&BraveCosmeticResourcesTabHelper:: + GetHiddenClassIdSelectorsOnUI, base::Unretained(this), + render_frame_host)); } WEB_CONTENTS_USER_DATA_KEY_IMPL(BraveCosmeticResourcesTabHelper) diff --git a/browser/android/brave_cosmetic_resources_tab_helper.h b/browser/android/brave_cosmetic_resources_tab_helper.h index 7d99c5c137d7..5a464cd4c246 100644 --- a/browser/android/brave_cosmetic_resources_tab_helper.h +++ b/browser/android/brave_cosmetic_resources_tab_helper.h @@ -6,12 +6,16 @@ #ifndef BRAVE_BROWSER_ANDROID_BRAVE_COSMETIC_RESOURCES_TAB_HELPER_H_ #define BRAVE_BROWSER_ANDROID_BRAVE_COSMETIC_RESOURCES_TAB_HELPER_H_ +#include + #include "base/memory/weak_ptr.h" +#include "brave/content/browser/cosmetic_filters_observer.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" class BraveCosmeticResourcesTabHelper - : public content::WebContentsObserver, + : public content::CosmeticFiltersObserver, + public content::WebContentsObserver, public content::WebContentsUserData, public base::SupportsWeakPtr { public: @@ -25,12 +29,42 @@ class BraveCosmeticResourcesTabHelper content::RenderFrameHost* render_frame_host, const content::GlobalRequestID& request_id, const blink::mojom::ResourceLoadInfo& resource_load_info) override; + bool OnMessageReceived(const IPC::Message& message, + content::RenderFrameHost* render_frame_host) override; + bool OnMessageReceived(const IPC::Message& message) override; + // + + // content::CosmeticFiltersObserver overrides: + void HiddenClassIdSelectors(content::RenderFrameHost* render_frame_host, + const std::vector& classes, + const std::vector& ids) override; + // WEB_CONTENTS_USER_DATA_KEY_DECL(); private: - void ProcessURL(content::WebContents* contents, - content::RenderFrameHost* render_frame_host, const GURL& url); + void ProcessURL(content::RenderFrameHost* render_frame_host, const GURL& url, + const bool& main_frame); + + std::unique_ptr GetUrlCosmeticResourcesOnTaskRunner( + const std::string& url); + void GetUrlCosmeticResourcesOnUI(content::RenderFrameHost* render_frame_host, + const std::string& url, bool main_frame, + std::unique_ptr resources); + void CSSRulesRoutine(const std::string& url, + base::DictionaryValue* resources_dict, + content::RenderFrameHost* render_frame_host); + + std::unique_ptr GetHiddenClassIdSelectorsOnTaskRunner( + const std::vector& classes, + const std::vector& ids); + void GetHiddenClassIdSelectorsOnUI( + content::RenderFrameHost* render_frame_host, + std::unique_ptr selectors); + + std::vector exceptions_; + bool enabled_1st_party_cf_filtering_; + DISALLOW_COPY_AND_ASSIGN(BraveCosmeticResourcesTabHelper); }; diff --git a/browser/brave_cosmetic_resources_tab_helper.h b/browser/brave_cosmetic_resources_tab_helper.h new file mode 100644 index 000000000000..6b9fa1880a8b --- /dev/null +++ b/browser/brave_cosmetic_resources_tab_helper.h @@ -0,0 +1,75 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 3.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_BROWSER_BRAVE_COSMETIC_RESOURCES_TAB_HELPER_H_ +#define BRAVE_BROWSER_BRAVE_COSMETIC_RESOURCES_TAB_HELPER_H_ + +#include +#include +#include + +#include "base/memory/weak_ptr.h" +#include "brave/content/browser/cosmetic_filters_observer.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" + +class BraveCosmeticResourcesTabHelper + : public content::CosmeticFiltersObserver, + public content::WebContentsObserver, + public content::WebContentsUserData, + public base::SupportsWeakPtr { + public: + static std::string* observing_script_; + + explicit BraveCosmeticResourcesTabHelper(content::WebContents* contents); + ~BraveCosmeticResourcesTabHelper() override; + + // content::WebContentsObserver overrides: + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + void ResourceLoadComplete( + content::RenderFrameHost* render_frame_host, + const content::GlobalRequestID& request_id, + const blink::mojom::ResourceLoadInfo& resource_load_info) override; + bool OnMessageReceived(const IPC::Message& message, + content::RenderFrameHost* render_frame_host) override; + bool OnMessageReceived(const IPC::Message& message) override; + // + + // content::CosmeticFiltersObserver overrides: + void HiddenClassIdSelectors(content::RenderFrameHost* render_frame_host, + const std::vector& classes, + const std::vector& ids) override; + // + + WEB_CONTENTS_USER_DATA_KEY_DECL(); + + private: + void ProcessURL(content::RenderFrameHost* render_frame_host, const GURL& url, + const bool& main_frame); + + std::unique_ptr GetUrlCosmeticResourcesOnTaskRunner( + const std::string& url); + void GetUrlCosmeticResourcesOnUI(content::GlobalFrameRoutingId frame_id, + const std::string& url, bool main_frame, + std::unique_ptr resources); + void CSSRulesRoutine(const std::string& url, + base::DictionaryValue* resources_dict, + content::GlobalFrameRoutingId frame_id); + + std::unique_ptr GetHiddenClassIdSelectorsOnTaskRunner( + const std::vector& classes, + const std::vector& ids); + void GetHiddenClassIdSelectorsOnUI( + content::RenderFrameHost* render_frame_host, + std::unique_ptr selectors); + + std::vector exceptions_; + bool enabled_1st_party_cf_filtering_; + + DISALLOW_COPY_AND_ASSIGN(BraveCosmeticResourcesTabHelper); +}; + +#endif // BRAVE_BROWSER_BRAVE_COSMETIC_RESOURCES_TAB_HELPER_H_ diff --git a/components/cosmetic_filters/content/renderer/BUILD.gn b/components/cosmetic_filters/content/renderer/BUILD.gn new file mode 100644 index 000000000000..24eaaeab3f95 --- /dev/null +++ b/components/cosmetic_filters/content/renderer/BUILD.gn @@ -0,0 +1,27 @@ +import("//build/config/features.gni") + +source_set("renderer") { + visibility = [ + "//brave/renderer/*", + "//brave:child_dependencies", + "//chrome/renderer/*", + "//components/content_settings/renderer/*", + ] + + sources = [ + "cosmetic_filters_js_render_frame_observer.cc", + "cosmetic_filters_js_render_frame_observer.h", + "cosmetic_filters_js_handler.cc", + "cosmetic_filters_js_handler.h", + ] + + deps = [ + "//base", + "//content/public/renderer", + "//gin", + "//mojo/public/cpp/bindings", + "//third_party/blink/public:blink", + "//third_party/blink/public/common", + "//v8", + ] +} diff --git a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc new file mode 100644 index 000000000000..294cf56c4b8c --- /dev/null +++ b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc @@ -0,0 +1,96 @@ +/* Copyright (c) 2020 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/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h" + +#include + +#include "base/bind.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/renderer/render_frame.h" +#include "gin/arguments.h" +#include "gin/function_template.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/web/blink.h" +#include "v8/include/v8.h" + +namespace cosmetic_filters_worker { + +CosmeticFiltersJSHandler::CosmeticFiltersJSHandler( + content::RenderFrame* render_frame): + render_frame_(render_frame) {} + +CosmeticFiltersJSHandler::~CosmeticFiltersJSHandler() = default; + +void CosmeticFiltersJSHandler::HiddenClassIdSelectors( + const std::string& input) { + if (cs_communicator_) { + cs_communicator_->HiddenClassIdSelectors(input); + } +} + +void CosmeticFiltersJSHandler::AddJavaScriptObjectToFrame( + v8::Local context) { + v8::Isolate* isolate = blink::MainThreadIsolate(); + v8::HandleScope handle_scope(isolate); + if (context.IsEmpty()) + return; + + v8::Context::Scope context_scope(context); + + v8::Local distiller_obj = + GetOrCreateWorkerObject(isolate, context); + + EnsureConnected(); + + BindFunctionToObject( + isolate, distiller_obj, "hiddenClassIdSelectors", + base::BindRepeating(&CosmeticFiltersJSHandler::HiddenClassIdSelectors, + base::Unretained(this))); +} + +template +void CosmeticFiltersJSHandler::BindFunctionToObject( + v8::Isolate* isolate, + v8::Local javascript_object, + const std::string& name, + const base::RepeatingCallback& callback) { + v8::Local context = isolate->GetCurrentContext(); + // Get the isolate associated with this object. + javascript_object + ->Set(context, gin::StringToSymbol(isolate, name), + gin::CreateFunctionTemplate(isolate, callback) + ->GetFunction(context) + .ToLocalChecked()) + .Check(); +} + +void CosmeticFiltersJSHandler::EnsureConnected() { + if (!cs_communicator_) { + render_frame_->GetBrowserInterfaceBroker()->GetInterface( + cs_communicator_.BindNewPipeAndPassReceiver()); + } +} + +v8::Local GetOrCreateWorkerObject( + v8::Isolate* isolate, + v8::Local context) { + v8::Local global = context->Global(); + v8::Local distiller_obj; + v8::Local distiller_value; + if (!global->Get(context, gin::StringToV8(isolate, "cf_worker")) + .ToLocal(&distiller_value) || + !distiller_value->IsObject()) { + distiller_obj = v8::Object::New(isolate); + global + ->Set(context, gin::StringToSymbol(isolate, "cf_worker"), distiller_obj) + .Check(); + } else { + distiller_obj = v8::Local::Cast(distiller_value); + } + return distiller_obj; +} + +} // namespace cosmetic_filters_worker diff --git a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h new file mode 100644 index 000000000000..62e7aabf0818 --- /dev/null +++ b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2020 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_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_HANDLER_H_ +#define BRAVE_COMPONENTS_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_HANDLER_H_ + +#include "brave/content/browser/mojom/cosmetic_filters_communication.mojom.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_frame_observer.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "v8/include/v8.h" + +namespace cosmetic_filters_worker { + +class CosmeticFiltersJSHandler { + public: + explicit CosmeticFiltersJSHandler(content::RenderFrame* render_frame); + ~CosmeticFiltersJSHandler(); + + // Adds the "cs_worker" JavaScript object and its functions to the current + // |RenderFrame|. + void AddJavaScriptObjectToFrame(v8::Local context); + + private: + // Add a function to the provided object. + template + void BindFunctionToObject(v8::Isolate* isolate, + v8::Local javascript_object, const std::string& name, + const base::RepeatingCallback& callback); + void EnsureConnected(); + + // A function to be called from JS + void HiddenClassIdSelectors(const std::string& input); + + content::RenderFrame* render_frame_; + mojo::Remote cs_communicator_; +}; + +// static +v8::Local GetOrCreateWorkerObject( + v8::Isolate* isolate, + v8::Local context); + +} // namespace cosmetic_filters_worker + +#endif // BRAVE_COMPONENTS_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_HANDLER_H_ diff --git a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.cc b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.cc new file mode 100644 index 000000000000..5c5b34ecd955 --- /dev/null +++ b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.cc @@ -0,0 +1,43 @@ +/* Copyright (c) 2020 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/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h" + +#include +#include + +#include "base/bind.h" +#include "content/public/renderer/render_frame.h" + +namespace cosmetic_filters_worker { + +CosmeticFiltersJsRenderFrameObserver::CosmeticFiltersJsRenderFrameObserver( + content::RenderFrame* render_frame, const int32_t isolated_world_id) + : RenderFrameObserver(render_frame), + worker_isolated_world_id_(isolated_world_id) {} + +CosmeticFiltersJsRenderFrameObserver::~CosmeticFiltersJsRenderFrameObserver() {} + +void CosmeticFiltersJsRenderFrameObserver::DidStartNavigation( + const GURL& url, + base::Optional navigation_type) { + // Save url for feature interactions +} + +void CosmeticFiltersJsRenderFrameObserver::DidCreateScriptContext( + v8::Local context, int32_t world_id) { + if (world_id != worker_isolated_world_id_) + return; + + native_javascript_handle_.reset( + new CosmeticFiltersJSHandler(render_frame())); + native_javascript_handle_->AddJavaScriptObjectToFrame(context); +} + +void CosmeticFiltersJsRenderFrameObserver::OnDestruct() { + delete this; +} + +} // namespace cosmetic_filters_worker diff --git a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h new file mode 100644 index 000000000000..c550ab1a9092 --- /dev/null +++ b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h @@ -0,0 +1,44 @@ +/* Copyright (c) 2020 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_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_RENDER_FRAME_OBSERVER_H_ +#define BRAVE_COMPONENTS_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_RENDER_FRAME_OBSERVER_H_ + +#include "base/memory/weak_ptr.h" +#include "brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_frame_observer.h" +#include "v8/include/v8.h" + +namespace cosmetic_filters_worker { + +// CosmeticFiltersJsRenderFrame observer waits for a page to be loaded and then +// adds the Javascript worker object. +class CosmeticFiltersJsRenderFrameObserver : public content::RenderFrameObserver { + public: + CosmeticFiltersJsRenderFrameObserver(content::RenderFrame* render_frame, + const int32_t isolated_world_id); + ~CosmeticFiltersJsRenderFrameObserver() override; + + // RenderFrameObserver implementation. + void DidStartNavigation(const GURL& url, + base::Optional navigation_type) override; + void DidCreateScriptContext(v8::Local context, + int32_t world_id) override; + + private: + // RenderFrameObserver implementation. + void OnDestruct() override; + + // The isolated world that the distiller object should be written to. + int32_t worker_isolated_world_id_; + + // Handle to "handler" JavaScript object functionality. + std::unique_ptr native_javascript_handle_; +}; + +} // namespace cosmetic_filters_worker + +#endif // BRAVE_COMPONENTS_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_RENDER_FRAME_OBSERVER_H_ diff --git a/content/browser/cosmetic_filters_communication_impl.cc b/content/browser/cosmetic_filters_communication_impl.cc new file mode 100644 index 000000000000..08c616ac6b66 --- /dev/null +++ b/content/browser/cosmetic_filters_communication_impl.cc @@ -0,0 +1,82 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 3.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/content/browser/cosmetic_filters_communication_impl.h" + +#include "base/json/json_reader.h" +#include "brave/content/browser/cosmetic_filters_observer.h" +#include "content/public/browser/render_frame_host.h" + +namespace content { + +// static +void CosmeticFiltersCommunicationImpl::CreateInstance( + content::RenderFrameHost* render_frame_host, + CosmeticFiltersObserver* cosmetic_filters_observer) { + if (!render_frame_host->cosmetic_filters_communication_impl_) { + render_frame_host->cosmetic_filters_communication_impl_.reset( + new CosmeticFiltersCommunicationImpl( + render_frame_host, cosmetic_filters_observer)); + } else { + render_frame_host->cosmetic_filters_communication_impl_->SetObserver( + cosmetic_filters_observer); + } +} + +CosmeticFiltersCommunicationImpl::CosmeticFiltersCommunicationImpl( + content::RenderFrameHost* render_frame_host, + CosmeticFiltersObserver* cosmetic_filters_observer) + : render_frame_host_(render_frame_host), + cosmetic_filters_observer_(cosmetic_filters_observer) { +} + +CosmeticFiltersCommunicationImpl::~CosmeticFiltersCommunicationImpl() { +} + +void CosmeticFiltersCommunicationImpl::SetObserver( + CosmeticFiltersObserver* cosmetic_filters_observer) { + if (cosmetic_filters_observer && !cosmetic_filters_observer_) { + cosmetic_filters_observer_ = cosmetic_filters_observer; + } +} + +void CosmeticFiltersCommunicationImpl::HiddenClassIdSelectors( + const std::string& input) { + base::Optional input_value = base::JSONReader::Read(input); + if (!input_value || !input_value->is_dict()) { + // Nothing to work with + return; + } + base::DictionaryValue* input_dict; + if (!input_value->GetAsDictionary(&input_dict)) { + return; + } + std::vector classes; + base::ListValue* classes_list; + if (input_dict->GetList("classes", &classes_list)) { + for (size_t i = 0; i < classes_list->GetSize(); i++) { + if (!classes_list->GetList()[i].is_string()) { + continue; + } + classes.push_back(classes_list->GetList()[i].GetString()); + } + } + std::vector ids; + base::ListValue* ids_list; + if (input_dict->GetList("ids", &ids_list)) { + for (size_t i = 0; i < ids_list->GetSize(); i++) { + if (!ids_list->GetList()[i].is_string()) { + continue; + } + ids.push_back(ids_list->GetList()[i].GetString()); + } + } + if (cosmetic_filters_observer_) { + cosmetic_filters_observer_->HiddenClassIdSelectors(render_frame_host_, + classes, ids); + } +} + +} // namespace content diff --git a/content/browser/cosmetic_filters_communication_impl.h b/content/browser/cosmetic_filters_communication_impl.h new file mode 100644 index 000000000000..c070775b4794 --- /dev/null +++ b/content/browser/cosmetic_filters_communication_impl.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 3.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_CONTENT_BROWSER_COSMETIC_COMMUNICATION_IMPL_H_ +#define BRAVE_CONTENT_BROWSER_COSMETIC_COMMUNICATION_IMPL_H_ + +#include +#include + +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "brave/content/browser/mojom/cosmetic_filters_communication.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" + +namespace content { +class RenderFrameHost; +class CosmeticFiltersObserver; + +class CosmeticFiltersCommunicationImpl final + : public cf_comm::mojom::CosmeticFiltersCommunication { + public: + static void CreateInstance(content::RenderFrameHost* render_frame_host, + CosmeticFiltersObserver* cosmetic_filters_observer); + + CosmeticFiltersCommunicationImpl( + content::RenderFrameHost* render_frame_host, + CosmeticFiltersObserver* cosmetic_filters_observer); + ~CosmeticFiltersCommunicationImpl() override; + + // cf_comm::mojom::CosmeticFiltersCommunication + void HiddenClassIdSelectors(const std::string& input) override; + + void SetObserver(CosmeticFiltersObserver* cosmetic_filters_observer); + + private: + content::RenderFrameHost* render_frame_host_; + CosmeticFiltersObserver* cosmetic_filters_observer_; +}; + +} // namespace content + +#endif // BRAVE_CONTENT_BROWSER_COSMETIC_COMMUNICATION_IMPL_H_ diff --git a/content/browser/cosmetic_filters_observer.h b/content/browser/cosmetic_filters_observer.h new file mode 100644 index 000000000000..45a789b43327 --- /dev/null +++ b/content/browser/cosmetic_filters_observer.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 3.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_CONTENT_BROWSER_COSMETIC_FILTERS_OBSERVER_H_ +#define BRAVE_CONTENT_BROWSER_COSMETIC_FILTERS_OBSERVER_H_ + +#include + +namespace content { + +class RenderFrameHost; + +class CosmeticFiltersObserver { + public: + CosmeticFiltersObserver() {} + ~CosmeticFiltersObserver() {} + + virtual void HiddenClassIdSelectors(RenderFrameHost* render_frame_host, + const std::vector& classes, + const std::vector& ids) {} +}; + +} // namespace content + +#endif // BRAVE_CONTENT_BROWSER_COSMETIC_FILTERS_OBSERVER_H_ diff --git a/content/browser/mojom/BUILD.gn b/content/browser/mojom/BUILD.gn new file mode 100644 index 000000000000..00ea727dee69 --- /dev/null +++ b/content/browser/mojom/BUILD.gn @@ -0,0 +1,5 @@ +import("//mojo/public/tools/bindings/mojom.gni") + +mojom("mojom") { + sources = [ "cosmetic_filters_communication.mojom" ] +} diff --git a/content/browser/mojom/cosmetic_filters_communication.mojom b/content/browser/mojom/cosmetic_filters_communication.mojom new file mode 100644 index 000000000000..8214d570a670 --- /dev/null +++ b/content/browser/mojom/cosmetic_filters_communication.mojom @@ -0,0 +1,6 @@ +module cf_comm.mojom; + +interface CosmeticFiltersCommunication { + // Receives an input string which is JSON object. + HiddenClassIdSelectors(string input); +}; diff --git a/content/public/browser/brave_render_frame_host.cc b/content/public/browser/brave_render_frame_host.cc new file mode 100644 index 000000000000..8ecb995eaabb --- /dev/null +++ b/content/public/browser/brave_render_frame_host.cc @@ -0,0 +1,16 @@ +/* Copyright (c) 2020 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 "content/public/browser/render_frame_host.h" + +#include "brave/content/browser/cosmetic_filters_communication_impl.h" + +namespace content { + +RenderFrameHost::RenderFrameHost() {} + +RenderFrameHost::~RenderFrameHost() {} + +} // namespace content diff --git a/patches/content-browser-browser_interface_binders.cc.patch b/patches/content-browser-browser_interface_binders.cc.patch new file mode 100644 index 000000000000..7f2b42c0e656 --- /dev/null +++ b/patches/content-browser-browser_interface_binders.cc.patch @@ -0,0 +1,25 @@ +diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc +index ba25194ba4178c7caa396ce44779cf70f4d69998..99f4b92f036db3f845e76fd9f7b744ec9e183e5a 100644 +--- a/content/browser/browser_interface_binders.cc ++++ b/content/browser/browser_interface_binders.cc +@@ -136,6 +136,7 @@ + #endif + + #if defined(OS_ANDROID) ++#include "brave/content/browser/mojom/cosmetic_filters_communication.mojom.h" + #include "content/browser/android/date_time_chooser_android.h" + #include "content/browser/android/text_suggestion_host_android.h" + #include "content/browser/renderer_host/render_widget_host_view_android.h" +@@ -748,6 +749,12 @@ void PopulateFrameBinders(RenderFrameHostImpl* host, mojo::BinderMap* map) { + map->Add( + base::BindRepeating(&BindTextInputHost)); + #endif ++#if defined(OS_ANDROID) ++ // Register the handler for cosmetic filters responder. ++ map->Add(base::BindRepeating( ++ &RenderFrameHostImpl::GetCosmeticFiltersResponder, ++ base::Unretained(host))); ++#endif + } + + void PopulateBinderMapWithContext( diff --git a/patches/content-browser-renderer_host-render_frame_host_impl.cc.patch b/patches/content-browser-renderer_host-render_frame_host_impl.cc.patch new file mode 100644 index 000000000000..a4cc3c49098b --- /dev/null +++ b/patches/content-browser-renderer_host-render_frame_host_impl.cc.patch @@ -0,0 +1,30 @@ +diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc +index 497033d3d5257daffe4aca2ebdd1fd71513db73f..f710a73beed45b44c822db4ee6366b7ca0a991e3 100644 +--- a/content/browser/renderer_host/render_frame_host_impl.cc ++++ b/content/browser/renderer_host/render_frame_host_impl.cc +@@ -1057,6 +1057,7 @@ RenderFrameHostImpl::RenderFrameHostImpl( + // of overrides. + idle_manager_ = + std::make_unique(GetProcess()->GetBrowserContext()); ++ cosmetic_filters_communication_impl_ = nullptr; + } + + RenderFrameHostImpl::~RenderFrameHostImpl() { +@@ -9683,6 +9684,17 @@ bool RenderFrameHostImpl::DocumentUsedWebOTP() { + return document_used_web_otp_; + } + ++#if defined(OS_ANDROID) ++void RenderFrameHostImpl::GetCosmeticFiltersResponder( ++ mojo::PendingReceiver< ++ cf_comm::mojom::CosmeticFiltersCommunication> receiver) { ++ CosmeticFiltersCommunicationImpl::CreateInstance(this, nullptr); ++ mojo::MakeSelfOwnedReceiver( ++ std::move(cosmetic_filters_communication_impl_), ++ std::move(receiver)); ++} ++#endif ++ + std::ostream& operator<<(std::ostream& o, + const RenderFrameHostImpl::LifecycleState& s) { + return o << LifecycleStateToString(s); diff --git a/patches/content-browser-renderer_host-render_frame_host_impl.h.patch b/patches/content-browser-renderer_host-render_frame_host_impl.h.patch new file mode 100644 index 000000000000..10aef0c74756 --- /dev/null +++ b/patches/content-browser-renderer_host-render_frame_host_impl.h.patch @@ -0,0 +1,25 @@ +diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h +index dc1015e539e768eb280c5f6b226415ec2f804ffe..3b34cc0b8494af5030852fa2eb78fad7634a0b74 100644 +--- a/content/browser/renderer_host/render_frame_host_impl.h ++++ b/content/browser/renderer_host/render_frame_host_impl.h +@@ -149,6 +149,7 @@ + #include "ui/gfx/geometry/rect.h" + + #if defined(OS_ANDROID) ++#include "brave/content/browser/cosmetic_filters_communication_impl.h" + #include "services/device/public/mojom/nfc.mojom.h" + #else + #include "third_party/blink/public/mojom/hid/hid.mojom.h" +@@ -1826,6 +1827,12 @@ class CONTENT_EXPORT RenderFrameHostImpl + std::unique_ptr CreateMessageFilterForAssociatedReceiver( + const char* interface_name); + ++#if defined(OS_ANDROID) ++ void GetCosmeticFiltersResponder( ++ mojo::PendingReceiver< ++ cf_comm::mojom::CosmeticFiltersCommunication> receiver); ++#endif ++ + protected: + friend class RenderFrameHostFactory; + diff --git a/patches/content-public-browser-BUILD.gn.patch b/patches/content-public-browser-BUILD.gn.patch new file mode 100644 index 000000000000..9389e6c533f3 --- /dev/null +++ b/patches/content-public-browser-BUILD.gn.patch @@ -0,0 +1,16 @@ +diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn +index bd83dfa0a32658c5b45ca001bfd04cc051d8bc73..51dec27a53837f8006076448633a0d72fe3229ab 100644 +--- a/content/public/browser/BUILD.gn ++++ b/content/public/browser/BUILD.gn +@@ -491,6 +491,11 @@ source_set("browser_sources") { + "//ui/shell_dialogs", + "//ui/surface", + ] ++ if (is_android) { deps += ["//brave/content/browser/mojom",] ++ sources += ["//brave/content/browser/cosmetic_filters_communication_impl.cc", ++ "//brave/content/browser/cosmetic_filters_communication_impl.h", ++ "//brave/content/browser/cosmetic_filters_observer.h", ++ "//brave/content/public/browser/brave_render_frame_host.cc"]} + + allow_circular_includes_from = [ + # This target is a pair with content/browser. They always go together and diff --git a/patches/content-public-browser-render_frame_host.h.patch b/patches/content-public-browser-render_frame_host.h.patch new file mode 100644 index 000000000000..890ffc3fc49f --- /dev/null +++ b/patches/content-public-browser-render_frame_host.h.patch @@ -0,0 +1,32 @@ +diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h +index 5fa3f1263137374f433acd4fd6a88b033aa61881..4465008f12673a86b4b42d91f7519ef5576e37c3 100644 +--- a/content/public/browser/render_frame_host.h ++++ b/content/public/browser/render_frame_host.h +@@ -83,6 +83,7 @@ class SiteInstance; + class BrowserContext; + class StoragePartition; + class WebUI; ++class CosmeticFiltersCommunicationImpl; + + // The interface provides a communication conduit with a frame in the renderer. + class CONTENT_EXPORT RenderFrameHost : public IPC::Listener, +@@ -124,7 +125,9 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener, + const base::android::JavaRef& jrender_frame_host_android); + #endif + +- ~RenderFrameHost() override {} ++ ~RenderFrameHost() override;// {} ++ ++ std::unique_ptr cosmetic_filters_communication_impl_; + + // Returns the route id for this frame. + virtual int GetRoutingID() = 0; +@@ -643,7 +646,7 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener, + private: + // This interface should only be implemented inside content. + friend class RenderFrameHostImpl; +- RenderFrameHost() {} ++ RenderFrameHost();// {} + }; + + } // namespace content diff --git a/renderer/BUILD.gn b/renderer/BUILD.gn index 40e8d9b4f948..969d2771dd91 100644 --- a/renderer/BUILD.gn +++ b/renderer/BUILD.gn @@ -11,4 +11,11 @@ source_set("renderer") { public_deps = [ "//chrome/renderer", ] + + if (is_android) { + deps = [ + "//chrome/common", + "//brave/components/cosmetic_filters/content/renderer", + ] + } } diff --git a/renderer/brave_content_renderer_client.cc b/renderer/brave_content_renderer_client.cc index 57d2952ebb02..4dfe92895449 100644 --- a/renderer/brave_content_renderer_client.cc +++ b/renderer/brave_content_renderer_client.cc @@ -4,6 +4,11 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "brave/renderer/brave_content_renderer_client.h" + +#if defined(OS_ANDROID) +#include "brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h" +#include "chrome/common/chrome_isolated_world_ids.h" +#endif #include "third_party/blink/public/platform/web_runtime_features.h" BraveContentRendererClient::BraveContentRendererClient() @@ -17,3 +22,13 @@ SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() { blink::WebRuntimeFeatures::EnableSharedArrayBuffer(false); } BraveContentRendererClient::~BraveContentRendererClient() = default; + +#if defined(OS_ANDROID) +void BraveContentRendererClient::RenderFrameCreated( + content::RenderFrame* render_frame) { + ChromeContentRendererClient::RenderFrameCreated(render_frame); + + new cosmetic_filters_worker::CosmeticFiltersJsRenderFrameObserver( + render_frame, ISOLATED_WORLD_ID_CHROME_INTERNAL); +} +#endif diff --git a/renderer/brave_content_renderer_client.h b/renderer/brave_content_renderer_client.h index 5f3d4b5f18c2..6f76e2c42744 100644 --- a/renderer/brave_content_renderer_client.h +++ b/renderer/brave_content_renderer_client.h @@ -12,6 +12,9 @@ class BraveContentRendererClient : public ChromeContentRendererClient { BraveContentRendererClient(); ~BraveContentRendererClient() override; void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override; +#if defined(OS_ANDROID) + void RenderFrameCreated(content::RenderFrame* render_frame) override; +#endif private: DISALLOW_COPY_AND_ASSIGN(BraveContentRendererClient); diff --git a/renderer/sources.gni b/renderer/sources.gni index 00cb3d91dd12..ba72f04c2440 100644 --- a/renderer/sources.gni +++ b/renderer/sources.gni @@ -6,8 +6,18 @@ brave_chrome_renderer_sources = [ "//brave/renderer/brave_content_renderer_client.cc", "//brave/renderer/brave_content_renderer_client.h", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.cc", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h", ] brave_chrome_renderer_public_deps = [ + "//base", "//brave/components/content_settings/renderer", - "//third_party/blink/public:blink" + "//content/public/renderer", + "//gin", + "//mojo/public/cpp/bindings", + "//third_party/blink/public:blink", + "//third_party/blink/public/common", + "//v8", ] From da1aac2bc53cf27451f06132456590471f5a0693 Mon Sep 17 00:00:00 2001 From: Serg Date: Wed, 11 Nov 2020 14:33:07 -0500 Subject: [PATCH 02/45] optimized cf patches --- .../brave_cosmetic_resources_tab_helper.cc | 7 ++-- .../browser/browser_interface_binders.cc | 36 +++++++++++++++++++ .../renderer_host/render_frame_host_impl.cc | 22 ++++++++++++ .../renderer_host/render_frame_host_impl.h | 18 ++++++++++ .../public/browser/brave_render_frame_host.cc | 4 ++- ...browser-browser_interface_binders.cc.patch | 25 ------------- ...derer_host-render_frame_host_impl.cc.patch | 30 ---------------- ...nderer_host-render_frame_host_impl.h.patch | 19 ++-------- 8 files changed, 84 insertions(+), 77 deletions(-) create mode 100644 chromium_src/content/browser/browser_interface_binders.cc create mode 100644 chromium_src/content/browser/renderer_host/render_frame_host_impl.cc create mode 100644 chromium_src/content/browser/renderer_host/render_frame_host_impl.h delete mode 100644 patches/content-browser-browser_interface_binders.cc.patch delete mode 100644 patches/content-browser-renderer_host-render_frame_host_impl.cc.patch diff --git a/browser/android/brave_cosmetic_resources_tab_helper.cc b/browser/android/brave_cosmetic_resources_tab_helper.cc index 7facd1d23ac8..ac716817cbdd 100644 --- a/browser/android/brave_cosmetic_resources_tab_helper.cc +++ b/browser/android/brave_cosmetic_resources_tab_helper.cc @@ -237,8 +237,6 @@ void BraveCosmeticResourcesTabHelper::CSSRulesRoutine( base::ListValue* force_hide_selectors_list = nullptr; if (resources_dict->GetList("hide_selectors", &hide_selectors_list)) { if (enabled_1st_party_cf_filtering_) { - // TODO - // resources.force_hide_selectors.push(...resources.hide_selectors) force_hide_selectors_list = hide_selectors_list; } else { std::string cosmeticFilterConsiderNewSelectors_script = @@ -363,9 +361,8 @@ void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( return; } if (enabled_1st_party_cf_filtering_) { - // TODO - // resources.force_hide_selectors.push(...resources.hide_selectors) - //force_hide_selectors_list = selectors; + // (sergz) We do the same in else section, we need to figure out do we + // need that if at all } else { std::string cosmeticFilterConsiderNewSelectors_script = "(function() {" diff --git a/chromium_src/content/browser/browser_interface_binders.cc b/chromium_src/content/browser/browser_interface_binders.cc new file mode 100644 index 000000000000..ab52d1532747 --- /dev/null +++ b/chromium_src/content/browser/browser_interface_binders.cc @@ -0,0 +1,36 @@ +/* Copyright (c) 2020 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/. */ + +#define PopulateBinderMap PopulateBinderMap_ChromiumImpl +#include "../../../../content/browser/browser_interface_binders.cc" +#undef PopulateBinderMap + +namespace content { +namespace internal { + +void PopulateBinderMap(RenderFrameHostImpl* host, mojo::BinderMap* map) { + PopulateBinderMap_ChromiumImpl(host, map); +#if defined(OS_ANDROID) + // Register the handler for cosmetic filters responder. + map->Add(base::BindRepeating( + &RenderFrameHostImpl::GetCosmeticFiltersResponder, + base::Unretained(host))); +#endif +} + +void PopulateBinderMap(DedicatedWorkerHost* host, mojo::BinderMap* map) { + PopulateBinderMap_ChromiumImpl(host, map); +} + +void PopulateBinderMap(SharedWorkerHost* host, mojo::BinderMap* map) { + PopulateBinderMap_ChromiumImpl(host, map); +} + +void PopulateBinderMap(ServiceWorkerHost* host, mojo::BinderMap* map) { + PopulateBinderMap_ChromiumImpl(host, map); +} + +} // namespace internal +} // namespace content diff --git a/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc b/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc new file mode 100644 index 000000000000..8531843e1dc5 --- /dev/null +++ b/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc @@ -0,0 +1,22 @@ +/* Copyright (c) 2020 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/content/browser/cosmetic_filters_communication_impl.h" +#include "../../../../../content/browser/renderer_host/render_frame_host_impl.cc" + +namespace content { + +#if defined(OS_ANDROID) +void RenderFrameHostImpl::GetCosmeticFiltersResponder( + mojo::PendingReceiver< + cf_comm::mojom::CosmeticFiltersCommunication> receiver) { + CosmeticFiltersCommunicationImpl::CreateInstance(this, nullptr); + mojo::MakeSelfOwnedReceiver( + std::move(cosmetic_filters_communication_impl_), + std::move(receiver)); +} +#endif + +} // namespace content diff --git a/chromium_src/content/browser/renderer_host/render_frame_host_impl.h b/chromium_src/content/browser/renderer_host/render_frame_host_impl.h new file mode 100644 index 000000000000..d7c7b17d1a12 --- /dev/null +++ b/chromium_src/content/browser/renderer_host/render_frame_host_impl.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2020 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_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_H_ +#define BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_H_ + +#include "brave/content/browser/mojom/cosmetic_filters_communication.mojom.h" + +#define BRAVE_RENDERER_FRAME_HOST_H \ + void GetCosmeticFiltersResponder( \ + mojo::PendingReceiver< \ + cf_comm::mojom::CosmeticFiltersCommunication> receiver); + +#include "../../../../../content/browser/renderer_host/render_frame_host_impl.h" // NOLINT + +#endif // BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_H_ diff --git a/content/public/browser/brave_render_frame_host.cc b/content/public/browser/brave_render_frame_host.cc index 8ecb995eaabb..6e3d9297f410 100644 --- a/content/public/browser/brave_render_frame_host.cc +++ b/content/public/browser/brave_render_frame_host.cc @@ -9,7 +9,9 @@ namespace content { -RenderFrameHost::RenderFrameHost() {} +RenderFrameHost::RenderFrameHost() { + cosmetic_filters_communication_impl_ = nullptr; +} RenderFrameHost::~RenderFrameHost() {} diff --git a/patches/content-browser-browser_interface_binders.cc.patch b/patches/content-browser-browser_interface_binders.cc.patch deleted file mode 100644 index 7f2b42c0e656..000000000000 --- a/patches/content-browser-browser_interface_binders.cc.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc -index ba25194ba4178c7caa396ce44779cf70f4d69998..99f4b92f036db3f845e76fd9f7b744ec9e183e5a 100644 ---- a/content/browser/browser_interface_binders.cc -+++ b/content/browser/browser_interface_binders.cc -@@ -136,6 +136,7 @@ - #endif - - #if defined(OS_ANDROID) -+#include "brave/content/browser/mojom/cosmetic_filters_communication.mojom.h" - #include "content/browser/android/date_time_chooser_android.h" - #include "content/browser/android/text_suggestion_host_android.h" - #include "content/browser/renderer_host/render_widget_host_view_android.h" -@@ -748,6 +749,12 @@ void PopulateFrameBinders(RenderFrameHostImpl* host, mojo::BinderMap* map) { - map->Add( - base::BindRepeating(&BindTextInputHost)); - #endif -+#if defined(OS_ANDROID) -+ // Register the handler for cosmetic filters responder. -+ map->Add(base::BindRepeating( -+ &RenderFrameHostImpl::GetCosmeticFiltersResponder, -+ base::Unretained(host))); -+#endif - } - - void PopulateBinderMapWithContext( diff --git a/patches/content-browser-renderer_host-render_frame_host_impl.cc.patch b/patches/content-browser-renderer_host-render_frame_host_impl.cc.patch deleted file mode 100644 index a4cc3c49098b..000000000000 --- a/patches/content-browser-renderer_host-render_frame_host_impl.cc.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc -index 497033d3d5257daffe4aca2ebdd1fd71513db73f..f710a73beed45b44c822db4ee6366b7ca0a991e3 100644 ---- a/content/browser/renderer_host/render_frame_host_impl.cc -+++ b/content/browser/renderer_host/render_frame_host_impl.cc -@@ -1057,6 +1057,7 @@ RenderFrameHostImpl::RenderFrameHostImpl( - // of overrides. - idle_manager_ = - std::make_unique(GetProcess()->GetBrowserContext()); -+ cosmetic_filters_communication_impl_ = nullptr; - } - - RenderFrameHostImpl::~RenderFrameHostImpl() { -@@ -9683,6 +9684,17 @@ bool RenderFrameHostImpl::DocumentUsedWebOTP() { - return document_used_web_otp_; - } - -+#if defined(OS_ANDROID) -+void RenderFrameHostImpl::GetCosmeticFiltersResponder( -+ mojo::PendingReceiver< -+ cf_comm::mojom::CosmeticFiltersCommunication> receiver) { -+ CosmeticFiltersCommunicationImpl::CreateInstance(this, nullptr); -+ mojo::MakeSelfOwnedReceiver( -+ std::move(cosmetic_filters_communication_impl_), -+ std::move(receiver)); -+} -+#endif -+ - std::ostream& operator<<(std::ostream& o, - const RenderFrameHostImpl::LifecycleState& s) { - return o << LifecycleStateToString(s); diff --git a/patches/content-browser-renderer_host-render_frame_host_impl.h.patch b/patches/content-browser-renderer_host-render_frame_host_impl.h.patch index 10aef0c74756..de6f63f63733 100644 --- a/patches/content-browser-renderer_host-render_frame_host_impl.h.patch +++ b/patches/content-browser-renderer_host-render_frame_host_impl.h.patch @@ -1,25 +1,12 @@ diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h -index dc1015e539e768eb280c5f6b226415ec2f804ffe..3b34cc0b8494af5030852fa2eb78fad7634a0b74 100644 +index dc1015e539e768eb280c5f6b226415ec2f804ffe..549a8a5b17ab010a0cb4cb5a14abc94551e12e38 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h -@@ -149,6 +149,7 @@ - #include "ui/gfx/geometry/rect.h" - - #if defined(OS_ANDROID) -+#include "brave/content/browser/cosmetic_filters_communication_impl.h" - #include "services/device/public/mojom/nfc.mojom.h" - #else - #include "third_party/blink/public/mojom/hid/hid.mojom.h" -@@ -1826,6 +1827,12 @@ class CONTENT_EXPORT RenderFrameHostImpl +@@ -1826,6 +1826,7 @@ class CONTENT_EXPORT RenderFrameHostImpl std::unique_ptr CreateMessageFilterForAssociatedReceiver( const char* interface_name); -+#if defined(OS_ANDROID) -+ void GetCosmeticFiltersResponder( -+ mojo::PendingReceiver< -+ cf_comm::mojom::CosmeticFiltersCommunication> receiver); -+#endif -+ ++ BRAVE_RENDERER_FRAME_HOST_H protected: friend class RenderFrameHostFactory; From 476eae54222a18e4d1746109bf93e05908107689 Mon Sep 17 00:00:00 2001 From: Serg Date: Thu, 12 Nov 2020 14:54:45 -0500 Subject: [PATCH 03/45] updates cf patches --- .../content/public/browser/render_frame_host.h | 16 ++++++++++++++++ content/public/browser/BUILD.gn | 16 ++++++++++++++++ patches/content-public-browser-BUILD.gn.patch | 10 +++------- ...ent-public-browser-render_frame_host.h.patch | 17 ++++------------- 4 files changed, 39 insertions(+), 20 deletions(-) create mode 100644 chromium_src/content/public/browser/render_frame_host.h create mode 100644 content/public/browser/BUILD.gn diff --git a/chromium_src/content/public/browser/render_frame_host.h b/chromium_src/content/public/browser/render_frame_host.h new file mode 100644 index 000000000000..d4b675af9083 --- /dev/null +++ b/chromium_src/content/public/browser/render_frame_host.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2020 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_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ +#define BRAVE_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ + +#include "brave/content/browser/cosmetic_filters_communication_impl.h" + +#define BRAVE_RENDER_FRAME_HOST_H \ + std::unique_ptr \ + cosmetic_filters_communication_impl_; +#include "../../../../../content/public/browser/render_frame_host.h" // NOLINT + +#endif // BRAVE_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ \ No newline at end of file diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn new file mode 100644 index 000000000000..8683773d5746 --- /dev/null +++ b/content/public/browser/BUILD.gn @@ -0,0 +1,16 @@ +source_set("browser") { + if (is_android) { + sources = [ + "//brave/content/browser/cosmetic_filters_communication_impl.cc", + "//brave/content/browser/cosmetic_filters_communication_impl.h", + "//brave/content/browser/cosmetic_filters_observer.h", + "//brave/content/public/browser/brave_render_frame_host.cc" + ] + + deps = [ + "//base", + "//brave/content/browser/mojom", + "//skia", + ] + } +} \ No newline at end of file diff --git a/patches/content-public-browser-BUILD.gn.patch b/patches/content-public-browser-BUILD.gn.patch index 9389e6c533f3..78b29605a00f 100644 --- a/patches/content-public-browser-BUILD.gn.patch +++ b/patches/content-public-browser-BUILD.gn.patch @@ -1,16 +1,12 @@ diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn -index bd83dfa0a32658c5b45ca001bfd04cc051d8bc73..51dec27a53837f8006076448633a0d72fe3229ab 100644 +index bd83dfa0a32658c5b45ca001bfd04cc051d8bc73..48d08aefda3e696d897b8e73a4a853a52f88aa27 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn -@@ -491,6 +491,11 @@ source_set("browser_sources") { +@@ -491,6 +491,7 @@ source_set("browser_sources") { "//ui/shell_dialogs", "//ui/surface", ] -+ if (is_android) { deps += ["//brave/content/browser/mojom",] -+ sources += ["//brave/content/browser/cosmetic_filters_communication_impl.cc", -+ "//brave/content/browser/cosmetic_filters_communication_impl.h", -+ "//brave/content/browser/cosmetic_filters_observer.h", -+ "//brave/content/public/browser/brave_render_frame_host.cc"]} ++ deps += ["//brave/content/public/browser:browser",] allow_circular_includes_from = [ # This target is a pair with content/browser. They always go together and diff --git a/patches/content-public-browser-render_frame_host.h.patch b/patches/content-public-browser-render_frame_host.h.patch index 890ffc3fc49f..8ef0ca327b19 100644 --- a/patches/content-public-browser-render_frame_host.h.patch +++ b/patches/content-public-browser-render_frame_host.h.patch @@ -1,27 +1,18 @@ diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h -index 5fa3f1263137374f433acd4fd6a88b033aa61881..4465008f12673a86b4b42d91f7519ef5576e37c3 100644 +index 5fa3f1263137374f433acd4fd6a88b033aa61881..6db6c0fa65bc4e6d0e85c0231fa4f4208226844d 100644 --- a/content/public/browser/render_frame_host.h +++ b/content/public/browser/render_frame_host.h -@@ -83,6 +83,7 @@ class SiteInstance; - class BrowserContext; - class StoragePartition; - class WebUI; -+class CosmeticFiltersCommunicationImpl; - - // The interface provides a communication conduit with a frame in the renderer. - class CONTENT_EXPORT RenderFrameHost : public IPC::Listener, -@@ -124,7 +125,9 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener, +@@ -124,7 +124,8 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener, const base::android::JavaRef& jrender_frame_host_android); #endif - ~RenderFrameHost() override {} + ~RenderFrameHost() override;// {} -+ -+ std::unique_ptr cosmetic_filters_communication_impl_; ++ BRAVE_RENDER_FRAME_HOST_H // Returns the route id for this frame. virtual int GetRoutingID() = 0; -@@ -643,7 +646,7 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener, +@@ -643,7 +644,7 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener, private: // This interface should only be implemented inside content. friend class RenderFrameHostImpl; From 3bc0ae3f1f9ba5425733424b00682a243375b98c Mon Sep 17 00:00:00 2001 From: Serg Date: Mon, 16 Nov 2020 09:59:25 -0500 Subject: [PATCH 04/45] guards cosmetic filters for Android implementation only --- .../renderer_host/render_frame_host_impl.cc | 2 ++ .../renderer_host/render_frame_host_impl.h | 12 ++++++--- .../public/browser/render_frame_host.h | 4 +++ content/public/browser/BUILD.gn | 14 ++++++---- .../public/browser/brave_render_frame_host.cc | 4 +++ renderer/sources.gni | 27 ++++++++++++------- 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc b/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc index 8531843e1dc5..1caaaf3f390c 100644 --- a/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc +++ b/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc @@ -3,7 +3,9 @@ * 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/. */ +#if defined(OS_ANDROID) #include "brave/content/browser/cosmetic_filters_communication_impl.h" +#endif #include "../../../../../content/browser/renderer_host/render_frame_host_impl.cc" namespace content { diff --git a/chromium_src/content/browser/renderer_host/render_frame_host_impl.h b/chromium_src/content/browser/renderer_host/render_frame_host_impl.h index d7c7b17d1a12..a2b927da705c 100644 --- a/chromium_src/content/browser/renderer_host/render_frame_host_impl.h +++ b/chromium_src/content/browser/renderer_host/render_frame_host_impl.h @@ -3,16 +3,20 @@ * 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_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_H_ -#define BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_H_ +#ifndef BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_IMPL_H_ +#define BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_IMPL_H_ +#if defined(OS_ANDROID) #include "brave/content/browser/mojom/cosmetic_filters_communication.mojom.h" -#define BRAVE_RENDERER_FRAME_HOST_H \ +#define BRAVE_RENDERER_FRAME_HOST_IMPL_H \ void GetCosmeticFiltersResponder( \ mojo::PendingReceiver< \ cf_comm::mojom::CosmeticFiltersCommunication> receiver); +#else +#define BRAVE_RENDERER_FRAME_HOST_IMPL_H +#endif #include "../../../../../content/browser/renderer_host/render_frame_host_impl.h" // NOLINT -#endif // BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_H_ +#endif // BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_IMPL_H_ diff --git a/chromium_src/content/public/browser/render_frame_host.h b/chromium_src/content/public/browser/render_frame_host.h index d4b675af9083..c81cbc6fb032 100644 --- a/chromium_src/content/public/browser/render_frame_host.h +++ b/chromium_src/content/public/browser/render_frame_host.h @@ -6,11 +6,15 @@ #ifndef BRAVE_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ #define BRAVE_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ +#if defined(OS_ANDROID) #include "brave/content/browser/cosmetic_filters_communication_impl.h" #define BRAVE_RENDER_FRAME_HOST_H \ std::unique_ptr \ cosmetic_filters_communication_impl_; +#else +#define BRAVE_RENDER_FRAME_HOST_H +#endif #include "../../../../../content/public/browser/render_frame_host.h" // NOLINT #endif // BRAVE_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ \ No newline at end of file diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index 8683773d5746..ff0782b23226 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn @@ -1,16 +1,20 @@ source_set("browser") { + sources = [ + "//brave/content/public/browser/brave_render_frame_host.cc", + ] + deps = [ + "//base", + "//skia", + ] if (is_android) { - sources = [ + sources += [ "//brave/content/browser/cosmetic_filters_communication_impl.cc", "//brave/content/browser/cosmetic_filters_communication_impl.h", "//brave/content/browser/cosmetic_filters_observer.h", - "//brave/content/public/browser/brave_render_frame_host.cc" ] - deps = [ - "//base", + deps += [ "//brave/content/browser/mojom", - "//skia", ] } } \ No newline at end of file diff --git a/content/public/browser/brave_render_frame_host.cc b/content/public/browser/brave_render_frame_host.cc index 6e3d9297f410..79374acd4f9a 100644 --- a/content/public/browser/brave_render_frame_host.cc +++ b/content/public/browser/brave_render_frame_host.cc @@ -5,12 +5,16 @@ #include "content/public/browser/render_frame_host.h" +#if defined(OS_ANDROID) #include "brave/content/browser/cosmetic_filters_communication_impl.h" +#endif namespace content { RenderFrameHost::RenderFrameHost() { +#if defined(OS_ANDROID) cosmetic_filters_communication_impl_ = nullptr; +#endif } RenderFrameHost::~RenderFrameHost() {} diff --git a/renderer/sources.gni b/renderer/sources.gni index ba72f04c2440..8a4a61b0b613 100644 --- a/renderer/sources.gni +++ b/renderer/sources.gni @@ -6,18 +6,27 @@ brave_chrome_renderer_sources = [ "//brave/renderer/brave_content_renderer_client.cc", "//brave/renderer/brave_content_renderer_client.h", - "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.cc", - "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h", - "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc", - "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h", ] + brave_chrome_renderer_public_deps = [ "//base", "//brave/components/content_settings/renderer", - "//content/public/renderer", - "//gin", - "//mojo/public/cpp/bindings", "//third_party/blink/public:blink", - "//third_party/blink/public/common", - "//v8", ] + +if (is_android) { + brave_chrome_renderer_sources += [ + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.cc", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h", + ] + + brave_chrome_renderer_public_deps += [ + "//content/public/renderer", + "//gin", + "//mojo/public/cpp/bindings", + "//third_party/blink/public/common", + "//v8", + ] +} From 2774592c27055985c4b053e7b3123ac8adcbbc5a Mon Sep 17 00:00:00 2001 From: Serg Date: Mon, 16 Nov 2020 10:00:53 -0500 Subject: [PATCH 05/45] updates cf patches --- ...ntent-browser-renderer_host-render_frame_host_impl.h.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/content-browser-renderer_host-render_frame_host_impl.h.patch b/patches/content-browser-renderer_host-render_frame_host_impl.h.patch index de6f63f63733..e25fbcf2d4c8 100644 --- a/patches/content-browser-renderer_host-render_frame_host_impl.h.patch +++ b/patches/content-browser-renderer_host-render_frame_host_impl.h.patch @@ -1,12 +1,12 @@ diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h -index dc1015e539e768eb280c5f6b226415ec2f804ffe..549a8a5b17ab010a0cb4cb5a14abc94551e12e38 100644 +index dc1015e539e768eb280c5f6b226415ec2f804ffe..c24ec63bd5fd2187cb762d534e246d203bb7e57a 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h @@ -1826,6 +1826,7 @@ class CONTENT_EXPORT RenderFrameHostImpl std::unique_ptr CreateMessageFilterForAssociatedReceiver( const char* interface_name); -+ BRAVE_RENDERER_FRAME_HOST_H ++ BRAVE_RENDERER_FRAME_HOST_IMPL_H protected: friend class RenderFrameHostFactory; From bc3377f60d85d7a9c27883866cf64cb8a59604d8 Mon Sep 17 00:00:00 2001 From: Serg Date: Tue, 17 Nov 2020 09:59:04 -0500 Subject: [PATCH 06/45] enable cf on desktop/disable extension --- browser/BUILD.gn | 5 + browser/android/BUILD.gn | 4 - .../brave_cosmetic_resources_tab_helper.h | 71 -------------- .../brave_cosmetic_resources_tab_helper.cc | 6 +- browser/brave_tab_helpers.cc | 4 +- browser/extensions/api/brave_shields_api.cc | 92 +++++++++---------- .../browser/browser_interface_binders.cc | 2 - .../renderer_host/render_frame_host_impl.cc | 4 - .../renderer_host/render_frame_host_impl.h | 10 +- .../public/browser/render_frame_host.h | 7 +- .../extension/brave_extension/BUILD.gn | 1 - .../actions/shieldsPanelActions.ts | 11 --- .../background/api/cosmeticFilterAPI.ts | 69 -------------- .../background/events/cosmeticFilterEvents.ts | 4 +- .../reducers/shieldsPanelReducer.ts | 62 ------------- .../constants/shieldsPanelTypes.ts | 1 - .../extension/brave_extension/manifest.json | 11 --- .../types/actions/shieldsPanelActions.ts | 14 --- .../types/constants/shieldsPanelTypes.ts | 1 - .../renderer/cosmetic_filters_js_handler.cc | 2 +- .../renderer/cosmetic_filters_js_handler.h | 2 + ...osmetic_filters_js_render_frame_observer.h | 5 +- .../cosmetic_filters_communication_impl.cc | 8 +- .../cosmetic_filters_communication_impl.h | 22 ++--- content/browser/cosmetic_filters_observer.h | 7 +- content/public/browser/BUILD.gn | 17 +--- .../public/browser/brave_render_frame_host.cc | 4 - renderer/BUILD.gn | 10 +- renderer/brave_content_renderer_client.cc | 6 +- renderer/brave_content_renderer_client.h | 5 +- renderer/sources.gni | 26 ++---- 31 files changed, 110 insertions(+), 383 deletions(-) delete mode 100644 browser/android/brave_cosmetic_resources_tab_helper.h rename browser/{android => }/brave_cosmetic_resources_tab_helper.cc (98%) diff --git a/browser/BUILD.gn b/browser/BUILD.gn index e6ea79cbe8ff..dfb796246bfc 100644 --- a/browser/BUILD.gn +++ b/browser/BUILD.gn @@ -48,6 +48,8 @@ source_set("browser_process") { "brave_browser_process_impl.h", "brave_content_browser_client.cc", "brave_content_browser_client.h", + "brave_cosmetic_resources_tab_helper.cc", + "brave_cosmetic_resources_tab_helper.h", "brave_local_state_prefs.cc", "brave_local_state_prefs.h", "brave_profile_prefs.cc", @@ -150,6 +152,8 @@ source_set("browser_process") { "//brave/components/speedreader:buildflags", "//brave/components/tor/buildflags", "//brave/components/weekly_storage", + "//brave/content/browser/mojom", + "//brave/content/public/browser:browser", "//brave/services/network/public/cpp", "//brave/ui/brave_ads", "//brave/ui/brave_ads/public/cpp", @@ -181,6 +185,7 @@ source_set("browser_process") { "//components/update_client:unzip_impl", "//content/public/browser", "//content/public/common", + "//mojo/public/cpp/bindings", "//extensions/buildflags", "//services/metrics/public/cpp:metrics_cpp", "//services/network/public/cpp", diff --git a/browser/android/BUILD.gn b/browser/android/BUILD.gn index 6b6991c37b02..4beefe722e98 100644 --- a/browser/android/BUILD.gn +++ b/browser/android/BUILD.gn @@ -5,8 +5,6 @@ source_set("android_browser_process") { check_includes = false sources = [ - "brave_cosmetic_resources_tab_helper.cc", - "brave_cosmetic_resources_tab_helper.h", "brave_feature_list.cc", "brave_relaunch_utils.cc", "brave_shields_content_settings.cc", @@ -16,7 +14,6 @@ source_set("android_browser_process") { deps = [ "//base", - "//brave/content/browser/mojom", "//brave/browser/android/preferences", "//brave/browser/brave_stats:stats_updater", "//brave/build/android:jni_headers", @@ -27,7 +24,6 @@ source_set("android_browser_process") { "//components/flags_ui", "//components/ntp_tiles", "//components/translate/core/browser", - "//mojo/public/cpp/bindings", ] if (brave_ads_enabled) { diff --git a/browser/android/brave_cosmetic_resources_tab_helper.h b/browser/android/brave_cosmetic_resources_tab_helper.h deleted file mode 100644 index 5a464cd4c246..000000000000 --- a/browser/android/brave_cosmetic_resources_tab_helper.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2020 The Brave Authors. All rights reserved. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 3.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_BROWSER_ANDROID_BRAVE_COSMETIC_RESOURCES_TAB_HELPER_H_ -#define BRAVE_BROWSER_ANDROID_BRAVE_COSMETIC_RESOURCES_TAB_HELPER_H_ - -#include - -#include "base/memory/weak_ptr.h" -#include "brave/content/browser/cosmetic_filters_observer.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" - -class BraveCosmeticResourcesTabHelper - : public content::CosmeticFiltersObserver, - public content::WebContentsObserver, - public content::WebContentsUserData, - public base::SupportsWeakPtr { - public: - explicit BraveCosmeticResourcesTabHelper(content::WebContents* contents); - ~BraveCosmeticResourcesTabHelper() override; - - // content::WebContentsObserver overrides: - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; - void ResourceLoadComplete( - content::RenderFrameHost* render_frame_host, - const content::GlobalRequestID& request_id, - const blink::mojom::ResourceLoadInfo& resource_load_info) override; - bool OnMessageReceived(const IPC::Message& message, - content::RenderFrameHost* render_frame_host) override; - bool OnMessageReceived(const IPC::Message& message) override; - // - - // content::CosmeticFiltersObserver overrides: - void HiddenClassIdSelectors(content::RenderFrameHost* render_frame_host, - const std::vector& classes, - const std::vector& ids) override; - // - - WEB_CONTENTS_USER_DATA_KEY_DECL(); - - private: - void ProcessURL(content::RenderFrameHost* render_frame_host, const GURL& url, - const bool& main_frame); - - std::unique_ptr GetUrlCosmeticResourcesOnTaskRunner( - const std::string& url); - void GetUrlCosmeticResourcesOnUI(content::RenderFrameHost* render_frame_host, - const std::string& url, bool main_frame, - std::unique_ptr resources); - void CSSRulesRoutine(const std::string& url, - base::DictionaryValue* resources_dict, - content::RenderFrameHost* render_frame_host); - - std::unique_ptr GetHiddenClassIdSelectorsOnTaskRunner( - const std::vector& classes, - const std::vector& ids); - void GetHiddenClassIdSelectorsOnUI( - content::RenderFrameHost* render_frame_host, - std::unique_ptr selectors); - - std::vector exceptions_; - bool enabled_1st_party_cf_filtering_; - - DISALLOW_COPY_AND_ASSIGN(BraveCosmeticResourcesTabHelper); -}; - -#endif // BRAVE_BROWSER_ANDROID_BRAVE_COSMETIC_RESOURCES_TAB_HELPER_H_ diff --git a/browser/android/brave_cosmetic_resources_tab_helper.cc b/browser/brave_cosmetic_resources_tab_helper.cc similarity index 98% rename from browser/android/brave_cosmetic_resources_tab_helper.cc rename to browser/brave_cosmetic_resources_tab_helper.cc index ac716817cbdd..04a357d08642 100644 --- a/browser/android/brave_cosmetic_resources_tab_helper.cc +++ b/browser/brave_cosmetic_resources_tab_helper.cc @@ -3,7 +3,7 @@ * License, v. 3.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/browser/android/brave_cosmetic_resources_tab_helper.h" +#include "brave/browser/brave_cosmetic_resources_tab_helper.h" #include #include @@ -40,7 +40,8 @@ const char k_observing_script[] = "(!notYetQueriedIds || notYetQueriedIds.length === 0)) {" "return;" "};" - "cf_worker.hiddenClassIdSelectors(JSON.stringify({classes: notYetQueriedClasses, ids: notYetQueriedIds}));" + "cf_worker.hiddenClassIdSelectors(" + "JSON.stringify({classes: notYetQueriedClasses, ids: notYetQueriedIds}));" "/*chrome.runtime.sendMessage({" "type: 'hiddenClassIdSelectors'," "classes: notYetQueriedClasses || []," @@ -208,7 +209,6 @@ void BraveCosmeticResourcesTabHelper::GetUrlCosmeticResourcesOnUI( // Working on css rules if (!main_frame) return; - CSSRulesRoutine(url, resources_dict, frame_id); } } diff --git a/browser/brave_tab_helpers.cc b/browser/brave_tab_helpers.cc index bbeeb955c799..9741940576ca 100644 --- a/browser/brave_tab_helpers.cc +++ b/browser/brave_tab_helpers.cc @@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/feature_list.h" +#include "brave/browser/brave_cosmetic_resources_tab_helper.h" #include "brave/browser/brave_stats/brave_stats_tab_helper.h" #include "brave/browser/ephemeral_storage/ephemeral_storage_tab_helper.h" #include "brave/browser/farbling/farbling_tab_helper.h" @@ -31,7 +32,6 @@ #endif #if defined(OS_ANDROID) -#include "brave/browser/android/brave_cosmetic_resources_tab_helper.h" #include "brave/browser/android/preferences/background_video_playback_tab_helper.h" #include "brave/browser/android/preferences/website/desktop_mode_tab_helper.h" #endif @@ -80,11 +80,11 @@ void AttachTabHelpers(content::WebContents* web_contents) { #endif brave_shields::BraveShieldsWebContentsObserver::CreateForWebContents( web_contents); + BraveCosmeticResourcesTabHelper::CreateForWebContents(web_contents); #if defined(OS_ANDROID) DesktopModeTabHelper::CreateForWebContents(web_contents); BackgroundVideoPlaybackTabHelper::CreateForWebContents(web_contents); - BraveCosmeticResourcesTabHelper::CreateForWebContents(web_contents); #else // Add tab helpers here unless they are intended for android too BraveBookmarkTabHelper::CreateForWebContents(web_contents); diff --git a/browser/extensions/api/brave_shields_api.cc b/browser/extensions/api/brave_shields_api.cc index 3a28dea9a93e..bab98a811e11 100644 --- a/browser/extensions/api/brave_shields_api.cc +++ b/browser/extensions/api/brave_shields_api.cc @@ -66,31 +66,31 @@ BraveShieldsUrlCosmeticResourcesFunction::Run() { std::unique_ptr BraveShieldsUrlCosmeticResourcesFunction:: GetUrlCosmeticResourcesOnTaskRunner(const std::string& url) { - base::Optional resources = g_brave_browser_process-> - ad_block_service()->UrlCosmeticResources(url); + // base::Optional resources = g_brave_browser_process-> + // ad_block_service()->UrlCosmeticResources(url); - if (!resources || !resources->is_dict()) { - return std::unique_ptr(); - } + // if (!resources || !resources->is_dict()) { + // return std::unique_ptr(); + // } - base::Optional regional_resources = g_brave_browser_process-> - ad_block_regional_service_manager()->UrlCosmeticResources(url); + // base::Optional regional_resources = g_brave_browser_process-> + // ad_block_regional_service_manager()->UrlCosmeticResources(url); - if (regional_resources && regional_resources->is_dict()) { - ::brave_shields::MergeResourcesInto( - std::move(*regional_resources), &*resources, /*force_hide=*/false); - } + // if (regional_resources && regional_resources->is_dict()) { + // ::brave_shields::MergeResourcesInto( + // std::move(*regional_resources), &*resources, /*force_hide=*/false); + // } - base::Optional custom_resources = g_brave_browser_process-> - ad_block_custom_filters_service()->UrlCosmeticResources(url); + // base::Optional custom_resources = g_brave_browser_process-> + // ad_block_custom_filters_service()->UrlCosmeticResources(url); - if (custom_resources && custom_resources->is_dict()) { - ::brave_shields::MergeResourcesInto( - std::move(*custom_resources), &*resources, /*force_hide=*/true); - } + // if (custom_resources && custom_resources->is_dict()) { + // ::brave_shields::MergeResourcesInto( + // std::move(*custom_resources), &*resources, /*force_hide=*/true); + // } auto result_list = std::make_unique(); - result_list->Append(std::move(*resources)); + // result_list->Append(std::move(*resources)); return result_list; } @@ -126,36 +126,36 @@ std::unique_ptr BraveShieldsHiddenClassIdSelectorsFunction:: const std::vector& classes, const std::vector& ids, const std::vector& exceptions) { - base::Optional hide_selectors = g_brave_browser_process-> - ad_block_service()->HiddenClassIdSelectors(classes, ids, exceptions); - - base::Optional regional_selectors = g_brave_browser_process-> - ad_block_regional_service_manager()-> - HiddenClassIdSelectors(classes, ids, exceptions); - - base::Optional custom_selectors = g_brave_browser_process-> - ad_block_custom_filters_service()-> - HiddenClassIdSelectors(classes, ids, exceptions); - - if (hide_selectors && hide_selectors->is_list()) { - if (regional_selectors && regional_selectors->is_list()) { - for (auto i = regional_selectors->GetList().begin(); - i < regional_selectors->GetList().end(); - i++) { - hide_selectors->Append(std::move(*i)); - } - } - } else { - hide_selectors = std::move(regional_selectors); - } + // base::Optional hide_selectors = g_brave_browser_process-> + // ad_block_service()->HiddenClassIdSelectors(classes, ids, exceptions); + + // base::Optional regional_selectors = g_brave_browser_process-> + // ad_block_regional_service_manager()-> + // HiddenClassIdSelectors(classes, ids, exceptions); + + // base::Optional custom_selectors = g_brave_browser_process-> + // ad_block_custom_filters_service()-> + // HiddenClassIdSelectors(classes, ids, exceptions); + + // if (hide_selectors && hide_selectors->is_list()) { + // if (regional_selectors && regional_selectors->is_list()) { + // for (auto i = regional_selectors->GetList().begin(); + // i < regional_selectors->GetList().end(); + // i++) { + // hide_selectors->Append(std::move(*i)); + // } + // } + // } else { + // hide_selectors = std::move(regional_selectors); + // } auto result_list = std::make_unique(); - if (hide_selectors && hide_selectors->is_list()) { - result_list->Append(std::move(*hide_selectors)); - } - if (custom_selectors && custom_selectors->is_list()) { - result_list->Append(std::move(*custom_selectors)); - } + // if (hide_selectors && hide_selectors->is_list()) { + // result_list->Append(std::move(*hide_selectors)); + // } + // if (custom_selectors && custom_selectors->is_list()) { + // result_list->Append(std::move(*custom_selectors)); + // } return result_list; } diff --git a/chromium_src/content/browser/browser_interface_binders.cc b/chromium_src/content/browser/browser_interface_binders.cc index ab52d1532747..40734583d0e9 100644 --- a/chromium_src/content/browser/browser_interface_binders.cc +++ b/chromium_src/content/browser/browser_interface_binders.cc @@ -12,12 +12,10 @@ namespace internal { void PopulateBinderMap(RenderFrameHostImpl* host, mojo::BinderMap* map) { PopulateBinderMap_ChromiumImpl(host, map); -#if defined(OS_ANDROID) // Register the handler for cosmetic filters responder. map->Add(base::BindRepeating( &RenderFrameHostImpl::GetCosmeticFiltersResponder, base::Unretained(host))); -#endif } void PopulateBinderMap(DedicatedWorkerHost* host, mojo::BinderMap* map) { diff --git a/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc b/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc index 1caaaf3f390c..288b81b8782b 100644 --- a/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc +++ b/chromium_src/content/browser/renderer_host/render_frame_host_impl.cc @@ -3,14 +3,11 @@ * 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/. */ -#if defined(OS_ANDROID) #include "brave/content/browser/cosmetic_filters_communication_impl.h" -#endif #include "../../../../../content/browser/renderer_host/render_frame_host_impl.cc" namespace content { -#if defined(OS_ANDROID) void RenderFrameHostImpl::GetCosmeticFiltersResponder( mojo::PendingReceiver< cf_comm::mojom::CosmeticFiltersCommunication> receiver) { @@ -19,6 +16,5 @@ void RenderFrameHostImpl::GetCosmeticFiltersResponder( std::move(cosmetic_filters_communication_impl_), std::move(receiver)); } -#endif } // namespace content diff --git a/chromium_src/content/browser/renderer_host/render_frame_host_impl.h b/chromium_src/content/browser/renderer_host/render_frame_host_impl.h index a2b927da705c..265968f86559 100644 --- a/chromium_src/content/browser/renderer_host/render_frame_host_impl.h +++ b/chromium_src/content/browser/renderer_host/render_frame_host_impl.h @@ -3,20 +3,16 @@ * 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_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_IMPL_H_ -#define BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_IMPL_H_ +#ifndef BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_RENDER_FRAME_HOST_IMPL_H_ +#define BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_RENDER_FRAME_HOST_IMPL_H_ -#if defined(OS_ANDROID) #include "brave/content/browser/mojom/cosmetic_filters_communication.mojom.h" #define BRAVE_RENDERER_FRAME_HOST_IMPL_H \ void GetCosmeticFiltersResponder( \ mojo::PendingReceiver< \ cf_comm::mojom::CosmeticFiltersCommunication> receiver); -#else -#define BRAVE_RENDERER_FRAME_HOST_IMPL_H -#endif #include "../../../../../content/browser/renderer_host/render_frame_host_impl.h" // NOLINT -#endif // BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_IMPL_H_ +#endif // BRAVE_CHROMIUM_SRC_CONTENT_BROWSER_RENDERER_HOST_RENDER_FRAME_HOST_IMPL_H_ diff --git a/chromium_src/content/public/browser/render_frame_host.h b/chromium_src/content/public/browser/render_frame_host.h index c81cbc6fb032..b4558035ba57 100644 --- a/chromium_src/content/public/browser/render_frame_host.h +++ b/chromium_src/content/public/browser/render_frame_host.h @@ -6,15 +6,12 @@ #ifndef BRAVE_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ #define BRAVE_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ -#if defined(OS_ANDROID) #include "brave/content/browser/cosmetic_filters_communication_impl.h" #define BRAVE_RENDER_FRAME_HOST_H \ std::unique_ptr \ cosmetic_filters_communication_impl_; -#else -#define BRAVE_RENDER_FRAME_HOST_H -#endif + #include "../../../../../content/public/browser/render_frame_host.h" // NOLINT -#endif // BRAVE_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ \ No newline at end of file +#endif // BRAVE_CHROMIUM_SRC_CONTENT_PUBLIC_BROWSER_RENDER_FRAME_HOST_H_ diff --git a/components/brave_extension/extension/brave_extension/BUILD.gn b/components/brave_extension/extension/brave_extension/BUILD.gn index 2e0e84155c1e..3cdad09ed270 100644 --- a/components/brave_extension/extension/brave_extension/BUILD.gn +++ b/components/brave_extension/extension/brave_extension/BUILD.gn @@ -9,7 +9,6 @@ transpile_web_ui("brave_extension") { ["brave_extension_background", rebase_path("background.ts")], ["content", rebase_path("content.ts")], ["content_dapps", rebase_path("content_dapps.ts")], - ["content_cosmetic", rebase_path("content_cosmetic.ts")], ["webstore", rebase_path("webstore.ts")], ] diff --git a/components/brave_extension/extension/brave_extension/actions/shieldsPanelActions.ts b/components/brave_extension/extension/brave_extension/actions/shieldsPanelActions.ts index 4abebb1c715d..b94877e136ce 100644 --- a/components/brave_extension/extension/brave_extension/actions/shieldsPanelActions.ts +++ b/components/brave_extension/extension/brave_extension/actions/shieldsPanelActions.ts @@ -147,17 +147,6 @@ 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, diff --git a/components/brave_extension/extension/brave_extension/background/api/cosmeticFilterAPI.ts b/components/brave_extension/extension/brave_extension/background/api/cosmeticFilterAPI.ts index 95c2700055df..261692c302b5 100644 --- a/components/brave_extension/extension/brave_extension/background/api/cosmeticFilterAPI.ts +++ b/components/brave_extension/extension/brave_extension/background/api/cosmeticFilterAPI.ts @@ -2,75 +2,6 @@ * 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 = {}) => { diff --git a/components/brave_extension/extension/brave_extension/background/events/cosmeticFilterEvents.ts b/components/brave_extension/extension/brave_extension/background/events/cosmeticFilterEvents.ts index 4e6f934f11b5..30f3f4555898 100644 --- a/components/brave_extension/extension/brave_extension/background/events/cosmeticFilterEvents.ts +++ b/components/brave_extension/extension/brave_extension/background/events/cosmeticFilterEvents.ts @@ -125,7 +125,7 @@ export async function onSelectorReturned (response: any) { code: `${rule.selector} {display: none !important;}`, cssOrigin: 'user' }) - - await addSiteCosmeticFilter(rule.host, rule.selector) } + + await addSiteCosmeticFilter(rule.host, rule.selector) } diff --git a/components/brave_extension/extension/brave_extension/background/reducers/shieldsPanelReducer.ts b/components/brave_extension/extension/brave_extension/background/reducers/shieldsPanelReducer.ts index 06b417eadf9f..c82c94b2678d 100644 --- a/components/brave_extension/extension/brave_extension/background/reducers/shieldsPanelReducer.ts +++ b/components/brave_extension/extension/brave_extension/background/reducers/shieldsPanelReducer.ts @@ -36,16 +36,10 @@ import { setAllowScriptOriginsOnce } from '../api/shieldsAPI' import { reloadTab } from '../api/tabsAPI' -import { - injectClassIdStylesheet, - applyAdblockCosmeticFilters, - applyCSSCosmeticFilters -} from '../api/cosmeticFilterAPI' // Helpers import { getAllowedScriptsOrigins } from '../../helpers/noScriptUtils' import { areObjectsEqual } from '../../helpers/objectUtils' -import { getHostname } from '../../helpers/urlUtils' export default function shieldsPanelReducer ( state: State = { @@ -66,7 +60,6 @@ export default function shieldsPanelReducer ( state = shieldsPanelState.resetBlockingResources(state, action.tabId) state = noScriptState.resetNoScriptInfo(state, action.tabId, new window.URL(action.url).origin) } - applyCSSCosmeticFilters(action.tabId, getHostname(action.url)) break } case windowTypes.WINDOW_REMOVED: { @@ -362,61 +355,6 @@ export default function shieldsPanelReducer ( }) break } - case shieldsPanelTypes.GENERATE_CLASS_ID_STYLESHEET: { - const tabData = state.tabs[action.tabId] - if (!tabData) { - console.error('Active tab not found') - break - } - const exceptions = tabData.cosmeticFilters.ruleExceptions - const hide1pContent = tabData.firstPartyCosmeticFiltering - - // setTimeout is used to prevent injectClassIdStylesheet from calling - // another Redux function immediately - setTimeout(() => injectClassIdStylesheet(action.tabId, action.classes, action.ids, exceptions, hide1pContent), 0) - break - } - case shieldsPanelTypes.COSMETIC_FILTER_RULE_EXCEPTIONS: { - const tabData = state.tabs[action.tabId] - if (!tabData) { - console.error('Active tab not found') - break - } - let message: { type: string, scriptlet: string, hideOptions?: { hide1pContent: boolean, generichide: boolean } } = { - type: 'cosmeticFilteringBackgroundReady', - scriptlet: action.scriptlet, - hideOptions: undefined - } - if (action.frameId === 0) { - // Non-scriptlet cosmetic filters are only applied on the top-level frame - state = shieldsPanelState.saveCosmeticFilterRuleExceptions(state, action.tabId, action.exceptions) - message.hideOptions = { - hide1pContent: tabData.firstPartyCosmeticFiltering, - generichide: action.generichide - } - } - chrome.tabs.sendMessage(action.tabId, message, { - frameId: action.frameId - }) - break - } - case shieldsPanelTypes.CONTENT_SCRIPTS_LOADED: { - const tabData = state.tabs[action.tabId] - if (!tabData) { - console.error('Active tab not found') - break - } - Promise.all([chrome.braveShields.shouldDoCosmeticFilteringAsync(action.url), chrome.braveShields.isFirstPartyCosmeticFilteringEnabledAsync(action.url)]) - .then(([doCosmeticBlocking, hide1pContent]: [boolean, boolean]) => { - if (doCosmeticBlocking) { - applyAdblockCosmeticFilters(action.tabId, action.frameId, action.url, hide1pContent) - } - }) - .catch(() => { - console.error('Could not apply cosmetic blocking') - }) - break - } } if (!areObjectsEqual(state.persistentData, initialPersistentData)) { diff --git a/components/brave_extension/extension/brave_extension/constants/shieldsPanelTypes.ts b/components/brave_extension/extension/brave_extension/constants/shieldsPanelTypes.ts index faea8d578819..e755eeb5df01 100644 --- a/components/brave_extension/extension/brave_extension/constants/shieldsPanelTypes.ts +++ b/components/brave_extension/extension/brave_extension/constants/shieldsPanelTypes.ts @@ -21,5 +21,4 @@ export const SET_ADVANCED_VIEW_FIRST_ACCESS = 'SET_ADVANCED_VIEW_FIRST_ACCESS' export const TOGGLE_ADVANCED_VIEW = 'TOGGLE_ADVANCED_VIEW' export const SHIELDS_READY = 'SHIELDS_READY' export const GENERATE_CLASS_ID_STYLESHEET = 'GENERATE_CLASS_ID_STYLESHEET' -export const COSMETIC_FILTER_RULE_EXCEPTIONS = 'COSMETIC_FILTER_RULE_EXCEPTIONS' export const CONTENT_SCRIPTS_LOADED = 'CONTENT_SCRIPTS_LOADED' diff --git a/components/brave_extension/extension/brave_extension/manifest.json b/components/brave_extension/extension/brave_extension/manifest.json index c4ef7a09e57f..b8f6bfedc61c 100644 --- a/components/brave_extension/extension/brave_extension/manifest.json +++ b/components/brave_extension/extension/brave_extension/manifest.json @@ -31,17 +31,6 @@ ] }, "content_scripts": [ - { - "matches": [ - "http://*/*", - "https://*/*" - ], - "js": [ - "out/content_cosmetic.bundle.js" - ], - "run_at": "document_start", - "all_frames": true - }, { "matches": [ "http://*/*", diff --git a/components/brave_extension/extension/brave_extension/types/actions/shieldsPanelActions.ts b/components/brave_extension/extension/brave_extension/types/actions/shieldsPanelActions.ts index 39c6a8c4c87b..3ca1a73aa7de 100644 --- a/components/brave_extension/extension/brave_extension/types/actions/shieldsPanelActions.ts +++ b/components/brave_extension/extension/brave_extension/types/actions/shieldsPanelActions.ts @@ -184,19 +184,6 @@ export interface GenerateClassIdStylesheet { (tabId: number, classes: string[], ids: string[]): GenerateClassIdStylesheetReturn } -interface CosmeticFilterRuleExceptionsReturn { - type: types.COSMETIC_FILTER_RULE_EXCEPTIONS, - tabId: number, - frameId: number, - exceptions: string[], - scriptlet: string, - generichide: boolean -} - -export interface CosmeticFilterRuleExceptions { - (tabId: number, frameId: number, exceptions: string[], scriptlet: string, generichide: boolean): CosmeticFilterRuleExceptionsReturn -} - interface ContentScriptsLoadedReturn { type: types.CONTENT_SCRIPTS_LOADED, tabId: number, @@ -227,5 +214,4 @@ export type shieldPanelActions = SetAdvancedViewFirstAccessReturn | ShieldsReadyReturn | GenerateClassIdStylesheetReturn | - CosmeticFilterRuleExceptionsReturn | ContentScriptsLoadedReturn diff --git a/components/brave_extension/extension/brave_extension/types/constants/shieldsPanelTypes.ts b/components/brave_extension/extension/brave_extension/types/constants/shieldsPanelTypes.ts index 05c2568a3cbb..b5b46459a757 100644 --- a/components/brave_extension/extension/brave_extension/types/constants/shieldsPanelTypes.ts +++ b/components/brave_extension/extension/brave_extension/types/constants/shieldsPanelTypes.ts @@ -23,5 +23,4 @@ export type SET_ADVANCED_VIEW_FIRST_ACCESS = typeof types.SET_ADVANCED_VIEW_FIRS export type TOGGLE_ADVANCED_VIEW = typeof types.TOGGLE_ADVANCED_VIEW export type SHIELDS_READY = typeof types.SHIELDS_READY export type GENERATE_CLASS_ID_STYLESHEET = typeof types.GENERATE_CLASS_ID_STYLESHEET -export type COSMETIC_FILTER_RULE_EXCEPTIONS = typeof types.COSMETIC_FILTER_RULE_EXCEPTIONS export type CONTENT_SCRIPTS_LOADED = typeof types.CONTENT_SCRIPTS_LOADED diff --git a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc index 294cf56c4b8c..12a1219f1310 100644 --- a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc +++ b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc @@ -71,7 +71,7 @@ void CosmeticFiltersJSHandler::EnsureConnected() { if (!cs_communicator_) { render_frame_->GetBrowserInterfaceBroker()->GetInterface( cs_communicator_.BindNewPipeAndPassReceiver()); - } + } } v8::Local GetOrCreateWorkerObject( diff --git a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h index 62e7aabf0818..e1fa2c5fee66 100644 --- a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h +++ b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h @@ -6,6 +6,8 @@ #ifndef BRAVE_COMPONENTS_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_HANDLER_H_ #define BRAVE_COMPONENTS_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_HANDLER_H_ +#include + #include "brave/content/browser/mojom/cosmetic_filters_communication.mojom.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame_observer.h" diff --git a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h index c550ab1a9092..4fa093706b40 100644 --- a/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h +++ b/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h @@ -6,6 +6,8 @@ #ifndef BRAVE_COMPONENTS_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_RENDER_FRAME_OBSERVER_H_ #define BRAVE_COMPONENTS_COSMETIC_FILTERS_CONTENT_RENDERER_COSMETIC_FILTERS_JS_RENDER_FRAME_OBSERVER_H_ +#include + #include "base/memory/weak_ptr.h" #include "brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h" #include "content/public/renderer/render_frame.h" @@ -16,7 +18,8 @@ namespace cosmetic_filters_worker { // CosmeticFiltersJsRenderFrame observer waits for a page to be loaded and then // adds the Javascript worker object. -class CosmeticFiltersJsRenderFrameObserver : public content::RenderFrameObserver { +class CosmeticFiltersJsRenderFrameObserver : + public content::RenderFrameObserver { public: CosmeticFiltersJsRenderFrameObserver(content::RenderFrame* render_frame, const int32_t isolated_world_id); diff --git a/content/browser/cosmetic_filters_communication_impl.cc b/content/browser/cosmetic_filters_communication_impl.cc index 08c616ac6b66..90b1673831d7 100644 --- a/content/browser/cosmetic_filters_communication_impl.cc +++ b/content/browser/cosmetic_filters_communication_impl.cc @@ -43,15 +43,15 @@ void CosmeticFiltersCommunicationImpl::SetObserver( } void CosmeticFiltersCommunicationImpl::HiddenClassIdSelectors( - const std::string& input) { + const std::string& input) { base::Optional input_value = base::JSONReader::Read(input); if (!input_value || !input_value->is_dict()) { - // Nothing to work with - return; + // Nothing to work with + return; } base::DictionaryValue* input_dict; if (!input_value->GetAsDictionary(&input_dict)) { - return; + return; } std::vector classes; base::ListValue* classes_list; diff --git a/content/browser/cosmetic_filters_communication_impl.h b/content/browser/cosmetic_filters_communication_impl.h index c070775b4794..9cb20c38a002 100644 --- a/content/browser/cosmetic_filters_communication_impl.h +++ b/content/browser/cosmetic_filters_communication_impl.h @@ -3,8 +3,8 @@ * License, v. 3.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_CONTENT_BROWSER_COSMETIC_COMMUNICATION_IMPL_H_ -#define BRAVE_CONTENT_BROWSER_COSMETIC_COMMUNICATION_IMPL_H_ +#ifndef BRAVE_CONTENT_BROWSER_COSMETIC_FILTERS_COMMUNICATION_IMPL_H_ +#define BRAVE_CONTENT_BROWSER_COSMETIC_FILTERS_COMMUNICATION_IMPL_H_ #include #include @@ -20,26 +20,26 @@ class RenderFrameHost; class CosmeticFiltersObserver; class CosmeticFiltersCommunicationImpl final - : public cf_comm::mojom::CosmeticFiltersCommunication { + : public cf_comm::mojom::CosmeticFiltersCommunication { public: static void CreateInstance(content::RenderFrameHost* render_frame_host, CosmeticFiltersObserver* cosmetic_filters_observer); CosmeticFiltersCommunicationImpl( - content::RenderFrameHost* render_frame_host, - CosmeticFiltersObserver* cosmetic_filters_observer); + content::RenderFrameHost* render_frame_host, + CosmeticFiltersObserver* cosmetic_filters_observer); ~CosmeticFiltersCommunicationImpl() override; - // cf_comm::mojom::CosmeticFiltersCommunication - void HiddenClassIdSelectors(const std::string& input) override; + // cf_comm::mojom::CosmeticFiltersCommunication + void HiddenClassIdSelectors(const std::string& input) override; - void SetObserver(CosmeticFiltersObserver* cosmetic_filters_observer); + void SetObserver(CosmeticFiltersObserver* cosmetic_filters_observer); private: - content::RenderFrameHost* render_frame_host_; - CosmeticFiltersObserver* cosmetic_filters_observer_; + content::RenderFrameHost* render_frame_host_; + CosmeticFiltersObserver* cosmetic_filters_observer_; }; } // namespace content -#endif // BRAVE_CONTENT_BROWSER_COSMETIC_COMMUNICATION_IMPL_H_ +#endif // BRAVE_CONTENT_BROWSER_COSMETIC_FILTERS_COMMUNICATION_IMPL_H_ diff --git a/content/browser/cosmetic_filters_observer.h b/content/browser/cosmetic_filters_observer.h index 45a789b43327..a553ec58141e 100644 --- a/content/browser/cosmetic_filters_observer.h +++ b/content/browser/cosmetic_filters_observer.h @@ -6,6 +6,7 @@ #ifndef BRAVE_CONTENT_BROWSER_COSMETIC_FILTERS_OBSERVER_H_ #define BRAVE_CONTENT_BROWSER_COSMETIC_FILTERS_OBSERVER_H_ +#include #include namespace content { @@ -14,10 +15,10 @@ class RenderFrameHost; class CosmeticFiltersObserver { public: - CosmeticFiltersObserver() {} - ~CosmeticFiltersObserver() {} + CosmeticFiltersObserver() {} + ~CosmeticFiltersObserver() {} - virtual void HiddenClassIdSelectors(RenderFrameHost* render_frame_host, + virtual void HiddenClassIdSelectors(RenderFrameHost* render_frame_host, const std::vector& classes, const std::vector& ids) {} }; diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index ff0782b23226..c22f6b03f7fb 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn @@ -1,20 +1,13 @@ source_set("browser") { sources = [ + "//brave/content/browser/cosmetic_filters_communication_impl.cc", + "//brave/content/browser/cosmetic_filters_communication_impl.h", + "//brave/content/browser/cosmetic_filters_observer.h", "//brave/content/public/browser/brave_render_frame_host.cc", ] deps = [ "//base", + "//brave/content/browser/mojom", "//skia", ] - if (is_android) { - sources += [ - "//brave/content/browser/cosmetic_filters_communication_impl.cc", - "//brave/content/browser/cosmetic_filters_communication_impl.h", - "//brave/content/browser/cosmetic_filters_observer.h", - ] - - deps += [ - "//brave/content/browser/mojom", - ] - } -} \ No newline at end of file +} diff --git a/content/public/browser/brave_render_frame_host.cc b/content/public/browser/brave_render_frame_host.cc index 79374acd4f9a..6e3d9297f410 100644 --- a/content/public/browser/brave_render_frame_host.cc +++ b/content/public/browser/brave_render_frame_host.cc @@ -5,16 +5,12 @@ #include "content/public/browser/render_frame_host.h" -#if defined(OS_ANDROID) #include "brave/content/browser/cosmetic_filters_communication_impl.h" -#endif namespace content { RenderFrameHost::RenderFrameHost() { -#if defined(OS_ANDROID) cosmetic_filters_communication_impl_ = nullptr; -#endif } RenderFrameHost::~RenderFrameHost() {} diff --git a/renderer/BUILD.gn b/renderer/BUILD.gn index 969d2771dd91..93b79f68c7fd 100644 --- a/renderer/BUILD.gn +++ b/renderer/BUILD.gn @@ -12,10 +12,8 @@ source_set("renderer") { "//chrome/renderer", ] - if (is_android) { - deps = [ - "//chrome/common", - "//brave/components/cosmetic_filters/content/renderer", - ] - } + deps = [ + "//chrome/common", + "//brave/components/cosmetic_filters/content/renderer", + ] } diff --git a/renderer/brave_content_renderer_client.cc b/renderer/brave_content_renderer_client.cc index 4dfe92895449..ea5c0ffc47c2 100644 --- a/renderer/brave_content_renderer_client.cc +++ b/renderer/brave_content_renderer_client.cc @@ -5,10 +5,8 @@ #include "brave/renderer/brave_content_renderer_client.h" -#if defined(OS_ANDROID) #include "brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h" #include "chrome/common/chrome_isolated_world_ids.h" -#endif #include "third_party/blink/public/platform/web_runtime_features.h" BraveContentRendererClient::BraveContentRendererClient() @@ -23,12 +21,10 @@ SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() { } BraveContentRendererClient::~BraveContentRendererClient() = default; -#if defined(OS_ANDROID) void BraveContentRendererClient::RenderFrameCreated( - content::RenderFrame* render_frame) { + content::RenderFrame* render_frame) { ChromeContentRendererClient::RenderFrameCreated(render_frame); new cosmetic_filters_worker::CosmeticFiltersJsRenderFrameObserver( render_frame, ISOLATED_WORLD_ID_CHROME_INTERNAL); } -#endif diff --git a/renderer/brave_content_renderer_client.h b/renderer/brave_content_renderer_client.h index 6f76e2c42744..2b90ef85fb73 100644 --- a/renderer/brave_content_renderer_client.h +++ b/renderer/brave_content_renderer_client.h @@ -1,4 +1,5 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright (c) 2019 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/. */ @@ -12,9 +13,7 @@ class BraveContentRendererClient : public ChromeContentRendererClient { BraveContentRendererClient(); ~BraveContentRendererClient() override; void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override; -#if defined(OS_ANDROID) void RenderFrameCreated(content::RenderFrame* render_frame) override; -#endif private: DISALLOW_COPY_AND_ASSIGN(BraveContentRendererClient); diff --git a/renderer/sources.gni b/renderer/sources.gni index 8a4a61b0b613..3fb8c38463f1 100644 --- a/renderer/sources.gni +++ b/renderer/sources.gni @@ -4,6 +4,10 @@ # You can obtain one at http://mozilla.org/MPL/2.0/. brave_chrome_renderer_sources = [ + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.cc", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc", + "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h", "//brave/renderer/brave_content_renderer_client.cc", "//brave/renderer/brave_content_renderer_client.h", ] @@ -11,22 +15,10 @@ brave_chrome_renderer_sources = [ brave_chrome_renderer_public_deps = [ "//base", "//brave/components/content_settings/renderer", + "//content/public/renderer", + "//gin", + "//mojo/public/cpp/bindings", "//third_party/blink/public:blink", + "//third_party/blink/public/common", + "//v8", ] - -if (is_android) { - brave_chrome_renderer_sources += [ - "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.cc", - "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_render_frame_observer.h", - "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.cc", - "//brave/components/cosmetic_filters/content/renderer/cosmetic_filters_js_handler.h", - ] - - brave_chrome_renderer_public_deps += [ - "//content/public/renderer", - "//gin", - "//mojo/public/cpp/bindings", - "//third_party/blink/public/common", - "//v8", - ] -} From b507e89247ac08d6b51a13cafe8a172f6ea7a434 Mon Sep 17 00:00:00 2001 From: Serg Date: Fri, 20 Nov 2020 16:41:19 -0500 Subject: [PATCH 07/45] adds fetching script from resources --- brave_paks.gni | 2 + browser/BUILD.gn | 1 + .../brave_cosmetic_resources_tab_helper.cc | 145 +++++------------- browser/brave_cosmetic_resources_tab_helper.h | 2 +- browser/resources/resource_ids | 3 + .../cosmetic_filters/resources/BUILD.gn | 12 ++ .../resources/cosmetic_filters_resources.grd | 14 ++ .../cosmetic_filters/resources/data/BUILD.gn | 15 ++ .../resources/data/cosmetic_filters.js | 100 ++++++++++++ .../data/cosmetic_filters_resources.grd | 14 ++ 10 files changed, 198 insertions(+), 110 deletions(-) create mode 100644 components/cosmetic_filters/resources/BUILD.gn create mode 100644 components/cosmetic_filters/resources/cosmetic_filters_resources.grd create mode 100644 components/cosmetic_filters/resources/data/BUILD.gn create mode 100644 components/cosmetic_filters/resources/data/cosmetic_filters.js create mode 100644 components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd diff --git a/brave_paks.gni b/brave_paks.gni index b0870eb69743..1be9e77b2776 100644 --- a/brave_paks.gni +++ b/brave_paks.gni @@ -59,6 +59,7 @@ template("brave_extra_paks") { output = "${invoker.output_dir}/brave_resources.pak" sources = [ "$root_gen_dir/components/brave_components_resources.pak", + "$root_gen_dir/brave/components/cosmetic_filters/resources/cosmetic_filters_resources.pak", "$root_gen_dir/brave/ui/webui/resources/brave_webui_resources.pak", ] @@ -72,6 +73,7 @@ template("brave_extra_paks") { deps = [ "//brave/components/resources", + "//brave/components/cosmetic_filters/resources", "//brave/ui/webui/resources", ] diff --git a/browser/BUILD.gn b/browser/BUILD.gn index dfb796246bfc..0f1a78276cbc 100644 --- a/browser/BUILD.gn +++ b/browser/BUILD.gn @@ -140,6 +140,7 @@ source_set("browser_process") { "//brave/components/brave_wayback_machine:buildflags", "//brave/components/brave_webtorrent/browser/buildflags", "//brave/components/content_settings/core/browser", + "//brave/components/cosmetic_filters/resources", "//brave/components/crypto_dot_com/browser/buildflags", "//brave/components/gemini/browser/buildflags", "//brave/components/greaselion/browser/buildflags", diff --git a/browser/brave_cosmetic_resources_tab_helper.cc b/browser/brave_cosmetic_resources_tab_helper.cc index 04a357d08642..cd9366237b37 100644 --- a/browser/brave_cosmetic_resources_tab_helper.cc +++ b/browser/brave_cosmetic_resources_tab_helper.cc @@ -23,114 +23,18 @@ #include "content/public/browser/global_routing_id.h" #include "content/public/browser/navigation_handle.h" #include "content/public/renderer/render_frame.h" +#include "components/cosmetic_filters/resources/grit/cosmetic_filters_resources.h" +#include "ui/base/resource/resource_bundle.h" +// Doing that to prevent lint error: +// Static/global string variables are not permitted +// You can create an object dynamically and never delete it by using a +// Function-local static pointer or reference +// (e.g., static const auto& impl = *new T(args...);). +std::string* BraveCosmeticResourcesTabHelper::observing_script_ = + new std::string(""); namespace { -const char k_observing_script[] = - "(function() {" - "const queriedIds = new Set();" - "const queriedClasses = new Set();" - "var notYetQueriedClasses;" - "var notYetQueriedIds;" - "var cosmeticObserver;" - "if (window.cosmeticStyleSheet === undefined) {" - "window.cosmeticStyleSheet = new CSSStyleSheet();}" - "const fetchNewClassIdRules = function () {" - "if ((!notYetQueriedClasses || notYetQueriedClasses.length === 0) &&" - "(!notYetQueriedIds || notYetQueriedIds.length === 0)) {" - "return;" - "};" - "cf_worker.hiddenClassIdSelectors(" - "JSON.stringify({classes: notYetQueriedClasses, ids: notYetQueriedIds}));" - "/*chrome.runtime.sendMessage({" - "type: 'hiddenClassIdSelectors'," - "classes: notYetQueriedClasses || []," - "ids: notYetQueriedIds || []" - "})*/" - "notYetQueriedClasses = [];" - "notYetQueriedIds = [];" -"};" - -"function isElement (node) {" - "return (node.nodeType === 1);" -"};" - -"function asElement (node) {" - "return isElement(node) ? node : null;" -"};" - -"const handleMutations = MutationCallback = function (mutations) {" - "for (const aMutation of mutations) {" - "if (aMutation.type === 'attributes') {" - "const changedElm = aMutation.target;" - "switch (aMutation.attributeName) {" - "case 'class':" - "for (const aClassName of changedElm.classList.values()) {" - "if (queriedClasses.has(aClassName) === false) {" - "notYetQueriedClasses.push(aClassName);" - "queriedClasses.add(aClassName);" - "};" - "};" - "break;" - "case 'id':" - "const mutatedId = changedElm.id;" - "if (queriedIds.has(mutatedId) === false) {" - "notYetQueriedIds.push(mutatedId);" - "queriedIds.add(mutatedId);" - "};" - "break;" - "};" - "} else if (aMutation.addedNodes.length > 0) {" - "for (const node of aMutation.addedNodes) {" - "const element = asElement(node);" - "if (!element) {" - "continue;" - "};" - "const id = element.id;" - "if (id && !queriedIds.has(id)) {" - "notYetQueriedIds.push(id);" - "queriedIds.add(id);" - "};" - "const classList = element.classList;" - "if (classList) {" - "for (const className of classList.values()) {" - "if (className && !queriedClasses.has(className)) {" - "notYetQueriedClasses.push(className);" - "queriedClasses.add(className);" - "};" - "};" - "};" - "};" - "};" - "};" - "fetchNewClassIdRules();" -"};" - - "const startObserving = () => {" - " const elmWithClassOrId = document.querySelectorAll('[class],[id]');" - " for (const elm of elmWithClassOrId) {" - " for (const aClassName of elm.classList.values()) {" - " queriedClasses.add(aClassName);" - " /*console.log('!!!aClassName == ' + aClassName);*/" - "}" - " const elmId = elm.getAttribute('id');" - " if (elmId) {" - " queriedIds.add(elmId);" - " }" - "};" - "notYetQueriedClasses = Array.from(queriedClasses);" - "notYetQueriedIds = Array.from(queriedIds);" - "fetchNewClassIdRules();" - "cosmeticObserver = new MutationObserver(handleMutations);" - "let observerConfig = {" - "subtree: true," - "childList: true," - "attributeFilter: ['id', 'class']" - "};" - "cosmeticObserver.observe(document.documentElement, observerConfig);" - "};" - "startObserving();" - "})();"; bool ShouldDoCosmeticFiltering(content::WebContents* contents, const GURL& url) { @@ -139,6 +43,20 @@ bool ShouldDoCosmeticFiltering(content::WebContents* contents, return ::brave_shields::ShouldDoCosmeticFiltering(map, url); } + +std::string LoadDataResource(const int& id) { + std::string data_resource; + + auto& resource_bundle = ui::ResourceBundle::GetSharedInstance(); + if (resource_bundle.IsGzipped(id)) { + data_resource = resource_bundle.LoadDataResourceString(id); + } else { + data_resource = resource_bundle.GetRawDataResource(id).as_string(); + } + + return data_resource; +} + } // namespace @@ -146,6 +64,10 @@ BraveCosmeticResourcesTabHelper::BraveCosmeticResourcesTabHelper( content::WebContents* contents) : WebContentsObserver(contents), enabled_1st_party_cf_filtering_(false) { + if (BraveCosmeticResourcesTabHelper::observing_script_->empty()) { + *BraveCosmeticResourcesTabHelper::observing_script_ = + LoadDataResource(IDR_COSMETIC_FILTERS_SCRIPT); + } } BraveCosmeticResourcesTabHelper::~BraveCosmeticResourcesTabHelper() { @@ -355,7 +277,7 @@ std::unique_ptr } void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( - content::RenderFrameHost* render_frame_host, + content::GlobalFrameRoutingId frame_id, std::unique_ptr selectors) { if (!selectors) { return; @@ -391,7 +313,10 @@ void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( "document.adoptedStyleSheets = [window.cosmeticStyleSheet];" "};"; cosmeticFilterConsiderNewSelectors_script += "})();"; - render_frame_host->ExecuteJavaScriptInIsolatedWorld( + auto* frame_host = content::RenderFrameHost::FromID(frame_id); + if (!frame_host) + return; + frame_host->ExecuteJavaScriptInIsolatedWorld( base::UTF8ToUTF16(cosmeticFilterConsiderNewSelectors_script), base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); } @@ -422,7 +347,7 @@ void BraveCosmeticResourcesTabHelper::ProcessURL( // Non-scriptlet cosmetic filters are only applied on the top-level frame if (web_contents()->GetMainFrame()) { web_contents()->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld( - base::UTF8ToUTF16(k_observing_script), + base::UTF8ToUTF16(*BraveCosmeticResourcesTabHelper::observing_script_), base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); } } @@ -462,7 +387,9 @@ void BraveCosmeticResourcesTabHelper::HiddenClassIdSelectors( classes, ids), base::BindOnce(&BraveCosmeticResourcesTabHelper:: GetHiddenClassIdSelectorsOnUI, base::Unretained(this), - render_frame_host)); + content::GlobalFrameRoutingId( + render_frame_host->GetProcess()->GetID(), + render_frame_host->GetRoutingID()))); } WEB_CONTENTS_USER_DATA_KEY_IMPL(BraveCosmeticResourcesTabHelper) diff --git a/browser/brave_cosmetic_resources_tab_helper.h b/browser/brave_cosmetic_resources_tab_helper.h index 6b9fa1880a8b..0e083bf851c3 100644 --- a/browser/brave_cosmetic_resources_tab_helper.h +++ b/browser/brave_cosmetic_resources_tab_helper.h @@ -63,7 +63,7 @@ class BraveCosmeticResourcesTabHelper const std::vector& classes, const std::vector& ids); void GetHiddenClassIdSelectorsOnUI( - content::RenderFrameHost* render_frame_host, + content::GlobalFrameRoutingId frame_id, std::unique_ptr selectors); std::vector exceptions_; diff --git a/browser/resources/resource_ids b/browser/resources/resource_ids index 580fd3ac51ec..73222c9234bd 100644 --- a/browser/resources/resource_ids +++ b/browser/resources/resource_ids @@ -100,4 +100,7 @@ "<(ROOT_GEN_DIR)/brave/web-ui-ipfs/ipfs.grd": { "includes": [45500], }, + "brave/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd": { + "includes": [46000] + }, } diff --git a/components/cosmetic_filters/resources/BUILD.gn b/components/cosmetic_filters/resources/BUILD.gn new file mode 100644 index 000000000000..fab2614d9b14 --- /dev/null +++ b/components/cosmetic_filters/resources/BUILD.gn @@ -0,0 +1,12 @@ +import("//tools/grit/repack.gni") + +repack("resources") { + output = "$root_gen_dir/brave/components/cosmetic_filters/resources/cosmetic_filters_resources.pak" + sources = [ + "$root_gen_dir/components/cosmetic_filters/resources/cosmetic_filters_resources.pak", + ] + + deps = [ + "data:resources_cf", + ] +} diff --git a/components/cosmetic_filters/resources/cosmetic_filters_resources.grd b/components/cosmetic_filters/resources/cosmetic_filters_resources.grd new file mode 100644 index 000000000000..236413c4eb04 --- /dev/null +++ b/components/cosmetic_filters/resources/cosmetic_filters_resources.grd @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/components/cosmetic_filters/resources/data/BUILD.gn b/components/cosmetic_filters/resources/data/BUILD.gn new file mode 100644 index 000000000000..467fb3b6ad61 --- /dev/null +++ b/components/cosmetic_filters/resources/data/BUILD.gn @@ -0,0 +1,15 @@ +import("//tools/grit/grit_rule.gni") +import("//tools/grit/repack.gni") + +grit("resources_cf") { + source = "cosmetic_filters_resources.grd" + + outputs = [ + "grit/cosmetic_filters_resources.h", + "cosmetic_filters_resources.pak", + ] + + resource_ids = "//brave/browser/resources/resource_ids" + + output_dir = "$root_gen_dir/components/cosmetic_filters/resources" +} diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters.js b/components/cosmetic_filters/resources/data/cosmetic_filters.js new file mode 100644 index 000000000000..bc7d719c8cfd --- /dev/null +++ b/components/cosmetic_filters/resources/data/cosmetic_filters.js @@ -0,0 +1,100 @@ +(function() { + const queriedIds = new Set(); + const queriedClasses = new Set(); + var notYetQueriedClasses; + var notYetQueriedIds; + var cosmeticObserver; + if (window.cosmeticStyleSheet === undefined) { + window.cosmeticStyleSheet = new CSSStyleSheet(); + } + const fetchNewClassIdRules = function () { + if ((!notYetQueriedClasses || notYetQueriedClasses.length === 0) && + (!notYetQueriedIds || notYetQueriedIds.length === 0)) { + return; + }; + // Callback to c++ renderer process + cf_worker.hiddenClassIdSelectors( + JSON.stringify({classes: notYetQueriedClasses, ids: notYetQueriedIds})); + notYetQueriedClasses = []; + notYetQueriedIds = []; + }; + + function isElement (node) { + return (node.nodeType === 1); + }; + + function asElement (node) { + return isElement(node) ? node : null; + }; + + const handleMutations = MutationCallback = function (mutations) { + for (const aMutation of mutations) { + if (aMutation.type === 'attributes') { + const changedElm = aMutation.target; + switch (aMutation.attributeName) { + case 'class': + for (const aClassName of changedElm.classList.values()) { + if (queriedClasses.has(aClassName) === false) { + notYetQueriedClasses.push(aClassName); + queriedClasses.add(aClassName); + }; + }; + break; + case 'id': + const mutatedId = changedElm.id; + if (queriedIds.has(mutatedId) === false) { + notYetQueriedIds.push(mutatedId); + queriedIds.add(mutatedId); + }; + break; + }; + } else if (aMutation.addedNodes.length > 0) { + for (const node of aMutation.addedNodes) { + const element = asElement(node); + if (!element) { + continue; + }; + const id = element.id; + if (id && !queriedIds.has(id)) { + notYetQueriedIds.push(id); + queriedIds.add(id); + }; + const classList = element.classList; + if (classList) { + for (const className of classList.values()) { + if (className && !queriedClasses.has(className)) { + notYetQueriedClasses.push(className); + queriedClasses.add(className); + }; + }; + }; + }; + }; + }; + fetchNewClassIdRules(); + }; + + const startObserving = () => { + const elmWithClassOrId = document.querySelectorAll('[class],[id]'); + for (const elm of elmWithClassOrId) { + for (const aClassName of elm.classList.values()) { + queriedClasses.add(aClassName); + } + const elmId = elm.getAttribute('id'); + if (elmId) { + queriedIds.add(elmId); + } + }; + notYetQueriedClasses = Array.from(queriedClasses); + notYetQueriedIds = Array.from(queriedIds); + fetchNewClassIdRules(); + cosmeticObserver = new MutationObserver(handleMutations); + let observerConfig = { + subtree: true, + childList: true, + attributeFilter: ['id', 'class'] + }; + cosmeticObserver.observe(document.documentElement, observerConfig); + }; + startObserving(); +})(); diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd b/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd new file mode 100644 index 000000000000..473de21b4176 --- /dev/null +++ b/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + From eead6317c5bb3ada19868facdb98cb5e3184b158 Mon Sep 17 00:00:00 2001 From: Serg Date: Tue, 24 Nov 2020 15:48:23 -0500 Subject: [PATCH 08/45] replaces Unretained to WeakPtr --- .../brave_cosmetic_resources_tab_helper.cc | 136 ++++++++---------- browser/brave_cosmetic_resources_tab_helper.h | 8 -- content/BUILD.gn | 1 + 3 files changed, 62 insertions(+), 83 deletions(-) diff --git a/browser/brave_cosmetic_resources_tab_helper.cc b/browser/brave_cosmetic_resources_tab_helper.cc index cd9366237b37..963ec290209f 100644 --- a/browser/brave_cosmetic_resources_tab_helper.cc +++ b/browser/brave_cosmetic_resources_tab_helper.cc @@ -57,25 +57,8 @@ std::string LoadDataResource(const int& id) { return data_resource; } -} // namespace - - -BraveCosmeticResourcesTabHelper::BraveCosmeticResourcesTabHelper( - content::WebContents* contents) - : WebContentsObserver(contents), - enabled_1st_party_cf_filtering_(false) { - if (BraveCosmeticResourcesTabHelper::observing_script_->empty()) { - *BraveCosmeticResourcesTabHelper::observing_script_ = - LoadDataResource(IDR_COSMETIC_FILTERS_SCRIPT); - } -} - -BraveCosmeticResourcesTabHelper::~BraveCosmeticResourcesTabHelper() { -} - -std::unique_ptr - BraveCosmeticResourcesTabHelper::GetUrlCosmeticResourcesOnTaskRunner( - const std::string& url) { +std::unique_ptr GetUrlCosmeticResourcesOnTaskRunner( + const std::string& url) { auto result_list = std::make_unique(); base::Optional resources = g_brave_browser_process-> @@ -106,6 +89,59 @@ std::unique_ptr return result_list; } +std::unique_ptr GetHiddenClassIdSelectorsOnTaskRunner( + const std::vector& classes, + const std::vector& ids, + const std::vector& exceptions) { + base::Optional hide_selectors = g_brave_browser_process-> + ad_block_service()->HiddenClassIdSelectors(classes, ids, exceptions); + + base::Optional regional_selectors = g_brave_browser_process-> + ad_block_regional_service_manager()-> + HiddenClassIdSelectors(classes, ids, exceptions); + + base::Optional custom_selectors = g_brave_browser_process-> + ad_block_custom_filters_service()-> + HiddenClassIdSelectors(classes, ids, exceptions); + + if (hide_selectors && hide_selectors->is_list()) { + if (regional_selectors && regional_selectors->is_list()) { + for (auto i = regional_selectors->GetList().begin(); + i < regional_selectors->GetList().end(); i++) { + hide_selectors->Append(std::move(*i)); + } + } + } else { + hide_selectors = std::move(regional_selectors); + } + + auto result_list = std::make_unique(); + if (hide_selectors && hide_selectors->is_list()) { + result_list->Append(std::move(*hide_selectors)); + } + if (custom_selectors && custom_selectors->is_list()) { + result_list->Append(std::move(*custom_selectors)); + } + + return result_list; +} + +} // namespace + + +BraveCosmeticResourcesTabHelper::BraveCosmeticResourcesTabHelper( + content::WebContents* contents) + : WebContentsObserver(contents), + enabled_1st_party_cf_filtering_(false) { + if (BraveCosmeticResourcesTabHelper::observing_script_->empty()) { + *BraveCosmeticResourcesTabHelper::observing_script_ = + LoadDataResource(IDR_COSMETIC_FILTERS_SCRIPT); + } +} + +BraveCosmeticResourcesTabHelper::~BraveCosmeticResourcesTabHelper() { +} + void BraveCosmeticResourcesTabHelper::GetUrlCosmeticResourcesOnUI( content::GlobalFrameRoutingId frame_id, const std::string& url, bool main_frame, std::unique_ptr resources) { @@ -239,43 +275,6 @@ void BraveCosmeticResourcesTabHelper::CSSRulesRoutine( // } -std::unique_ptr - BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnTaskRunner( - const std::vector& classes, - const std::vector& ids) { - base::Optional hide_selectors = g_brave_browser_process-> - ad_block_service()->HiddenClassIdSelectors(classes, ids, exceptions_); - - base::Optional regional_selectors = g_brave_browser_process-> - ad_block_regional_service_manager()-> - HiddenClassIdSelectors(classes, ids, exceptions_); - - base::Optional custom_selectors = g_brave_browser_process-> - ad_block_custom_filters_service()-> - HiddenClassIdSelectors(classes, ids, exceptions_); - - if (hide_selectors && hide_selectors->is_list()) { - if (regional_selectors && regional_selectors->is_list()) { - for (auto i = regional_selectors->GetList().begin(); - i < regional_selectors->GetList().end(); i++) { - hide_selectors->Append(std::move(*i)); - } - } - } else { - hide_selectors = std::move(regional_selectors); - } - - auto result_list = std::make_unique(); - if (hide_selectors && hide_selectors->is_list()) { - result_list->Append(std::move(*hide_selectors)); - } - if (custom_selectors && custom_selectors->is_list()) { - result_list->Append(std::move(*custom_selectors)); - } - - return result_list; -} - void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( content::GlobalFrameRoutingId frame_id, std::unique_ptr selectors) { @@ -333,11 +332,10 @@ void BraveCosmeticResourcesTabHelper::ProcessURL( } g_brave_browser_process->ad_block_service()->GetTaskRunner()-> PostTaskAndReplyWithResult(FROM_HERE, - base::BindOnce(&BraveCosmeticResourcesTabHelper:: - GetUrlCosmeticResourcesOnTaskRunner, base::Unretained(this), + base::BindOnce(GetUrlCosmeticResourcesOnTaskRunner, url.spec()), base::BindOnce(&BraveCosmeticResourcesTabHelper:: - GetUrlCosmeticResourcesOnUI, base::Unretained(this), + GetUrlCosmeticResourcesOnUI, AsWeakPtr(), content::GlobalFrameRoutingId( render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID()), @@ -365,29 +363,17 @@ void BraveCosmeticResourcesTabHelper::ResourceLoadComplete( ProcessURL(render_frame_host, resource_load_info.final_url, false); } -bool BraveCosmeticResourcesTabHelper::OnMessageReceived( - const IPC::Message& message, - content::RenderFrameHost* render_frame_host) { - return false; -} - -bool BraveCosmeticResourcesTabHelper::OnMessageReceived( - const IPC::Message& message) { - return false; -} - void BraveCosmeticResourcesTabHelper::HiddenClassIdSelectors( content::RenderFrameHost* render_frame_host, const std::vector& classes, const std::vector& ids) { g_brave_browser_process->ad_block_service()->GetTaskRunner()-> PostTaskAndReplyWithResult(FROM_HERE, + base::BindOnce(&GetHiddenClassIdSelectorsOnTaskRunner, classes, ids, + exceptions_), base::BindOnce(&BraveCosmeticResourcesTabHelper:: - GetHiddenClassIdSelectorsOnTaskRunner, base::Unretained(this), - classes, ids), - base::BindOnce(&BraveCosmeticResourcesTabHelper:: - GetHiddenClassIdSelectorsOnUI, base::Unretained(this), - content::GlobalFrameRoutingId( + GetHiddenClassIdSelectorsOnUI, AsWeakPtr(), + content::GlobalFrameRoutingId( render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID()))); } diff --git a/browser/brave_cosmetic_resources_tab_helper.h b/browser/brave_cosmetic_resources_tab_helper.h index 0e083bf851c3..c09198440c45 100644 --- a/browser/brave_cosmetic_resources_tab_helper.h +++ b/browser/brave_cosmetic_resources_tab_helper.h @@ -33,9 +33,6 @@ class BraveCosmeticResourcesTabHelper content::RenderFrameHost* render_frame_host, const content::GlobalRequestID& request_id, const blink::mojom::ResourceLoadInfo& resource_load_info) override; - bool OnMessageReceived(const IPC::Message& message, - content::RenderFrameHost* render_frame_host) override; - bool OnMessageReceived(const IPC::Message& message) override; // // content::CosmeticFiltersObserver overrides: @@ -50,8 +47,6 @@ class BraveCosmeticResourcesTabHelper void ProcessURL(content::RenderFrameHost* render_frame_host, const GURL& url, const bool& main_frame); - std::unique_ptr GetUrlCosmeticResourcesOnTaskRunner( - const std::string& url); void GetUrlCosmeticResourcesOnUI(content::GlobalFrameRoutingId frame_id, const std::string& url, bool main_frame, std::unique_ptr resources); @@ -59,9 +54,6 @@ class BraveCosmeticResourcesTabHelper base::DictionaryValue* resources_dict, content::GlobalFrameRoutingId frame_id); - std::unique_ptr GetHiddenClassIdSelectorsOnTaskRunner( - const std::vector& classes, - const std::vector& ids); void GetHiddenClassIdSelectorsOnUI( content::GlobalFrameRoutingId frame_id, std::unique_ptr selectors); diff --git a/content/BUILD.gn b/content/BUILD.gn index cc923ca14341..f2cbea8f9c1a 100644 --- a/content/BUILD.gn +++ b/content/BUILD.gn @@ -17,6 +17,7 @@ source_set("browser") { deps = [ "//base", + "//content", "//content/public/browser", "//brave/ui/webui/resources", "//ui/base", From de97795c2b25cc41f2bf7db4cd1174c392b525fe Mon Sep 17 00:00:00 2001 From: Serg Date: Wed, 2 Dec 2020 15:40:19 -0500 Subject: [PATCH 09/45] adds a pump functionality to cf --- .../brave_cosmetic_resources_tab_helper.cc | 143 ++++++++--- browser/brave_cosmetic_resources_tab_helper.h | 8 +- .../resources/data/cosmetic_filters.js | 41 +++- .../resources/data/cosmetic_filters_pump.js | 232 ++++++++++++++++++ .../data/cosmetic_filters_resources.grd | 1 + renderer/brave_content_renderer_client.cc | 6 +- 6 files changed, 396 insertions(+), 35 deletions(-) create mode 100644 components/cosmetic_filters/resources/data/cosmetic_filters_pump.js diff --git a/browser/brave_cosmetic_resources_tab_helper.cc b/browser/brave_cosmetic_resources_tab_helper.cc index 963ec290209f..5cf34c6d723d 100644 --- a/browser/brave_cosmetic_resources_tab_helper.cc +++ b/browser/brave_cosmetic_resources_tab_helper.cc @@ -7,6 +7,7 @@ #include #include +#include #include #include "brave/browser/brave_browser_process_impl.h" @@ -26,13 +27,27 @@ #include "components/cosmetic_filters/resources/grit/cosmetic_filters_resources.h" #include "ui/base/resource/resource_bundle.h" -// Doing that to prevent lint error: +std::vector + BraveCosmeticResourcesTabHelper::vetted_search_engines_ = { + "duckduckgo", + "qwant", + "bing", + "startpage", + "yahoo", + "onesearch", + "google", + "yandex" +}; + +// Doing that to prevent a lint error: // Static/global string variables are not permitted // You can create an object dynamically and never delete it by using a // Function-local static pointer or reference // (e.g., static const auto& impl = *new T(args...);). std::string* BraveCosmeticResourcesTabHelper::observing_script_ = new std::string(""); +std::string* BraveCosmeticResourcesTabHelper::observing_pump_script_ = + new std::string(""); namespace { @@ -126,6 +141,26 @@ std::unique_ptr GetHiddenClassIdSelectorsOnTaskRunner( return result_list; } +bool IsVettedSearchEngine(const std::string& host) { + for (size_t i = 0; + i < BraveCosmeticResourcesTabHelper::vetted_search_engines_.size(); + i++) { + size_t found_pos = host.find( + BraveCosmeticResourcesTabHelper::vetted_search_engines_[i]); + if (found_pos != std::string::npos) { + size_t last_dot_pos = host.find(".", found_pos + 1); + if (last_dot_pos == std::string::npos) { + return false; + } + if (host.find(".", last_dot_pos + 1) == std::string::npos) { + return true; + } + } + } + + return false; +} + } // namespace @@ -137,6 +172,10 @@ BraveCosmeticResourcesTabHelper::BraveCosmeticResourcesTabHelper( *BraveCosmeticResourcesTabHelper::observing_script_ = LoadDataResource(IDR_COSMETIC_FILTERS_SCRIPT); } + if (BraveCosmeticResourcesTabHelper::observing_pump_script_->empty()) { + *BraveCosmeticResourcesTabHelper::observing_pump_script_ = + LoadDataResource(IDR_COSMETIC_FILTERS_PUMP_SCRIPT); + } } BraveCosmeticResourcesTabHelper::~BraveCosmeticResourcesTabHelper() { @@ -144,7 +183,7 @@ BraveCosmeticResourcesTabHelper::~BraveCosmeticResourcesTabHelper() { void BraveCosmeticResourcesTabHelper::GetUrlCosmeticResourcesOnUI( content::GlobalFrameRoutingId frame_id, const std::string& url, - bool main_frame, std::unique_ptr resources) { + bool do_non_scriplets, std::unique_ptr resources) { if (!resources) { return; } @@ -165,7 +204,7 @@ void BraveCosmeticResourcesTabHelper::GetUrlCosmeticResourcesOnUI( base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); } // Working on css rules - if (!main_frame) + if (!do_non_scriplets) return; CSSRulesRoutine(url, resources_dict, frame_id); } @@ -176,7 +215,7 @@ void BraveCosmeticResourcesTabHelper::CSSRulesRoutine( content::GlobalFrameRoutingId frame_id) { // Check are first party cosmetic filters enabled const GURL url(url_string); - if (url.is_empty() || !url.is_valid()) { + if (url.is_empty() || !url.is_valid() || IsVettedSearchEngine(url.host())) { return; } @@ -204,9 +243,17 @@ void BraveCosmeticResourcesTabHelper::CSSRulesRoutine( std::string rule = hide_selectors_list->GetList()[i].GetString() + "{display:none !important;}"; cosmeticFilterConsiderNewSelectors_script += - "window.cosmeticStyleSheet.insertRule(`" + rule + - "`,nextIndex);" - "nextIndex++;"; + "if (!window.allSelectorsToRules.has(`" + + hide_selectors_list->GetList()[i].GetString() + "`)) {" + "window.cosmeticStyleSheet.insertRule(`" + rule + + "`, nextIndex);" + "window.allSelectorsToRules.set(`" + + hide_selectors_list->GetList()[i].GetString() + + "`, nextIndex);" + "nextIndex++;" + "window.firstRunQueue.add(`" + + hide_selectors_list->GetList()[i].GetString() + "`);" + "}"; } cosmeticFilterConsiderNewSelectors_script += "if (!document.adoptedStyleSheets.includes(" @@ -254,31 +301,47 @@ void BraveCosmeticResourcesTabHelper::CSSRulesRoutine( } styled_stylesheet += ";}\n"; } - std::string cosmeticFilterConsiderNewSelectors_script = - "(function() {"; - cosmeticFilterConsiderNewSelectors_script += - "window.cosmeticStyleSheet.insertRule(`" + styled_stylesheet + - "`,window.cosmeticStyleSheet.rules.length);"; - cosmeticFilterConsiderNewSelectors_script += - "if (!document.adoptedStyleSheets.includes(" - "window.cosmeticStyleSheet)){" - "document.adoptedStyleSheets = [window.cosmeticStyleSheet];" - "};"; - cosmeticFilterConsiderNewSelectors_script += "})();"; + if (!styled_stylesheet.empty()) { + std::string cosmeticFilterConsiderNewSelectors_script = + "(function() {" + "let nextIndex = window.cosmeticStyleSheet.rules.length;"; + cosmeticFilterConsiderNewSelectors_script += + "window.cosmeticStyleSheet.insertRule(`" + styled_stylesheet + + "`, nextIndex);" + "window.allSelectorsToRules.set(`" + + styled_stylesheet + "`, nextIndex);" + "nextIndex++;"; + cosmeticFilterConsiderNewSelectors_script += + "if (!document.adoptedStyleSheets.includes(" + "window.cosmeticStyleSheet)){" + "document.adoptedStyleSheets = [window.cosmeticStyleSheet];" + "};"; + cosmeticFilterConsiderNewSelectors_script += + "})();"; + auto* frame_host = content::RenderFrameHost::FromID(frame_id); + if (!frame_host) + return; + frame_host->ExecuteJavaScriptInIsolatedWorld( + base::UTF8ToUTF16(cosmeticFilterConsiderNewSelectors_script), + base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); + } + } + + if (!enabled_1st_party_cf_filtering_) { auto* frame_host = content::RenderFrameHost::FromID(frame_id); if (!frame_host) return; frame_host->ExecuteJavaScriptInIsolatedWorld( - base::UTF8ToUTF16(cosmeticFilterConsiderNewSelectors_script), + base::UTF8ToUTF16( + *BraveCosmeticResourcesTabHelper::observing_pump_script_), base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); } - // } void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( - content::GlobalFrameRoutingId frame_id, + content::GlobalFrameRoutingId frame_id, const GURL& url, std::unique_ptr selectors) { - if (!selectors) { + if (!selectors || IsVettedSearchEngine(url.host())) { return; } if (enabled_1st_party_cf_filtering_) { @@ -299,9 +362,17 @@ void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( std::string rule = selectors_list->GetList()[i].GetString() + "{display:none !important;}"; cosmeticFilterConsiderNewSelectors_script += + "if (!window.allSelectorsToRules.has(`" + + selectors_list->GetList()[i].GetString() + "`)) {" "window.cosmeticStyleSheet.insertRule(`" + rule + - "`,nextIndex);" - "nextIndex++;"; + "`,nextIndex);" + "window.allSelectorsToRules.set(`" + + selectors_list->GetList()[i].GetString() + + "`, nextIndex);" + "nextIndex++;" + "window.firstRunQueue.add(`" + + selectors_list->GetList()[i].GetString() + "`);" + "}"; execute_script = true; } } @@ -320,11 +391,21 @@ void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); } } + + if (!enabled_1st_party_cf_filtering_) { + auto* frame_host = content::RenderFrameHost::FromID(frame_id); + if (!frame_host) + return; + frame_host->ExecuteJavaScriptInIsolatedWorld( + base::UTF8ToUTF16( + *BraveCosmeticResourcesTabHelper::observing_pump_script_), + base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); + } } void BraveCosmeticResourcesTabHelper::ProcessURL( content::RenderFrameHost* render_frame_host, const GURL& url, - const bool& main_frame) { + const bool& do_non_scriplets) { content::CosmeticFiltersCommunicationImpl::CreateInstance(render_frame_host, this); if (!render_frame_host || !ShouldDoCosmeticFiltering(web_contents(), url)) { @@ -339,8 +420,8 @@ void BraveCosmeticResourcesTabHelper::ProcessURL( content::GlobalFrameRoutingId( render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID()), - url.spec(), main_frame)); - if (!main_frame) + url.spec(), do_non_scriplets)); + if (!do_non_scriplets) return; // Non-scriptlet cosmetic filters are only applied on the top-level frame if (web_contents()->GetMainFrame()) { @@ -352,8 +433,11 @@ void BraveCosmeticResourcesTabHelper::ProcessURL( void BraveCosmeticResourcesTabHelper::DidFinishNavigation( content::NavigationHandle* navigation_handle) { + if (!navigation_handle) + return; ProcessURL(web_contents()->GetMainFrame(), - web_contents()->GetLastCommittedURL(), true); + web_contents()->GetLastCommittedURL(), + navigation_handle->IsInMainFrame()); } void BraveCosmeticResourcesTabHelper::ResourceLoadComplete( @@ -375,7 +459,8 @@ void BraveCosmeticResourcesTabHelper::HiddenClassIdSelectors( GetHiddenClassIdSelectorsOnUI, AsWeakPtr(), content::GlobalFrameRoutingId( render_frame_host->GetProcess()->GetID(), - render_frame_host->GetRoutingID()))); + render_frame_host->GetRoutingID()), + web_contents()->GetLastCommittedURL())); } WEB_CONTENTS_USER_DATA_KEY_IMPL(BraveCosmeticResourcesTabHelper) diff --git a/browser/brave_cosmetic_resources_tab_helper.h b/browser/brave_cosmetic_resources_tab_helper.h index c09198440c45..0e6d6264f504 100644 --- a/browser/brave_cosmetic_resources_tab_helper.h +++ b/browser/brave_cosmetic_resources_tab_helper.h @@ -22,6 +22,8 @@ class BraveCosmeticResourcesTabHelper public base::SupportsWeakPtr { public: static std::string* observing_script_; + static std::string* observing_pump_script_; + static std::vector vetted_search_engines_; explicit BraveCosmeticResourcesTabHelper(content::WebContents* contents); ~BraveCosmeticResourcesTabHelper() override; @@ -45,17 +47,17 @@ class BraveCosmeticResourcesTabHelper private: void ProcessURL(content::RenderFrameHost* render_frame_host, const GURL& url, - const bool& main_frame); + const bool& do_non_scriplets); void GetUrlCosmeticResourcesOnUI(content::GlobalFrameRoutingId frame_id, - const std::string& url, bool main_frame, + const std::string& url, bool do_non_scriplets, std::unique_ptr resources); void CSSRulesRoutine(const std::string& url, base::DictionaryValue* resources_dict, content::GlobalFrameRoutingId frame_id); void GetHiddenClassIdSelectorsOnUI( - content::GlobalFrameRoutingId frame_id, + content::GlobalFrameRoutingId frame_id, const GURL& url, std::unique_ptr selectors); std::vector exceptions_; diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters.js b/components/cosmetic_filters/resources/data/cosmetic_filters.js index bc7d719c8cfd..32a34f20e2b3 100644 --- a/components/cosmetic_filters/resources/data/cosmetic_filters.js +++ b/components/cosmetic_filters/resources/data/cosmetic_filters.js @@ -1,3 +1,8 @@ +/* Copyright (c) 2020 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/. */ + (function() { const queriedIds = new Set(); const queriedClasses = new Set(); @@ -7,6 +12,32 @@ if (window.cosmeticStyleSheet === undefined) { window.cosmeticStyleSheet = new CSSStyleSheet(); } + if (window.allSelectorsToRules === undefined) { + window.allSelectorsToRules = new Map(); + } + // All new selectors go in `firstRunQueue` + if (window.firstRunQueue === undefined) { + window.firstRunQueue = new Set(); + } + // Third party matches go in the second and third queues. + if (window.secondRunQueue === undefined) { + window.secondRunQueue = new Set(); + } + // Once a selector gets in to this queue, it's only evaluated for 1p content one + // more time. + if (window.finalRunQueue === undefined) { + window.finalRunQueue = new Set(); + } + if (window.allQueues === undefined) { + window.allQueues = [firstRunQueue, secondRunQueue, finalRunQueue]; + } + if (window.numQueues === undefined) { + window.numQueues = allQueues.length; + } + if (window.alreadyKnownFirstPartySubtrees === undefined) { + window.alreadyKnownFirstPartySubtrees = new Set(); + } + const fetchNewClassIdRules = function () { if ((!notYetQueriedClasses || notYetQueriedClasses.length === 0) && (!notYetQueriedIds || notYetQueriedIds.length === 0)) { @@ -75,6 +106,8 @@ }; const startObserving = () => { + // First queue up any classes and ids that exist before the mutation observer + // starts running. const elmWithClassOrId = document.querySelectorAll('[class],[id]'); for (const elm of elmWithClassOrId) { for (const aClassName of elm.classList.values()) { @@ -85,16 +118,22 @@ queriedIds.add(elmId); } }; + notYetQueriedClasses = Array.from(queriedClasses); notYetQueriedIds = Array.from(queriedIds); fetchNewClassIdRules(); + + // Second, set up a mutation observer to handle any new ids or classes + // that are added to the document. cosmeticObserver = new MutationObserver(handleMutations); let observerConfig = { subtree: true, childList: true, attributeFilter: ['id', 'class'] }; - cosmeticObserver.observe(document.documentElement, observerConfig); + if (document.documentElement instanceof Node) { + cosmeticObserver.observe(document.documentElement, observerConfig); + } }; startObserving(); })(); diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js b/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js new file mode 100644 index 000000000000..bceaaa109241 --- /dev/null +++ b/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js @@ -0,0 +1,232 @@ +/* Copyright (c) 2020 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/. */ + +(function() { + const pumpIntervalMaxMs = 1000; + const maxWorkSize = 60; + let queueIsSleeping = false; + + /** + * Provides a new function which can only be scheduled once at a time. + * + * @param onIdle function to run when the thread is less busy + * @param timeout max time to wait. at or after this time the function will be run regardless of thread noise + */ + const idleize = (onIdle, timeout) => { + let idleId = undefined; + return function WillRunOnIdle () { + if (idleId !== undefined) { + return; + } + idleId = window.requestIdleCallback(() => { + idleId = undefined; + onIdle(); + }, { timeout }) + } + } + + // const isFirstPartyUrl = (url) => { + // if (isRelativeUrl(url)) { + // return true + // } + + // const parsedTargetDomain = getParsedDomain(url) + + // if (parsedTargetDomain.type !== _parsedCurrentDomain.type) { + // return false + // } + + // if (parsedTargetDomain.type === ParseResultType.Listed) { + // const isSameEtldP1 = (_parsedCurrentDomain.icann.topLevelDomains === parsedTargetDomain.icann.topLevelDomains && + // _parsedCurrentDomain.icann.domain === parsedTargetDomain.icann.domain) + // return isSameEtldP1 + // } + + // const looksLikePrivateOrigin = + // [ParseResultType.NotListed, ParseResultType.Ip, ParseResultType.Reserved].includes(parsedTargetDomain.type) + // if (looksLikePrivateOrigin) { + // return _parsedCurrentDomain.hostname === parsedTargetDomain.hostname + // } + + // return false + // } + + /** + * Determine whether a subtree should be considered as "first party" content. + * + * Uses the following process in making this determination. + * - If the subtree contains any first party resources, the subtree is 1p. + * - If the subtree contains no remote resources, the subtree is first party. + * - Otherwise, its 3rd party. + * + * Note that any instances of "url(" or escape characters in style attributes + * are automatically treated as third-party URLs. These patterns and special + * cases were generated from looking at patterns in ads with resources in the + * style attribute. + * + * Similarly, an empty srcdoc attribute is also considered 3p, since many + * third party ads clear this attribute in practice. + * + * Finally, special case some ids we know are used only for third party ads. + */ + const isSubTreeFirstParty = (elm, possibleQueryResult) => { + let queryResult; + let isTopLevel; + + if (possibleQueryResult) { + queryResult = possibleQueryResult; + isTopLevel = false; + } else { + queryResult = { + foundFirstPartyResource: false, + foundThirdPartyResource: false, + foundKnownThirdPartyAd: false + }; + isTopLevel = true; + } + + if (elm.getAttribute) { + if (elm.hasAttribute('id')) { + const elmId = elm.getAttribute('id'); + if (elmId.startsWith('google_ads_iframe_') || + elmId.startsWith('div-gpt-ad') || + elmId.startsWith('adfox_')) { + queryResult.foundKnownThirdPartyAd = true; + return false; + } + } + + // if (elm.hasAttribute('src')) { + // const elmSrc = elm.getAttribute('src') as string; + // const elmSrcIsFirstParty = isFirstPartyUrl(elmSrc); + // if (elmSrcIsFirstParty === true) { + // queryResult.foundFirstPartyResource = true; + // return true; + // } + // queryResult.foundThirdPartyResource = true; + // } + + // if (elm.hasAttribute('style')) { + // const elmStyle = elm.getAttribute('style') as string; + // if (elmStyle.includes('url(') || + // elmStyle.includes('//')) { + // queryResult.foundThirdPartyResource = true; + // } + // } + + // if (elm.hasAttribute('srcdoc')) { + // const elmSrcDoc = elm.getAttribute('srcdoc') as string; + // if (elmSrcDoc.trim() === '') { + // queryResult.foundThirdPartyResource = true; + // } + // } + } + + // if (elm.firstChild) { + // isSubTreeFirstParty(elm.firstChild as Element, queryResult) + // if (queryResult.foundKnownThirdPartyAd === true) { + // return false + // } + // if (queryResult.foundFirstPartyResource === true) { + // return true + // } + // } + + // if (elm.nextSibling) { + // isSubTreeFirstParty(elm.nextSibling as Element, queryResult) + // if (queryResult.foundKnownThirdPartyAd === true) { + // return false + // } + // if (queryResult.foundFirstPartyResource === true) { + // return true + // } + // } + + // if (isTopLevel === false) { + // return (queryResult.foundThirdPartyResource === false) + // } + + // if (queryResult.foundThirdPartyResource) { + // return false + // } + + // const htmlElement = asHTMLElement(elm) + // // Check for several things here: + // // 1. If its not an HTML node (i.e. its a text node), then its definitely + // // not the root of first party ad (we'd have caught that it was a text + // // add when checking the text node's parent). + // // 2. If it's a script node, then similarly, its definitely not the root + // // of a first party ad on the page. + // // 3. Last, check the text content on the page. If the node contains a + // // non-trivial amount of text in it, then we _should_ treat it as a + // // possible 1p ad. + // if (!htmlElement || + // htmlElement.tagName.toLowerCase() === 'script' || + // isTextAd(htmlElement.innerText) === false) { + // return false + // } + + return true + } + + /** + * Go through each of the 3 queues, only take maxWorkSize items from each one + * 1. Take maxWorkSize selects from the first queue with any items + * 2. Determine partyness of matched element: + * - If any are 3rd party, keep 'hide' rule and check again later in next queue. + * - If any are 1st party, remove 'hide' rule and never check selector again. + * 3. If we're looking at the 3rd queue, don't requeue any selectors. + */ + const pumpCosmeticFilterQueues = () => { + if (queueIsSleeping === true) { + return; + } + + let didPumpAnything = false + // For each "pump", walk through each queue until we find selectors + // to evaluate. This means that nothing in queue N+1 will be evaluated + // until queue N is completely empty. + for (let queueIndex = 0; queueIndex < window.numQueues; queueIndex += 1) { + const currentQueue = window.allQueues[queueIndex]; + const nextQueue = window.allQueues[queueIndex + 1]; + if (currentQueue.size === 0) { + continue; + } + + const currentWorkLoad = Array.from(currentQueue.values()).slice(0, maxWorkSize); + const comboSelector = currentWorkLoad.join(','); + const matchingElms = document.querySelectorAll(comboSelector); + // Will hold selectors identified by _this_ queue pumping, that were + // newly identified to be matching 1p content. Will be sent to + // the background script to do the un-hiding. + const newlyIdentifiedFirstPartySelectors = new Set(); + + for (const aMatchingElm of matchingElms) { + // Don't recheck elements / subtrees we already know are first party. + // Once we know something is third party, we never need to evaluate it + // again. + if (window.alreadyKnownFirstPartySubtrees.has(aMatchingElm)) { + continue; + } + + const elmSubtreeIsFirstParty = isSubTreeFirstParty(aMatchingElm); + // If we find that a subtree is third party, then no need to change + // anything, leave the selector as "hiding" and move on. + // This element will likely be checked again on the next 'pump' + // as long as another element from the selector does not match 1st party. + if (elmSubtreeIsFirstParty === false) { + continue; + } + } + } + } + + const pumpCosmeticFilterQueuesOnIdle = idleize( + pumpCosmeticFilterQueues, + pumpIntervalMaxMs + ); + + pumpCosmeticFilterQueuesOnIdle(); +})(); diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd b/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd index 473de21b4176..ec77028bcb02 100644 --- a/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd +++ b/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd @@ -9,6 +9,7 @@ + diff --git a/renderer/brave_content_renderer_client.cc b/renderer/brave_content_renderer_client.cc index ea5c0ffc47c2..a9218c2105c6 100644 --- a/renderer/brave_content_renderer_client.cc +++ b/renderer/brave_content_renderer_client.cc @@ -25,6 +25,8 @@ void BraveContentRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { ChromeContentRendererClient::RenderFrameCreated(render_frame); - new cosmetic_filters_worker::CosmeticFiltersJsRenderFrameObserver( - render_frame, ISOLATED_WORLD_ID_CHROME_INTERNAL); + if (render_frame->IsMainFrame()) { + new cosmetic_filters_worker::CosmeticFiltersJsRenderFrameObserver( + render_frame, ISOLATED_WORLD_ID_CHROME_INTERNAL); + } } From 93ced6a488c9a8162b3bbd41f28fe326eb86356d Mon Sep 17 00:00:00 2001 From: Serg Date: Thu, 3 Dec 2020 12:02:10 -0500 Subject: [PATCH 10/45] corrects cf scripts --- .../resources/data/cosmetic_filters.js | 3 + .../resources/data/cosmetic_filters_pump.js | 312 +++++++++++++----- 2 files changed, 226 insertions(+), 89 deletions(-) diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters.js b/components/cosmetic_filters/resources/data/cosmetic_filters.js index 32a34f20e2b3..cdfd724507f8 100644 --- a/components/cosmetic_filters/resources/data/cosmetic_filters.js +++ b/components/cosmetic_filters/resources/data/cosmetic_filters.js @@ -37,6 +37,9 @@ if (window.alreadyKnownFirstPartySubtrees === undefined) { window.alreadyKnownFirstPartySubtrees = new Set(); } + if (window.alreadyUnhiddenSelectors === undefined) { + window.alreadyUnhiddenSelectors = new Set(); + } const fetchNewClassIdRules = function () { if ((!notYetQueriedClasses || notYetQueriedClasses.length === 0) && diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js b/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js index bceaaa109241..030a477e9ed1 100644 --- a/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js +++ b/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js @@ -4,9 +4,16 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ (function() { + const { parseDomain, ParseResultType } = require('parse-domain') + const pumpIntervalMinMs = 40 const pumpIntervalMaxMs = 1000; const maxWorkSize = 60; let queueIsSleeping = false; + // The cutoff for text ads. If something has only text in it, it needs to have + // this many, or more, characters. Similarly, require it to have a non-trivial + // number of words in it, to look like an actual text ad. + const minAdTextChars = 30; + const minAdTextWords = 5; /** * Provides a new function which can only be scheduled once at a time. @@ -27,31 +34,72 @@ } } - // const isFirstPartyUrl = (url) => { - // if (isRelativeUrl(url)) { - // return true - // } + const _parseDomainCache = Object.create(null); + const getParsedDomain = (aDomain) => { + const cacheResult = _parseDomainCache[aDomain]; + if (cacheResult !== undefined) { + return cacheResult; + } + + const newResult = parseDomain(aDomain); + _parseDomainCache[aDomain] = newResult; + console.log('aDomain == ' + aDomain); + return newResult; + } + + const isRelativeUrl = (url) => { + return ( + !url.startsWith('//') && + !url.startsWith('http://') && + !url.startsWith('https://') + ) + } + + const _parsedCurrentDomain = getParsedDomain(window.location.host) + const isFirstPartyUrl = (url) => { + if (isRelativeUrl(url)) { + return true + } + + const parsedTargetDomain = getParsedDomain(url) - // const parsedTargetDomain = getParsedDomain(url) + if (parsedTargetDomain.type !== _parsedCurrentDomain.type) { + return false + } + + if (parsedTargetDomain.type === ParseResultType.Listed) { + const isSameEtldP1 = (_parsedCurrentDomain.icann.topLevelDomains === parsedTargetDomain.icann.topLevelDomains && + _parsedCurrentDomain.icann.domain === parsedTargetDomain.icann.domain) + return isSameEtldP1 + } - // if (parsedTargetDomain.type !== _parsedCurrentDomain.type) { - // return false - // } + const looksLikePrivateOrigin = + [ParseResultType.NotListed, ParseResultType.Ip, ParseResultType.Reserved].includes(parsedTargetDomain.type) + if (looksLikePrivateOrigin) { + return _parsedCurrentDomain.hostname === parsedTargetDomain.hostname + } - // if (parsedTargetDomain.type === ParseResultType.Listed) { - // const isSameEtldP1 = (_parsedCurrentDomain.icann.topLevelDomains === parsedTargetDomain.icann.topLevelDomains && - // _parsedCurrentDomain.icann.domain === parsedTargetDomain.icann.domain) - // return isSameEtldP1 - // } + return false + } - // const looksLikePrivateOrigin = - // [ParseResultType.NotListed, ParseResultType.Ip, ParseResultType.Reserved].includes(parsedTargetDomain.type) - // if (looksLikePrivateOrigin) { - // return _parsedCurrentDomain.hostname === parsedTargetDomain.hostname - // } + const isHTMLElement = (node) => { + return ('innerText' in node) + } - // return false - // } + const asHTMLElement = (node) => { + return isHTMLElement(node) ? node : null + } + + const isTextAd = (text) => { + const trimmedText = text.trim() + if (trimmedText.length < minAdTextChars) { + return false + } + if (trimmedText.split(' ').length < minAdTextWords) { + return false + } + return true + } /** * Determine whether a subtree should be considered as "first party" content. @@ -98,79 +146,119 @@ } } - // if (elm.hasAttribute('src')) { - // const elmSrc = elm.getAttribute('src') as string; - // const elmSrcIsFirstParty = isFirstPartyUrl(elmSrc); - // if (elmSrcIsFirstParty === true) { - // queryResult.foundFirstPartyResource = true; - // return true; - // } - // queryResult.foundThirdPartyResource = true; - // } - - // if (elm.hasAttribute('style')) { - // const elmStyle = elm.getAttribute('style') as string; - // if (elmStyle.includes('url(') || - // elmStyle.includes('//')) { - // queryResult.foundThirdPartyResource = true; - // } - // } - - // if (elm.hasAttribute('srcdoc')) { - // const elmSrcDoc = elm.getAttribute('srcdoc') as string; - // if (elmSrcDoc.trim() === '') { - // queryResult.foundThirdPartyResource = true; - // } - // } - } - - // if (elm.firstChild) { - // isSubTreeFirstParty(elm.firstChild as Element, queryResult) - // if (queryResult.foundKnownThirdPartyAd === true) { - // return false - // } - // if (queryResult.foundFirstPartyResource === true) { - // return true - // } - // } - - // if (elm.nextSibling) { - // isSubTreeFirstParty(elm.nextSibling as Element, queryResult) - // if (queryResult.foundKnownThirdPartyAd === true) { - // return false - // } - // if (queryResult.foundFirstPartyResource === true) { - // return true - // } - // } - - // if (isTopLevel === false) { - // return (queryResult.foundThirdPartyResource === false) - // } - - // if (queryResult.foundThirdPartyResource) { - // return false - // } - - // const htmlElement = asHTMLElement(elm) - // // Check for several things here: - // // 1. If its not an HTML node (i.e. its a text node), then its definitely - // // not the root of first party ad (we'd have caught that it was a text - // // add when checking the text node's parent). - // // 2. If it's a script node, then similarly, its definitely not the root - // // of a first party ad on the page. - // // 3. Last, check the text content on the page. If the node contains a - // // non-trivial amount of text in it, then we _should_ treat it as a - // // possible 1p ad. - // if (!htmlElement || - // htmlElement.tagName.toLowerCase() === 'script' || - // isTextAd(htmlElement.innerText) === false) { - // return false - // } + if (elm.hasAttribute('src')) { + const elmSrc = elm.getAttribute('src'); + const elmSrcIsFirstParty = isFirstPartyUrl(elmSrc); + if (elmSrcIsFirstParty === true) { + queryResult.foundFirstPartyResource = true; + return true; + } + queryResult.foundThirdPartyResource = true; + } + + if (elm.hasAttribute('style')) { + const elmStyle = elm.getAttribute('style'); + if (elmStyle.includes('url(') || + elmStyle.includes('//')) { + queryResult.foundThirdPartyResource = true; + } + } + + if (elm.hasAttribute('srcdoc')) { + const elmSrcDoc = elm.getAttribute('srcdoc'); + if (elmSrcDoc.trim() === '') { + queryResult.foundThirdPartyResource = true; + } + } + } + + if (elm.firstChild) { + isSubTreeFirstParty(elm.firstChild, queryResult) + if (queryResult.foundKnownThirdPartyAd === true) { + return false + } + if (queryResult.foundFirstPartyResource === true) { + return true + } + } + + if (elm.nextSibling) { + isSubTreeFirstParty(elm.nextSibling, queryResult) + if (queryResult.foundKnownThirdPartyAd === true) { + return false + } + if (queryResult.foundFirstPartyResource === true) { + return true + } + } + + if (isTopLevel === false) { + return (queryResult.foundThirdPartyResource === false) + } + + if (queryResult.foundThirdPartyResource) { + return false + } + + const htmlElement = asHTMLElement(elm) + // Check for several things here: + // 1. If its not an HTML node (i.e. its a text node), then its definitely + // not the root of first party ad (we'd have caught that it was a text + // add when checking the text node's parent). + // 2. If it's a script node, then similarly, its definitely not the root + // of a first party ad on the page. + // 3. Last, check the text content on the page. If the node contains a + // non-trivial amount of text in it, then we _should_ treat it as a + // possible 1p ad. + if (!htmlElement || + htmlElement.tagName.toLowerCase() === 'script' || + isTextAd(htmlElement.innerText) === false) { + return false + } return true } + const unhideSelectors = (selectors) => { + if (selectors.size === 0) { + return + } + // Find selectors we have a rule index for + const rulesToRemove = Array.from(selectors) + .map(selector => window.allSelectorsToRules.get(selector)) + .filter(i => i !== undefined) + .sort() + .reverse() + // Delete the rules + let lastIdx = window.allSelectorsToRules.size - 1 + for (const ruleIdx of rulesToRemove) { + // Safe to asset ruleIdx is a number because we've already filtered out + // any `undefined` instances with the filter call above. + window.cosmeticStyleSheet.deleteRule(ruleIdx) + } + // Re-sync the indexes + // TODO: Sync is hard, just re-build by iterating through the StyleSheet rules. + const ruleLookup = Array.from(window.allSelectorsToRules.entries()) + let countAtLastHighest = rulesToRemove.length + for (let i = lastIdx; i > 0; i--) { + const [selector, oldIdx] = ruleLookup[i] + // Is this one we removed? + if (rulesToRemove.includes(i)) { + window.allSelectorsToRules.delete(selector) + countAtLastHighest-- + if (countAtLastHighest === 0) { + break + } + continue + } + if (oldIdx !== i) { + // Probably out of sync + console.error('Cosmetic Filters: old index did not match lookup index', { selector, oldIdx, i }) + } + window.allSelectorsToRules.set(selector, oldIdx - countAtLastHighest) + } + } + /** * Go through each of the 3 queues, only take maxWorkSize items from each one * 1. Take maxWorkSize selects from the first queue with any items @@ -219,7 +307,53 @@ if (elmSubtreeIsFirstParty === false) { continue; } + // Otherwise, we know that the given subtree was evaluated to be + // first party, so we need to figure out which selector from the combo + // selector did the matching. + for (const selector of currentWorkLoad) { + if (aMatchingElm.matches(selector) === false) { + continue + } + + // Similarly, if we already know a selector matches 1p content, + // there is no need to notify the background script again, so + // we don't need to consider further. + if (window.alreadyUnhiddenSelectors.has(selector) === true) { + continue + } + + newlyIdentifiedFirstPartySelectors.add(selector) + window.alreadyUnhiddenSelectors.add(selector) + } + window.alreadyKnownFirstPartySubtrees.add(aMatchingElm) } + + unhideSelectors(newlyIdentifiedFirstPartySelectors) + + for (const aUsedSelector of currentWorkLoad) { + currentQueue.delete(aUsedSelector) + // Don't requeue selectors we know identify first party content. + const selectorMatchedFirstParty = newlyIdentifiedFirstPartySelectors.has(aUsedSelector) + if (nextQueue && selectorMatchedFirstParty === false) { + nextQueue.add(aUsedSelector) + } + } + + didPumpAnything = true + // If we did something, process the next queue, save it for next time. + break + } + + if (didPumpAnything) { + queueIsSleeping = true + window.setTimeout(() => { + // Set this to false now even though there's a gap in time between now and + // idle since all other calls to `pumpCosmeticFilterQueuesOnIdle` that occur during this time + // will be ignored (and nothing else should be calling `pumpCosmeticFilterQueues` straight). + queueIsSleeping = false + // tslint:disable-next-line:no-use-before-declare + pumpCosmeticFilterQueuesOnIdle() + }, pumpIntervalMinMs) } } From 57568bd7c2c44a08f805c2f8828b68b4e72fb057 Mon Sep 17 00:00:00 2001 From: Serg Date: Thu, 3 Dec 2020 14:32:54 -0500 Subject: [PATCH 11/45] moves all cf in a one script --- .../brave_cosmetic_resources_tab_helper.cc | 11 +- browser/brave_cosmetic_resources_tab_helper.h | 1 - .../resources/data/cosmetic_filters.js | 374 +++++++++++++++++- .../resources/data/cosmetic_filters_pump.js | 366 ----------------- .../data/cosmetic_filters_resources.grd | 3 +- 5 files changed, 377 insertions(+), 378 deletions(-) delete mode 100644 components/cosmetic_filters/resources/data/cosmetic_filters_pump.js diff --git a/browser/brave_cosmetic_resources_tab_helper.cc b/browser/brave_cosmetic_resources_tab_helper.cc index 5cf34c6d723d..d35e996d43df 100644 --- a/browser/brave_cosmetic_resources_tab_helper.cc +++ b/browser/brave_cosmetic_resources_tab_helper.cc @@ -46,8 +46,7 @@ std::vector // (e.g., static const auto& impl = *new T(args...);). std::string* BraveCosmeticResourcesTabHelper::observing_script_ = new std::string(""); -std::string* BraveCosmeticResourcesTabHelper::observing_pump_script_ = - new std::string(""); + namespace { @@ -172,10 +171,6 @@ BraveCosmeticResourcesTabHelper::BraveCosmeticResourcesTabHelper( *BraveCosmeticResourcesTabHelper::observing_script_ = LoadDataResource(IDR_COSMETIC_FILTERS_SCRIPT); } - if (BraveCosmeticResourcesTabHelper::observing_pump_script_->empty()) { - *BraveCosmeticResourcesTabHelper::observing_pump_script_ = - LoadDataResource(IDR_COSMETIC_FILTERS_PUMP_SCRIPT); - } } BraveCosmeticResourcesTabHelper::~BraveCosmeticResourcesTabHelper() { @@ -333,7 +328,7 @@ void BraveCosmeticResourcesTabHelper::CSSRulesRoutine( return; frame_host->ExecuteJavaScriptInIsolatedWorld( base::UTF8ToUTF16( - *BraveCosmeticResourcesTabHelper::observing_pump_script_), + *BraveCosmeticResourcesTabHelper::observing_script_), base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); } } @@ -398,7 +393,7 @@ void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( return; frame_host->ExecuteJavaScriptInIsolatedWorld( base::UTF8ToUTF16( - *BraveCosmeticResourcesTabHelper::observing_pump_script_), + *BraveCosmeticResourcesTabHelper::observing_script_), base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); } } diff --git a/browser/brave_cosmetic_resources_tab_helper.h b/browser/brave_cosmetic_resources_tab_helper.h index 0e6d6264f504..09934be558f5 100644 --- a/browser/brave_cosmetic_resources_tab_helper.h +++ b/browser/brave_cosmetic_resources_tab_helper.h @@ -22,7 +22,6 @@ class BraveCosmeticResourcesTabHelper public base::SupportsWeakPtr { public: static std::string* observing_script_; - static std::string* observing_pump_script_; static std::vector vetted_search_engines_; explicit BraveCosmeticResourcesTabHelper(content::WebContents* contents); diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters.js b/components/cosmetic_filters/resources/data/cosmetic_filters.js index cdfd724507f8..834ff68221de 100644 --- a/components/cosmetic_filters/resources/data/cosmetic_filters.js +++ b/components/cosmetic_filters/resources/data/cosmetic_filters.js @@ -4,6 +4,21 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ (function() { + const { parseDomain, ParseResultType } = require('parse-domain') + // Start looking for things to unhide before at most this long after + // the backend script is up and connected (eg backgroundReady = true), + // or sooner if the thread is idle. + const maxTimeMSBeforeStart = 2500 + const pumpIntervalMinMs = 40 + const pumpIntervalMaxMs = 1000; + const maxWorkSize = 60; + let queueIsSleeping = false; + // The cutoff for text ads. If something has only text in it, it needs to have + // this many, or more, characters. Similarly, require it to have a non-trivial + // number of words in it, to look like an actual text ad. + const minAdTextChars = 30; + const minAdTextWords = 5; + const queriedIds = new Set(); const queriedClasses = new Set(); var notYetQueriedClasses; @@ -40,6 +55,9 @@ if (window.alreadyUnhiddenSelectors === undefined) { window.alreadyUnhiddenSelectors = new Set(); } + if (window.observingHasStarted === undefined) { + window.observingHasStarted = false; + } const fetchNewClassIdRules = function () { if ((!notYetQueriedClasses || notYetQueriedClasses.length === 0) && @@ -138,5 +156,359 @@ cosmeticObserver.observe(document.documentElement, observerConfig); } }; - startObserving(); + + /** + * Provides a new function which can only be scheduled once at a time. + * + * @param onIdle function to run when the thread is less busy + * @param timeout max time to wait. at or after this time the function will be run regardless of thread noise + */ + const idleize = (onIdle, timeout) => { + let idleId = undefined; + return function WillRunOnIdle () { + if (idleId !== undefined) { + return; + } + idleId = window.requestIdleCallback(() => { + idleId = undefined; + onIdle(); + }, { timeout }) + } + } + + const _parseDomainCache = Object.create(null); + const getParsedDomain = (aDomain) => { + const cacheResult = _parseDomainCache[aDomain]; + if (cacheResult !== undefined) { + return cacheResult; + } + + const newResult = parseDomain(aDomain); + _parseDomainCache[aDomain] = newResult; + return newResult; + } + + const isRelativeUrl = (url) => { + return ( + !url.startsWith('//') && + !url.startsWith('http://') && + !url.startsWith('https://') + ) + } + + const _parsedCurrentDomain = getParsedDomain(window.location.host) + const isFirstPartyUrl = (url) => { + if (isRelativeUrl(url)) { + return true + } + + const parsedTargetDomain = getParsedDomain(url) + + if (parsedTargetDomain.type !== _parsedCurrentDomain.type) { + return false + } + + if (parsedTargetDomain.type === ParseResultType.Listed) { + const isSameEtldP1 = (_parsedCurrentDomain.icann.topLevelDomains === parsedTargetDomain.icann.topLevelDomains && + _parsedCurrentDomain.icann.domain === parsedTargetDomain.icann.domain) + return isSameEtldP1 + } + + const looksLikePrivateOrigin = + [ParseResultType.NotListed, ParseResultType.Ip, ParseResultType.Reserved].includes(parsedTargetDomain.type) + if (looksLikePrivateOrigin) { + return _parsedCurrentDomain.hostname === parsedTargetDomain.hostname + } + + return false + } + + const isHTMLElement = (node) => { + return ('innerText' in node) + } + + const asHTMLElement = (node) => { + return isHTMLElement(node) ? node : null + } + + const isTextAd = (text) => { + const trimmedText = text.trim() + if (trimmedText.length < minAdTextChars) { + return false + } + if (trimmedText.split(' ').length < minAdTextWords) { + return false + } + return true + } + + /** + * Determine whether a subtree should be considered as "first party" content. + * + * Uses the following process in making this determination. + * - If the subtree contains any first party resources, the subtree is 1p. + * - If the subtree contains no remote resources, the subtree is first party. + * - Otherwise, its 3rd party. + * + * Note that any instances of "url(" or escape characters in style attributes + * are automatically treated as third-party URLs. These patterns and special + * cases were generated from looking at patterns in ads with resources in the + * style attribute. + * + * Similarly, an empty srcdoc attribute is also considered 3p, since many + * third party ads clear this attribute in practice. + * + * Finally, special case some ids we know are used only for third party ads. + */ + const isSubTreeFirstParty = (elm, possibleQueryResult) => { + let queryResult; + let isTopLevel; + + if (possibleQueryResult) { + queryResult = possibleQueryResult; + isTopLevel = false; + } else { + queryResult = { + foundFirstPartyResource: false, + foundThirdPartyResource: false, + foundKnownThirdPartyAd: false + }; + isTopLevel = true; + } + + if (elm.getAttribute) { + if (elm.hasAttribute('id')) { + const elmId = elm.getAttribute('id'); + if (elmId.startsWith('google_ads_iframe_') || + elmId.startsWith('div-gpt-ad') || + elmId.startsWith('adfox_')) { + queryResult.foundKnownThirdPartyAd = true; + return false; + } + } + + if (elm.hasAttribute('src')) { + const elmSrc = elm.getAttribute('src'); + const elmSrcIsFirstParty = isFirstPartyUrl(elmSrc); + if (elmSrcIsFirstParty === true) { + queryResult.foundFirstPartyResource = true; + return true; + } + queryResult.foundThirdPartyResource = true; + } + + if (elm.hasAttribute('style')) { + const elmStyle = elm.getAttribute('style'); + if (elmStyle.includes('url(') || + elmStyle.includes('//')) { + queryResult.foundThirdPartyResource = true; + } + } + + if (elm.hasAttribute('srcdoc')) { + const elmSrcDoc = elm.getAttribute('srcdoc'); + if (elmSrcDoc.trim() === '') { + queryResult.foundThirdPartyResource = true; + } + } + } + + if (elm.firstChild) { + isSubTreeFirstParty(elm.firstChild, queryResult) + if (queryResult.foundKnownThirdPartyAd === true) { + return false + } + if (queryResult.foundFirstPartyResource === true) { + return true + } + } + + if (elm.nextSibling) { + isSubTreeFirstParty(elm.nextSibling, queryResult) + if (queryResult.foundKnownThirdPartyAd === true) { + return false + } + if (queryResult.foundFirstPartyResource === true) { + return true + } + } + + if (isTopLevel === false) { + return (queryResult.foundThirdPartyResource === false) + } + + if (queryResult.foundThirdPartyResource) { + return false + } + + const htmlElement = asHTMLElement(elm) + // Check for several things here: + // 1. If its not an HTML node (i.e. its a text node), then its definitely + // not the root of first party ad (we'd have caught that it was a text + // add when checking the text node's parent). + // 2. If it's a script node, then similarly, its definitely not the root + // of a first party ad on the page. + // 3. Last, check the text content on the page. If the node contains a + // non-trivial amount of text in it, then we _should_ treat it as a + // possible 1p ad. + if (!htmlElement || + htmlElement.tagName.toLowerCase() === 'script' || + isTextAd(htmlElement.innerText) === false) { + return false + } + + return true + } + + const unhideSelectors = (selectors) => { + if (selectors.size === 0) { + return + } + // Find selectors we have a rule index for + const rulesToRemove = Array.from(selectors) + .map(selector => window.allSelectorsToRules.get(selector)) + .filter(i => i !== undefined) + .sort() + .reverse() + // Delete the rules + let lastIdx = window.allSelectorsToRules.size - 1 + for (const ruleIdx of rulesToRemove) { + // Safe to asset ruleIdx is a number because we've already filtered out + // any `undefined` instances with the filter call above. + window.cosmeticStyleSheet.deleteRule(ruleIdx) + } + // Re-sync the indexes + // TODO: Sync is hard, just re-build by iterating through the StyleSheet rules. + const ruleLookup = Array.from(window.allSelectorsToRules.entries()) + let countAtLastHighest = rulesToRemove.length + for (let i = lastIdx; i > 0; i--) { + const [selector, oldIdx] = ruleLookup[i] + // Is this one we removed? + if (rulesToRemove.includes(i)) { + window.allSelectorsToRules.delete(selector) + countAtLastHighest-- + if (countAtLastHighest === 0) { + break + } + continue + } + if (oldIdx !== i) { + // Probably out of sync + console.error('Cosmetic Filters: old index did not match lookup index', { selector, oldIdx, i }) + } + window.allSelectorsToRules.set(selector, oldIdx - countAtLastHighest) + } + } + + /** + * Go through each of the 3 queues, only take maxWorkSize items from each one + * 1. Take maxWorkSize selects from the first queue with any items + * 2. Determine partyness of matched element: + * - If any are 3rd party, keep 'hide' rule and check again later in next queue. + * - If any are 1st party, remove 'hide' rule and never check selector again. + * 3. If we're looking at the 3rd queue, don't requeue any selectors. + */ + const pumpCosmeticFilterQueues = () => { + if (queueIsSleeping === true) { + return; + } + + let didPumpAnything = false + // For each "pump", walk through each queue until we find selectors + // to evaluate. This means that nothing in queue N+1 will be evaluated + // until queue N is completely empty. + for (let queueIndex = 0; queueIndex < window.numQueues; queueIndex += 1) { + const currentQueue = window.allQueues[queueIndex]; + const nextQueue = window.allQueues[queueIndex + 1]; + if (currentQueue.size === 0) { + continue; + } + + const currentWorkLoad = Array.from(currentQueue.values()).slice(0, maxWorkSize); + const comboSelector = currentWorkLoad.join(','); + const matchingElms = document.querySelectorAll(comboSelector); + // Will hold selectors identified by _this_ queue pumping, that were + // newly identified to be matching 1p content. Will be sent to + // the background script to do the un-hiding. + const newlyIdentifiedFirstPartySelectors = new Set(); + + for (const aMatchingElm of matchingElms) { + // Don't recheck elements / subtrees we already know are first party. + // Once we know something is third party, we never need to evaluate it + // again. + if (window.alreadyKnownFirstPartySubtrees.has(aMatchingElm)) { + continue; + } + + const elmSubtreeIsFirstParty = isSubTreeFirstParty(aMatchingElm); + // If we find that a subtree is third party, then no need to change + // anything, leave the selector as "hiding" and move on. + // This element will likely be checked again on the next 'pump' + // as long as another element from the selector does not match 1st party. + if (elmSubtreeIsFirstParty === false) { + continue; + } + // Otherwise, we know that the given subtree was evaluated to be + // first party, so we need to figure out which selector from the combo + // selector did the matching. + for (const selector of currentWorkLoad) { + if (aMatchingElm.matches(selector) === false) { + continue + } + + // Similarly, if we already know a selector matches 1p content, + // there is no need to notify the background script again, so + // we don't need to consider further. + if (window.alreadyUnhiddenSelectors.has(selector) === true) { + continue + } + + newlyIdentifiedFirstPartySelectors.add(selector) + window.alreadyUnhiddenSelectors.add(selector) + } + window.alreadyKnownFirstPartySubtrees.add(aMatchingElm) + } + + unhideSelectors(newlyIdentifiedFirstPartySelectors) + + for (const aUsedSelector of currentWorkLoad) { + currentQueue.delete(aUsedSelector) + // Don't requeue selectors we know identify first party content. + const selectorMatchedFirstParty = newlyIdentifiedFirstPartySelectors.has(aUsedSelector) + if (nextQueue && selectorMatchedFirstParty === false) { + nextQueue.add(aUsedSelector) + } + } + + didPumpAnything = true + // If we did something, process the next queue, save it for next time. + break + } + + if (didPumpAnything) { + queueIsSleeping = true + window.setTimeout(() => { + // Set this to false now even though there's a gap in time between now and + // idle since all other calls to `pumpCosmeticFilterQueuesOnIdle` that occur during this time + // will be ignored (and nothing else should be calling `pumpCosmeticFilterQueues` straight). + queueIsSleeping = false + // tslint:disable-next-line:no-use-before-declare + pumpCosmeticFilterQueuesOnIdle() + }, pumpIntervalMinMs) + } + } + + const pumpCosmeticFilterQueuesOnIdle = idleize( + pumpCosmeticFilterQueues, + pumpIntervalMaxMs + ); + + if (!window.observingHasStarted) { + window.observingHasStarted = true; + window.requestIdleCallback(function ({ didTimeout }) { + startObserving(); + }, { timeout: maxTimeMSBeforeStart }) + } else { + pumpCosmeticFilterQueuesOnIdle(); + } })(); diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js b/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js deleted file mode 100644 index 030a477e9ed1..000000000000 --- a/components/cosmetic_filters/resources/data/cosmetic_filters_pump.js +++ /dev/null @@ -1,366 +0,0 @@ -/* Copyright (c) 2020 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/. */ - -(function() { - const { parseDomain, ParseResultType } = require('parse-domain') - const pumpIntervalMinMs = 40 - const pumpIntervalMaxMs = 1000; - const maxWorkSize = 60; - let queueIsSleeping = false; - // The cutoff for text ads. If something has only text in it, it needs to have - // this many, or more, characters. Similarly, require it to have a non-trivial - // number of words in it, to look like an actual text ad. - const minAdTextChars = 30; - const minAdTextWords = 5; - - /** - * Provides a new function which can only be scheduled once at a time. - * - * @param onIdle function to run when the thread is less busy - * @param timeout max time to wait. at or after this time the function will be run regardless of thread noise - */ - const idleize = (onIdle, timeout) => { - let idleId = undefined; - return function WillRunOnIdle () { - if (idleId !== undefined) { - return; - } - idleId = window.requestIdleCallback(() => { - idleId = undefined; - onIdle(); - }, { timeout }) - } - } - - const _parseDomainCache = Object.create(null); - const getParsedDomain = (aDomain) => { - const cacheResult = _parseDomainCache[aDomain]; - if (cacheResult !== undefined) { - return cacheResult; - } - - const newResult = parseDomain(aDomain); - _parseDomainCache[aDomain] = newResult; - console.log('aDomain == ' + aDomain); - return newResult; - } - - const isRelativeUrl = (url) => { - return ( - !url.startsWith('//') && - !url.startsWith('http://') && - !url.startsWith('https://') - ) - } - - const _parsedCurrentDomain = getParsedDomain(window.location.host) - const isFirstPartyUrl = (url) => { - if (isRelativeUrl(url)) { - return true - } - - const parsedTargetDomain = getParsedDomain(url) - - if (parsedTargetDomain.type !== _parsedCurrentDomain.type) { - return false - } - - if (parsedTargetDomain.type === ParseResultType.Listed) { - const isSameEtldP1 = (_parsedCurrentDomain.icann.topLevelDomains === parsedTargetDomain.icann.topLevelDomains && - _parsedCurrentDomain.icann.domain === parsedTargetDomain.icann.domain) - return isSameEtldP1 - } - - const looksLikePrivateOrigin = - [ParseResultType.NotListed, ParseResultType.Ip, ParseResultType.Reserved].includes(parsedTargetDomain.type) - if (looksLikePrivateOrigin) { - return _parsedCurrentDomain.hostname === parsedTargetDomain.hostname - } - - return false - } - - const isHTMLElement = (node) => { - return ('innerText' in node) - } - - const asHTMLElement = (node) => { - return isHTMLElement(node) ? node : null - } - - const isTextAd = (text) => { - const trimmedText = text.trim() - if (trimmedText.length < minAdTextChars) { - return false - } - if (trimmedText.split(' ').length < minAdTextWords) { - return false - } - return true - } - - /** - * Determine whether a subtree should be considered as "first party" content. - * - * Uses the following process in making this determination. - * - If the subtree contains any first party resources, the subtree is 1p. - * - If the subtree contains no remote resources, the subtree is first party. - * - Otherwise, its 3rd party. - * - * Note that any instances of "url(" or escape characters in style attributes - * are automatically treated as third-party URLs. These patterns and special - * cases were generated from looking at patterns in ads with resources in the - * style attribute. - * - * Similarly, an empty srcdoc attribute is also considered 3p, since many - * third party ads clear this attribute in practice. - * - * Finally, special case some ids we know are used only for third party ads. - */ - const isSubTreeFirstParty = (elm, possibleQueryResult) => { - let queryResult; - let isTopLevel; - - if (possibleQueryResult) { - queryResult = possibleQueryResult; - isTopLevel = false; - } else { - queryResult = { - foundFirstPartyResource: false, - foundThirdPartyResource: false, - foundKnownThirdPartyAd: false - }; - isTopLevel = true; - } - - if (elm.getAttribute) { - if (elm.hasAttribute('id')) { - const elmId = elm.getAttribute('id'); - if (elmId.startsWith('google_ads_iframe_') || - elmId.startsWith('div-gpt-ad') || - elmId.startsWith('adfox_')) { - queryResult.foundKnownThirdPartyAd = true; - return false; - } - } - - if (elm.hasAttribute('src')) { - const elmSrc = elm.getAttribute('src'); - const elmSrcIsFirstParty = isFirstPartyUrl(elmSrc); - if (elmSrcIsFirstParty === true) { - queryResult.foundFirstPartyResource = true; - return true; - } - queryResult.foundThirdPartyResource = true; - } - - if (elm.hasAttribute('style')) { - const elmStyle = elm.getAttribute('style'); - if (elmStyle.includes('url(') || - elmStyle.includes('//')) { - queryResult.foundThirdPartyResource = true; - } - } - - if (elm.hasAttribute('srcdoc')) { - const elmSrcDoc = elm.getAttribute('srcdoc'); - if (elmSrcDoc.trim() === '') { - queryResult.foundThirdPartyResource = true; - } - } - } - - if (elm.firstChild) { - isSubTreeFirstParty(elm.firstChild, queryResult) - if (queryResult.foundKnownThirdPartyAd === true) { - return false - } - if (queryResult.foundFirstPartyResource === true) { - return true - } - } - - if (elm.nextSibling) { - isSubTreeFirstParty(elm.nextSibling, queryResult) - if (queryResult.foundKnownThirdPartyAd === true) { - return false - } - if (queryResult.foundFirstPartyResource === true) { - return true - } - } - - if (isTopLevel === false) { - return (queryResult.foundThirdPartyResource === false) - } - - if (queryResult.foundThirdPartyResource) { - return false - } - - const htmlElement = asHTMLElement(elm) - // Check for several things here: - // 1. If its not an HTML node (i.e. its a text node), then its definitely - // not the root of first party ad (we'd have caught that it was a text - // add when checking the text node's parent). - // 2. If it's a script node, then similarly, its definitely not the root - // of a first party ad on the page. - // 3. Last, check the text content on the page. If the node contains a - // non-trivial amount of text in it, then we _should_ treat it as a - // possible 1p ad. - if (!htmlElement || - htmlElement.tagName.toLowerCase() === 'script' || - isTextAd(htmlElement.innerText) === false) { - return false - } - - return true - } - - const unhideSelectors = (selectors) => { - if (selectors.size === 0) { - return - } - // Find selectors we have a rule index for - const rulesToRemove = Array.from(selectors) - .map(selector => window.allSelectorsToRules.get(selector)) - .filter(i => i !== undefined) - .sort() - .reverse() - // Delete the rules - let lastIdx = window.allSelectorsToRules.size - 1 - for (const ruleIdx of rulesToRemove) { - // Safe to asset ruleIdx is a number because we've already filtered out - // any `undefined` instances with the filter call above. - window.cosmeticStyleSheet.deleteRule(ruleIdx) - } - // Re-sync the indexes - // TODO: Sync is hard, just re-build by iterating through the StyleSheet rules. - const ruleLookup = Array.from(window.allSelectorsToRules.entries()) - let countAtLastHighest = rulesToRemove.length - for (let i = lastIdx; i > 0; i--) { - const [selector, oldIdx] = ruleLookup[i] - // Is this one we removed? - if (rulesToRemove.includes(i)) { - window.allSelectorsToRules.delete(selector) - countAtLastHighest-- - if (countAtLastHighest === 0) { - break - } - continue - } - if (oldIdx !== i) { - // Probably out of sync - console.error('Cosmetic Filters: old index did not match lookup index', { selector, oldIdx, i }) - } - window.allSelectorsToRules.set(selector, oldIdx - countAtLastHighest) - } - } - - /** - * Go through each of the 3 queues, only take maxWorkSize items from each one - * 1. Take maxWorkSize selects from the first queue with any items - * 2. Determine partyness of matched element: - * - If any are 3rd party, keep 'hide' rule and check again later in next queue. - * - If any are 1st party, remove 'hide' rule and never check selector again. - * 3. If we're looking at the 3rd queue, don't requeue any selectors. - */ - const pumpCosmeticFilterQueues = () => { - if (queueIsSleeping === true) { - return; - } - - let didPumpAnything = false - // For each "pump", walk through each queue until we find selectors - // to evaluate. This means that nothing in queue N+1 will be evaluated - // until queue N is completely empty. - for (let queueIndex = 0; queueIndex < window.numQueues; queueIndex += 1) { - const currentQueue = window.allQueues[queueIndex]; - const nextQueue = window.allQueues[queueIndex + 1]; - if (currentQueue.size === 0) { - continue; - } - - const currentWorkLoad = Array.from(currentQueue.values()).slice(0, maxWorkSize); - const comboSelector = currentWorkLoad.join(','); - const matchingElms = document.querySelectorAll(comboSelector); - // Will hold selectors identified by _this_ queue pumping, that were - // newly identified to be matching 1p content. Will be sent to - // the background script to do the un-hiding. - const newlyIdentifiedFirstPartySelectors = new Set(); - - for (const aMatchingElm of matchingElms) { - // Don't recheck elements / subtrees we already know are first party. - // Once we know something is third party, we never need to evaluate it - // again. - if (window.alreadyKnownFirstPartySubtrees.has(aMatchingElm)) { - continue; - } - - const elmSubtreeIsFirstParty = isSubTreeFirstParty(aMatchingElm); - // If we find that a subtree is third party, then no need to change - // anything, leave the selector as "hiding" and move on. - // This element will likely be checked again on the next 'pump' - // as long as another element from the selector does not match 1st party. - if (elmSubtreeIsFirstParty === false) { - continue; - } - // Otherwise, we know that the given subtree was evaluated to be - // first party, so we need to figure out which selector from the combo - // selector did the matching. - for (const selector of currentWorkLoad) { - if (aMatchingElm.matches(selector) === false) { - continue - } - - // Similarly, if we already know a selector matches 1p content, - // there is no need to notify the background script again, so - // we don't need to consider further. - if (window.alreadyUnhiddenSelectors.has(selector) === true) { - continue - } - - newlyIdentifiedFirstPartySelectors.add(selector) - window.alreadyUnhiddenSelectors.add(selector) - } - window.alreadyKnownFirstPartySubtrees.add(aMatchingElm) - } - - unhideSelectors(newlyIdentifiedFirstPartySelectors) - - for (const aUsedSelector of currentWorkLoad) { - currentQueue.delete(aUsedSelector) - // Don't requeue selectors we know identify first party content. - const selectorMatchedFirstParty = newlyIdentifiedFirstPartySelectors.has(aUsedSelector) - if (nextQueue && selectorMatchedFirstParty === false) { - nextQueue.add(aUsedSelector) - } - } - - didPumpAnything = true - // If we did something, process the next queue, save it for next time. - break - } - - if (didPumpAnything) { - queueIsSleeping = true - window.setTimeout(() => { - // Set this to false now even though there's a gap in time between now and - // idle since all other calls to `pumpCosmeticFilterQueuesOnIdle` that occur during this time - // will be ignored (and nothing else should be calling `pumpCosmeticFilterQueues` straight). - queueIsSleeping = false - // tslint:disable-next-line:no-use-before-declare - pumpCosmeticFilterQueuesOnIdle() - }, pumpIntervalMinMs) - } - } - - const pumpCosmeticFilterQueuesOnIdle = idleize( - pumpCosmeticFilterQueues, - pumpIntervalMaxMs - ); - - pumpCosmeticFilterQueuesOnIdle(); -})(); diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd b/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd index ec77028bcb02..5446dc0d6093 100644 --- a/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd +++ b/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd @@ -8,8 +8,7 @@ - - + From cd595d1227004336d2a65df2d5d9582806121077 Mon Sep 17 00:00:00 2001 From: Serg Date: Fri, 4 Dec 2020 12:07:22 -0500 Subject: [PATCH 12/45] creates webpack bundle from js --- brave_paks.gni | 2 -- browser/BUILD.gn | 7 +++++-- .../brave_cosmetic_resources_tab_helper.cc | 4 ++-- browser/resources/resource_ids | 2 +- browser/sources.gni | 14 +++++++++++++ .../content/renderer/BUILD.gn | 1 + .../cosmetic_filters/resources/BUILD.gn | 12 ----------- .../resources/cosmetic_filters_resources.grd | 14 ------------- .../cosmetic_filters/resources/data/BUILD.gn | 20 +++++++++++-------- .../data/cosmetic_filters_resources.grd | 14 ------------- components/resources/BUILD.gn | 2 ++ content/BUILD.gn | 1 - content/public/browser/BUILD.gn | 13 ------------ patches/content-public-browser-BUILD.gn.patch | 4 ++-- 14 files changed, 39 insertions(+), 71 deletions(-) delete mode 100644 components/cosmetic_filters/resources/BUILD.gn delete mode 100644 components/cosmetic_filters/resources/cosmetic_filters_resources.grd delete mode 100644 components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd delete mode 100644 content/public/browser/BUILD.gn diff --git a/brave_paks.gni b/brave_paks.gni index 1be9e77b2776..b0870eb69743 100644 --- a/brave_paks.gni +++ b/brave_paks.gni @@ -59,7 +59,6 @@ template("brave_extra_paks") { output = "${invoker.output_dir}/brave_resources.pak" sources = [ "$root_gen_dir/components/brave_components_resources.pak", - "$root_gen_dir/brave/components/cosmetic_filters/resources/cosmetic_filters_resources.pak", "$root_gen_dir/brave/ui/webui/resources/brave_webui_resources.pak", ] @@ -73,7 +72,6 @@ template("brave_extra_paks") { deps = [ "//brave/components/resources", - "//brave/components/cosmetic_filters/resources", "//brave/ui/webui/resources", ] diff --git a/browser/BUILD.gn b/browser/BUILD.gn index 0f1a78276cbc..7f22116e8f1b 100644 --- a/browser/BUILD.gn +++ b/browser/BUILD.gn @@ -140,7 +140,7 @@ source_set("browser_process") { "//brave/components/brave_wayback_machine:buildflags", "//brave/components/brave_webtorrent/browser/buildflags", "//brave/components/content_settings/core/browser", - "//brave/components/cosmetic_filters/resources", + "//brave/components/cosmetic_filters/resources/data:generated_resources", "//brave/components/crypto_dot_com/browser/buildflags", "//brave/components/gemini/browser/buildflags", "//brave/components/greaselion/browser/buildflags", @@ -154,7 +154,6 @@ source_set("browser_process") { "//brave/components/tor/buildflags", "//brave/components/weekly_storage", "//brave/content/browser/mojom", - "//brave/content/public/browser:browser", "//brave/services/network/public/cpp", "//brave/ui/brave_ads", "//brave/ui/brave_ads/public/cpp", @@ -194,6 +193,10 @@ source_set("browser_process") { "//third_party/widevine/cdm:buildflags", "//ui/base", ] + if (is_component_build) { + sources += brave_content_public_browser_sources + deps += brave_content_public_browser_deps + } if (brave_wallet_enabled) { deps += [ diff --git a/browser/brave_cosmetic_resources_tab_helper.cc b/browser/brave_cosmetic_resources_tab_helper.cc index d35e996d43df..b444ff4c42ca 100644 --- a/browser/brave_cosmetic_resources_tab_helper.cc +++ b/browser/brave_cosmetic_resources_tab_helper.cc @@ -24,7 +24,7 @@ #include "content/public/browser/global_routing_id.h" #include "content/public/browser/navigation_handle.h" #include "content/public/renderer/render_frame.h" -#include "components/cosmetic_filters/resources/grit/cosmetic_filters_resources.h" +#include "brave/components/cosmetic_filters/resources/grit/cosmetic_filters_generated_map.h" #include "ui/base/resource/resource_bundle.h" std::vector @@ -169,7 +169,7 @@ BraveCosmeticResourcesTabHelper::BraveCosmeticResourcesTabHelper( enabled_1st_party_cf_filtering_(false) { if (BraveCosmeticResourcesTabHelper::observing_script_->empty()) { *BraveCosmeticResourcesTabHelper::observing_script_ = - LoadDataResource(IDR_COSMETIC_FILTERS_SCRIPT); + LoadDataResource(kCosmeticFiltersGenerated[0].value); } } diff --git a/browser/resources/resource_ids b/browser/resources/resource_ids index 73222c9234bd..27b87469a3c3 100644 --- a/browser/resources/resource_ids +++ b/browser/resources/resource_ids @@ -100,7 +100,7 @@ "<(ROOT_GEN_DIR)/brave/web-ui-ipfs/ipfs.grd": { "includes": [45500], }, - "brave/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd": { + "<(ROOT_GEN_DIR)/brave/web-ui-cosmetic_filters/cosmetic_filters.grd": { "includes": [46000] }, } diff --git a/browser/sources.gni b/browser/sources.gni index e6860abc311f..ddda60c977b3 100644 --- a/browser/sources.gni +++ b/browser/sources.gni @@ -27,3 +27,17 @@ brave_chrome_browser_public_deps = [ "//brave/components/brave_sync:constants", "//brave/components/variations:constants", ] + +brave_content_public_browser_sources = [ + "//brave/content/browser/cosmetic_filters_communication_impl.cc", + "//brave/content/browser/cosmetic_filters_communication_impl.h", + "//brave/content/browser/cosmetic_filters_observer.h", + "//brave/content/public/browser/brave_render_frame_host.cc", +] + +brave_content_public_browser_deps = [ + "//base", + "//brave/content/browser/mojom", + "//skia", + "//third_party/blink/public:blink_headers", +] diff --git a/components/cosmetic_filters/content/renderer/BUILD.gn b/components/cosmetic_filters/content/renderer/BUILD.gn index 24eaaeab3f95..d7b74733daa8 100644 --- a/components/cosmetic_filters/content/renderer/BUILD.gn +++ b/components/cosmetic_filters/content/renderer/BUILD.gn @@ -17,6 +17,7 @@ source_set("renderer") { deps = [ "//base", + "//brave/content/browser/mojom", "//content/public/renderer", "//gin", "//mojo/public/cpp/bindings", diff --git a/components/cosmetic_filters/resources/BUILD.gn b/components/cosmetic_filters/resources/BUILD.gn deleted file mode 100644 index fab2614d9b14..000000000000 --- a/components/cosmetic_filters/resources/BUILD.gn +++ /dev/null @@ -1,12 +0,0 @@ -import("//tools/grit/repack.gni") - -repack("resources") { - output = "$root_gen_dir/brave/components/cosmetic_filters/resources/cosmetic_filters_resources.pak" - sources = [ - "$root_gen_dir/components/cosmetic_filters/resources/cosmetic_filters_resources.pak", - ] - - deps = [ - "data:resources_cf", - ] -} diff --git a/components/cosmetic_filters/resources/cosmetic_filters_resources.grd b/components/cosmetic_filters/resources/cosmetic_filters_resources.grd deleted file mode 100644 index 236413c4eb04..000000000000 --- a/components/cosmetic_filters/resources/cosmetic_filters_resources.grd +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/components/cosmetic_filters/resources/data/BUILD.gn b/components/cosmetic_filters/resources/data/BUILD.gn index 467fb3b6ad61..037466be4018 100644 --- a/components/cosmetic_filters/resources/data/BUILD.gn +++ b/components/cosmetic_filters/resources/data/BUILD.gn @@ -1,15 +1,19 @@ import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") +import("//brave/components/common/typescript.gni") -grit("resources_cf") { - source = "cosmetic_filters_resources.grd" - - outputs = [ - "grit/cosmetic_filters_resources.h", - "cosmetic_filters_resources.pak", +transpile_web_ui("cosmetic_filters_resources") { + entry_points = [ + ["cosmetic_filters", rebase_path("cosmetic_filters.js")] ] - resource_ids = "//brave/browser/resources/resource_ids" + resource_name = "cosmetic_filters" +} - output_dir = "$root_gen_dir/components/cosmetic_filters/resources" +pack_web_resources("generated_resources") { + resource_name = "cosmetic_filters" + output_dir = "$root_gen_dir/brave/components/cosmetic_filters/resources" + deps = [ + ":cosmetic_filters_resources" + ] } diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd b/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd deleted file mode 100644 index 5446dc0d6093..000000000000 --- a/components/cosmetic_filters/resources/data/cosmetic_filters_resources.grd +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/components/resources/BUILD.gn b/components/resources/BUILD.gn index b629e19c155f..7bf646c26861 100644 --- a/components/resources/BUILD.gn +++ b/components/resources/BUILD.gn @@ -61,12 +61,14 @@ repack("resources") { "//brave/components/brave_adblock_ui:generated_resources", "//brave/components/webcompat_reporter/ui:generated_resources", "//brave/components/brave_new_tab_ui:generated_resources", + "//brave/components/cosmetic_filters/resources/data:generated_resources", "//brave/components/brave_welcome_ui:generated_resources", ] sources = [ "$root_gen_dir/components/brave_components_static.pak", "$root_gen_dir/brave/components/brave_adblock/resources/brave_adblock_generated.pak", + "$root_gen_dir/brave/components/cosmetic_filters/resources/cosmetic_filters_generated.pak", "$root_gen_dir/brave/components/webcompat_reporter/resources/webcompat_reporter_generated.pak", "$root_gen_dir/brave/components/brave_new_tab/resources/brave_new_tab_generated.pak", "$root_gen_dir/brave/components/brave_welcome/resources/brave_welcome_generated.pak", diff --git a/content/BUILD.gn b/content/BUILD.gn index f2cbea8f9c1a..cc923ca14341 100644 --- a/content/BUILD.gn +++ b/content/BUILD.gn @@ -17,7 +17,6 @@ source_set("browser") { deps = [ "//base", - "//content", "//content/public/browser", "//brave/ui/webui/resources", "//ui/base", diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn deleted file mode 100644 index c22f6b03f7fb..000000000000 --- a/content/public/browser/BUILD.gn +++ /dev/null @@ -1,13 +0,0 @@ -source_set("browser") { - sources = [ - "//brave/content/browser/cosmetic_filters_communication_impl.cc", - "//brave/content/browser/cosmetic_filters_communication_impl.h", - "//brave/content/browser/cosmetic_filters_observer.h", - "//brave/content/public/browser/brave_render_frame_host.cc", - ] - deps = [ - "//base", - "//brave/content/browser/mojom", - "//skia", - ] -} diff --git a/patches/content-public-browser-BUILD.gn.patch b/patches/content-public-browser-BUILD.gn.patch index 78b29605a00f..003487011183 100644 --- a/patches/content-public-browser-BUILD.gn.patch +++ b/patches/content-public-browser-BUILD.gn.patch @@ -1,12 +1,12 @@ diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn -index bd83dfa0a32658c5b45ca001bfd04cc051d8bc73..48d08aefda3e696d897b8e73a4a853a52f88aa27 100644 +index bd83dfa0a32658c5b45ca001bfd04cc051d8bc73..655081a2772722e240e553b33a1c89acaa693e4e 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn @@ -491,6 +491,7 @@ source_set("browser_sources") { "//ui/shell_dialogs", "//ui/surface", ] -+ deps += ["//brave/content/public/browser:browser",] ++ sources += brave_content_public_browser_sources deps += brave_content_public_browser_deps allow_circular_includes_from = [ # This target is a pair with content/browser. They always go together and From 45ebea5b6182a9e97895d3368c4a54d79c84f285 Mon Sep 17 00:00:00 2001 From: Serg Date: Thu, 17 Dec 2020 11:51:02 -0500 Subject: [PATCH 13/45] optimizes JS size that we pass to a web page --- .../brave_cosmetic_resources_tab_helper.cc | 80 ++++++++++--------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/browser/brave_cosmetic_resources_tab_helper.cc b/browser/brave_cosmetic_resources_tab_helper.cc index b444ff4c42ca..8542258ecbb6 100644 --- a/browser/brave_cosmetic_resources_tab_helper.cc +++ b/browser/brave_cosmetic_resources_tab_helper.cc @@ -233,29 +233,30 @@ void BraveCosmeticResourcesTabHelper::CSSRulesRoutine( } else { std::string cosmeticFilterConsiderNewSelectors_script = "(function() {" - "let nextIndex = window.cosmeticStyleSheet.rules.length;"; + "let nextIndex = window.cosmeticStyleSheet.rules.length;" + "const selectors = ["; for (size_t i = 0; i < hide_selectors_list->GetSize(); i++) { - std::string rule = hide_selectors_list->GetList()[i].GetString() + - "{display:none !important;}"; - cosmeticFilterConsiderNewSelectors_script += - "if (!window.allSelectorsToRules.has(`" + - hide_selectors_list->GetList()[i].GetString() + "`)) {" - "window.cosmeticStyleSheet.insertRule(`" + rule + - "`, nextIndex);" - "window.allSelectorsToRules.set(`" + - hide_selectors_list->GetList()[i].GetString() + - "`, nextIndex);" - "nextIndex++;" - "window.firstRunQueue.add(`" + - hide_selectors_list->GetList()[i].GetString() + "`);" - "}"; + cosmeticFilterConsiderNewSelectors_script += "`" + + hide_selectors_list->GetList()[i].GetString() + "`"; + if (i != hide_selectors_list->GetSize() - 1) { + cosmeticFilterConsiderNewSelectors_script += ","; + } } - cosmeticFilterConsiderNewSelectors_script += + cosmeticFilterConsiderNewSelectors_script += "];" + "selectors.forEach(selector => {" + "if (!window.allSelectorsToRules.has(selector)) {" + "window.cosmeticStyleSheet.insertRule(selector + " + "`{display:none !important;}`, nextIndex);" + "window.allSelectorsToRules.set(selector, nextIndex);" + "nextIndex++;" + "window.firstRunQueue.add(selector);" + "}" + "});" "if (!document.adoptedStyleSheets.includes(" "window.cosmeticStyleSheet)){" "document.adoptedStyleSheets = [window.cosmeticStyleSheet];" - "};"; - cosmeticFilterConsiderNewSelectors_script += "})();"; + "};" + "})();"; if (hide_selectors_list->GetSize() != 0) { auto* frame_host = content::RenderFrameHost::FromID(frame_id); if (!frame_host) @@ -345,7 +346,8 @@ void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( } else { std::string cosmeticFilterConsiderNewSelectors_script = "(function() {" - "let nextIndex = window.cosmeticStyleSheet.rules.length;"; + "let nextIndex = window.cosmeticStyleSheet.rules.length;" + "const selectors = ["; bool execute_script = false; for (size_t i = 0; i < selectors->GetSize(); i++) { base::ListValue* selectors_list = nullptr; @@ -354,30 +356,30 @@ void BraveCosmeticResourcesTabHelper::GetHiddenClassIdSelectorsOnUI( continue; } for (size_t j = 0; j < selectors_list->GetSize(); j++) { - std::string rule = selectors_list->GetList()[i].GetString() + - "{display:none !important;}"; - cosmeticFilterConsiderNewSelectors_script += - "if (!window.allSelectorsToRules.has(`" + - selectors_list->GetList()[i].GetString() + "`)) {" - "window.cosmeticStyleSheet.insertRule(`" + rule + - "`,nextIndex);" - "window.allSelectorsToRules.set(`" + - selectors_list->GetList()[i].GetString() + - "`, nextIndex);" - "nextIndex++;" - "window.firstRunQueue.add(`" + - selectors_list->GetList()[i].GetString() + "`);" - "}"; + cosmeticFilterConsiderNewSelectors_script += "`" + + selectors_list->GetList()[i].GetString() + "`"; + if (i != selectors_list->GetSize() - 1) { + cosmeticFilterConsiderNewSelectors_script += ","; + } execute_script = true; } } if (execute_script) { - cosmeticFilterConsiderNewSelectors_script += - "if (!document.adoptedStyleSheets.includes(" - "window.cosmeticStyleSheet)){" - "document.adoptedStyleSheets = [window.cosmeticStyleSheet];" - "};"; - cosmeticFilterConsiderNewSelectors_script += "})();"; + cosmeticFilterConsiderNewSelectors_script += "];" + "selectors.forEach(selector => {" + "if (!window.allSelectorsToRules.has(selector)) {" + "window.cosmeticStyleSheet.insertRule(selector + " + "`{display:none !important;}`, nextIndex);" + "window.allSelectorsToRules.set(selector, nextIndex);" + "nextIndex++;" + "window.firstRunQueue.add(selector);" + "}" + "});" + "if (!document.adoptedStyleSheets.includes(" + "window.cosmeticStyleSheet)){" + "document.adoptedStyleSheets = [window.cosmeticStyleSheet];" + "};" + "})();"; auto* frame_host = content::RenderFrameHost::FromID(frame_id); if (!frame_host) return; From c7cf63c48e32b155c44772d8db4c0137204c47ea Mon Sep 17 00:00:00 2001 From: Serg Date: Fri, 18 Dec 2020 09:59:18 -0500 Subject: [PATCH 14/45] fixes generichide browser test --- .../brave_cosmetic_resources_tab_helper.cc | 58 +++++++++++++------ .../resources/data/cosmetic_filters.js | 37 ++++++++++-- .../cosmetic_filters_communication_impl.cc | 10 +++- .../cosmetic_filters_communication_impl.h | 3 +- 4 files changed, 83 insertions(+), 25 deletions(-) diff --git a/browser/brave_cosmetic_resources_tab_helper.cc b/browser/brave_cosmetic_resources_tab_helper.cc index 8542258ecbb6..2fd9db02de3c 100644 --- a/browser/brave_cosmetic_resources_tab_helper.cc +++ b/browser/brave_cosmetic_resources_tab_helper.cc @@ -190,15 +190,52 @@ void BraveCosmeticResourcesTabHelper::GetUrlCosmeticResourcesOnUI( } std::string to_inject; resources_dict->GetString("injected_script", &to_inject); + auto* frame_host = content::RenderFrameHost::FromID(frame_id); + if (!frame_host) + return; + if (do_non_scriplets) { + Profile* profile = Profile::FromBrowserContext( + web_contents()->GetBrowserContext()); + enabled_1st_party_cf_filtering_ = + brave_shields::IsFirstPartyCosmeticFilteringEnabled( + HostContentSettingsMapFactory::GetForProfile(profile), + GURL(url)); + bool generichide = false; + resources_dict->GetBoolean("generichide", &generichide); + std::string pre_init_script = + "(function() {" + "if (window.hide1pContent === undefined) {" + "window.hide1pContent = "; + if (enabled_1st_party_cf_filtering_) { + pre_init_script += "true"; + } else { + pre_init_script += "false"; + } + pre_init_script += ";" + "}" + "if (window.generichide === undefined) {" + "window.generichide = "; + if (generichide) { + pre_init_script += "true"; + } else { + pre_init_script += "false"; + } + pre_init_script += ";" + "}" + "})();"; + frame_host->ExecuteJavaScriptInIsolatedWorld( + base::UTF8ToUTF16(pre_init_script), + base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); + frame_host->ExecuteJavaScriptInIsolatedWorld( + base::UTF8ToUTF16(*BraveCosmeticResourcesTabHelper::observing_script_), + base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); + } if (to_inject.length() > 1) { - auto* frame_host = content::RenderFrameHost::FromID(frame_id); - if (!frame_host) - return; frame_host->ExecuteJavaScriptInIsolatedWorld( base::UTF8ToUTF16(to_inject), base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); } - // Working on css rules + // Working on css rules, we do that on a main frame only if (!do_non_scriplets) return; CSSRulesRoutine(url, resources_dict, frame_id); @@ -214,11 +251,6 @@ void BraveCosmeticResourcesTabHelper::CSSRulesRoutine( return; } - Profile* profile = Profile::FromBrowserContext( - web_contents()->GetBrowserContext()); - enabled_1st_party_cf_filtering_ = - brave_shields::IsFirstPartyCosmeticFilteringEnabled( - HostContentSettingsMapFactory::GetForProfile(profile), url); base::ListValue* cf_exceptions_list; if (resources_dict->GetList("exceptions", &cf_exceptions_list)) { for (size_t i = 0; i < cf_exceptions_list->GetSize(); i++) { @@ -418,14 +450,6 @@ void BraveCosmeticResourcesTabHelper::ProcessURL( render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID()), url.spec(), do_non_scriplets)); - if (!do_non_scriplets) - return; - // Non-scriptlet cosmetic filters are only applied on the top-level frame - if (web_contents()->GetMainFrame()) { - web_contents()->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld( - base::UTF8ToUTF16(*BraveCosmeticResourcesTabHelper::observing_script_), - base::NullCallback(), ISOLATED_WORLD_ID_CHROME_INTERNAL); - } } void BraveCosmeticResourcesTabHelper::DidFinishNavigation( diff --git a/components/cosmetic_filters/resources/data/cosmetic_filters.js b/components/cosmetic_filters/resources/data/cosmetic_filters.js index 834ff68221de..3e8e30dc252b 100644 --- a/components/cosmetic_filters/resources/data/cosmetic_filters.js +++ b/components/cosmetic_filters/resources/data/cosmetic_filters.js @@ -58,6 +58,12 @@ if (window.observingHasStarted === undefined) { window.observingHasStarted = false; } + if (window._hasDelayOcurred === undefined) { + window._hasDelayOcurred = false; + } + if (window._startCheckingId === undefined) { + window._startCheckingId = 0; + } const fetchNewClassIdRules = function () { if ((!notYetQueriedClasses || notYetQueriedClasses.length === 0) && @@ -503,12 +509,35 @@ pumpIntervalMaxMs ); + const scheduleQueuePump = (hide1pContent, generichide) => { + // Three states possible here. First, the delay has already occurred. If so, + // pass through to pumpCosmeticFilterQueues immediately. + if (_hasDelayOcurred === true) { + pumpCosmeticFilterQueuesOnIdle() + return + } + // Second possibility is that we're already waiting for the delay to pass / + // occur. In this case, do nothing. + if (_startCheckingId !== 0) { + return + } + // Third / final possibility, this is this the first time this has been + // called, in which case set up a timmer and quit + _startCheckingId = window.requestIdleCallback(function ({ didTimeout }) { + _hasDelayOcurred = true + if (!generichide) { + startObserving() + } + if (!hide1pContent) { + pumpCosmeticFilterQueuesOnIdle() + } + }, { timeout: maxTimeMSBeforeStart }) + } + if (!window.observingHasStarted) { window.observingHasStarted = true; - window.requestIdleCallback(function ({ didTimeout }) { - startObserving(); - }, { timeout: maxTimeMSBeforeStart }) + scheduleQueuePump(window.hide1pContent, window.generichide); } else { - pumpCosmeticFilterQueuesOnIdle(); + scheduleQueuePump(false, false); } })(); diff --git a/content/browser/cosmetic_filters_communication_impl.cc b/content/browser/cosmetic_filters_communication_impl.cc index 90b1673831d7..355272d4895b 100644 --- a/content/browser/cosmetic_filters_communication_impl.cc +++ b/content/browser/cosmetic_filters_communication_impl.cc @@ -8,6 +8,7 @@ #include "base/json/json_reader.h" #include "brave/content/browser/cosmetic_filters_observer.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" namespace content { @@ -28,7 +29,9 @@ void CosmeticFiltersCommunicationImpl::CreateInstance( CosmeticFiltersCommunicationImpl::CosmeticFiltersCommunicationImpl( content::RenderFrameHost* render_frame_host, CosmeticFiltersObserver* cosmetic_filters_observer) - : render_frame_host_(render_frame_host), + : frame_id_(content::GlobalFrameRoutingId( + render_frame_host->GetProcess()->GetID(), + render_frame_host->GetRoutingID())), cosmetic_filters_observer_(cosmetic_filters_observer) { } @@ -73,8 +76,9 @@ void CosmeticFiltersCommunicationImpl::HiddenClassIdSelectors( ids.push_back(ids_list->GetList()[i].GetString()); } } - if (cosmetic_filters_observer_) { - cosmetic_filters_observer_->HiddenClassIdSelectors(render_frame_host_, + auto* frame_host = content::RenderFrameHost::FromID(frame_id_); + if (cosmetic_filters_observer_ && frame_host) { + cosmetic_filters_observer_->HiddenClassIdSelectors(frame_host, classes, ids); } } diff --git a/content/browser/cosmetic_filters_communication_impl.h b/content/browser/cosmetic_filters_communication_impl.h index 9cb20c38a002..973cbe35463a 100644 --- a/content/browser/cosmetic_filters_communication_impl.h +++ b/content/browser/cosmetic_filters_communication_impl.h @@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/values.h" +#include "content/public/browser/global_routing_id.h" #include "brave/content/browser/mojom/cosmetic_filters_communication.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" @@ -36,7 +37,7 @@ class CosmeticFiltersCommunicationImpl final void SetObserver(CosmeticFiltersObserver* cosmetic_filters_observer); private: - content::RenderFrameHost* render_frame_host_; + content::GlobalFrameRoutingId frame_id_; CosmeticFiltersObserver* cosmetic_filters_observer_; }; From 56e83f8cbcedbd0114e28830c718cefe1836d48b Mon Sep 17 00:00:00 2001 From: Serg Date: Mon, 4 Jan 2021 11:37:33 -0500 Subject: [PATCH 15/45] corrects stylesheet correction and injects scripts in a