diff --git a/browser/about_flags.cc b/browser/about_flags.cc index 071c5b85a281..cbdbb1af599c 100644 --- a/browser/about_flags.cc +++ b/browser/about_flags.cc @@ -522,6 +522,16 @@ FEATURE_VALUE_TYPE(brave_shields::features:: \ kBraveAdblockMobileNotificationsListDefault), \ }, \ + { \ + "brave-adblock-scriptlet-debug-logs", \ + "Enable debug logging for scriptlet injections", \ + "Enable console debugging for scriptlets injected by cosmetic " \ + "filtering, exposing additional information that can be useful for " \ + "filter authors.", \ + kOsDesktop, \ + FEATURE_VALUE_TYPE( \ + brave_shields::features::kBraveAdblockScriptletDebugLogs), \ + }, \ { \ "brave-dark-mode-block", \ "Enable dark mode blocking fingerprinting protection", \ diff --git a/browser/brave_shields/ad_block_service_browsertest.cc b/browser/brave_shields/ad_block_service_browsertest.cc index c8d032223cfd..845ced0f3813 100644 --- a/browser/brave_shields/ad_block_service_browsertest.cc +++ b/browser/brave_shields/ad_block_service_browsertest.cc @@ -87,6 +87,7 @@ using brave_shields::features::kBraveAdblockCollapseBlockedElements; using brave_shields::features::kBraveAdblockCookieListDefault; using brave_shields::features::kBraveAdblockCosmeticFiltering; using brave_shields::features::kBraveAdblockDefault1pBlocking; +using brave_shields::features::kBraveAdblockScriptletDebugLogs; using brave_shields::features::kCosmeticFilteringJsPerformance; AdBlockServiceTest::AdBlockServiceTest() @@ -2255,6 +2256,47 @@ IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CosmeticFilteringWindowScriptlet) { EXPECT_EQ(base::Value(true), result.value); } +class ScriptletDebugLogsFlagEnabledTest : public AdBlockServiceTest { + public: + ScriptletDebugLogsFlagEnabledTest() { + feature_list_.InitAndEnableFeature(kBraveAdblockScriptletDebugLogs); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +// Test that scriptlet injection has access to `canDebug` inside of +// `scriptletGlobals`, and that it is set to `true`. +IN_PROC_BROWSER_TEST_F(ScriptletDebugLogsFlagEnabledTest, CanDebugSetToTrue) { + ASSERT_TRUE(InstallDefaultAdBlockExtension()); + std::string scriptlet = + "(function() {" + " if (scriptletGlobals.get('canDebug')) {" + " window.success = true;" + " }" + "})();"; + std::string scriptlet_base64; + base::Base64Encode(scriptlet, &scriptlet_base64); + UpdateAdBlockInstanceWithRules( + "b.com##+js(debuggable)", + "[{" + "\"name\": \"debuggable\"," + "\"aliases\": []," + "\"kind\": {\"mime\": \"application/javascript\"}," + "\"content\": \"" + + scriptlet_base64 + "\"}]"); + + GURL tab_url = + embedded_test_server()->GetURL("b.com", "/cosmetic_filtering.html"); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), tab_url)); + + content::WebContents* contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + EXPECT_EQ(true, EvalJs(contents, R"(window.success)")); +} + // Test scriptlet injection with DeAMP enabled IN_PROC_BROWSER_TEST_F(AdBlockServiceTest, CheckForDeAmpPref) { std::string scriptlet = diff --git a/components/brave_shields/common/features.cc b/components/brave_shields/common/features.cc index 8e6319d9a16a..e217175176ad 100644 --- a/components/brave_shields/common/features.cc +++ b/components/brave_shields/common/features.cc @@ -41,6 +41,9 @@ BASE_FEATURE(kBraveAdblockCookieListOptIn, BASE_FEATURE(kBraveAdblockCosmeticFiltering, "BraveAdblockCosmeticFiltering", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kBraveAdblockScriptletDebugLogs, + "BraveAdblockScriptletDebugLogs", + base::FEATURE_DISABLED_BY_DEFAULT); BASE_FEATURE(kBraveAdblockCspRules, "BraveAdblockCspRules", base::FEATURE_ENABLED_BY_DEFAULT); diff --git a/components/brave_shields/common/features.h b/components/brave_shields/common/features.h index 18f62c38acf2..23bd615d0d9c 100644 --- a/components/brave_shields/common/features.h +++ b/components/brave_shields/common/features.h @@ -21,6 +21,7 @@ BASE_DECLARE_FEATURE(kBraveAdblockCookieListOptIn); BASE_DECLARE_FEATURE(kBraveAdblockCosmeticFiltering); BASE_DECLARE_FEATURE(kBraveAdblockCspRules); BASE_DECLARE_FEATURE(kBraveAdblockMobileNotificationsListDefault); +BASE_DECLARE_FEATURE(kBraveAdblockScriptletDebugLogs); BASE_DECLARE_FEATURE(kBraveDomainBlock); BASE_DECLARE_FEATURE(kBraveDomainBlock1PES); BASE_DECLARE_FEATURE(kBraveExtensionNetworkBlocking); diff --git a/components/cosmetic_filters/renderer/cosmetic_filters_js_handler.cc b/components/cosmetic_filters/renderer/cosmetic_filters_js_handler.cc index c9dc589e0204..a1797065bdfd 100644 --- a/components/cosmetic_filters/renderer/cosmetic_filters_js_handler.cc +++ b/components/cosmetic_filters/renderer/cosmetic_filters_js_handler.cc @@ -45,7 +45,7 @@ const char kObservingScriptletEntryPoint[] = const char kScriptletInitScript[] = R"((function() { - let text = '(function() {\nconst scriptletGlobals = new Map();\nlet deAmpEnabled = %s;\n' + %s + '})()'; + let text = '(function() {\nconst scriptletGlobals = new Map(%s);\nlet deAmpEnabled = %s;\n' + %s + '})()'; let script; try { script = document.createElement('script'); @@ -411,11 +411,16 @@ void CosmeticFiltersJSHandler::ApplyRules(bool de_amp_enabled) { std::string scriptlet_script; base::Value* injected_script = resources_dict_->Find("injected_script"); + if (injected_script && base::JSONWriter::Write(*injected_script, &scriptlet_script)) { - scriptlet_script = base::StringPrintf(kScriptletInitScript, - de_amp_enabled ? "true" : "false", - scriptlet_script.c_str()); + const bool scriptlet_debug_enabled = base::FeatureList::IsEnabled( + brave_shields::features::kBraveAdblockScriptletDebugLogs); + + scriptlet_script = base::StringPrintf( + kScriptletInitScript, + scriptlet_debug_enabled ? "[[\"canDebug\", true]]" : "", + de_amp_enabled ? "true" : "false", scriptlet_script.c_str()); } if (!scriptlet_script.empty()) { web_frame->ExecuteScriptInIsolatedWorld(