Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Implement cosmetic filtering #3303

Merged
merged 9 commits into from Dec 14, 2019
Prev

store generic rule exceptions in the Shields Panel state

  • Loading branch information
antonok-edm committed Dec 11, 2019
commit ec80ce731925f251cc26c4de6f03f44e9e03f4af
@@ -138,6 +138,23 @@ export const shieldsReady: actions.ShieldsReady = () => {
}
}

export const generateClassIdStylesheet = (tabId: number, classes: string[], ids: string[]) => {
return {
type: types.GENERATE_CLASS_ID_STYLESHEET,
tabId,
classes,
ids
}
}

export const cosmeticFilterRuleExceptions = (tabId: number, exceptions: string[]) => {
return {
type: types.COSMETIC_FILTER_RULE_EXCEPTIONS,
tabId,
exceptions
}
}

export const contentScriptsLoaded: actions.ContentScriptsLoaded = (tabId: number, url: string) => {
return {
type: types.CONTENT_SCRIPTS_LOADED,
@@ -2,6 +2,8 @@
* 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 generateCosmeticBlockingStylesheet = (hideSelectors: string[], styleSelectors: any) => {
let stylesheet = ''
if (hideSelectors.length > 0) {
@@ -18,6 +20,16 @@ const generateCosmeticBlockingStylesheet = (hideSelectors: string[], styleSelect
return stylesheet
}

export const injectClassIdStylesheet = (tabId: number, classes: string[], ids: string[], exceptions: string[]) => {
chrome.braveShields.classIdStylesheet(classes, ids, exceptions, stylesheet => {
chrome.tabs.insertCSS(tabId, {
code: stylesheet,
cssOrigin: 'user',
runAt: 'document_start'
})
})
}

export const addSiteCosmeticFilter = async (origin: string, cssfilter: string) => {
chrome.storage.local.get('cosmeticFilterList', (storeData = {}) => {
let storeList = Object.assign({}, storeData.cosmeticFilterList)
@@ -54,17 +66,14 @@ export const applyAdblockCosmeticFilters = (tabId: number, hostname: string) =>
})
}

chrome.tabs.sendMessage(tabId, {
type: 'cosmeticFilterGenericExceptions',
exceptions: resources.exceptions
})

if (resources.injected_script) {
chrome.tabs.executeScript(tabId, {
code: resources.injected_script,
runAt: 'document_start'
})
}

shieldsPanelActions.cosmeticFilterRuleExceptions(tabId, resources.exceptions)
})
}

@@ -51,13 +51,15 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
break
}
case 'classIdStylesheet': {
chrome.braveShields.classIdStylesheet(msg.classes, msg.ids, msg.exceptions, stylesheet => {
chrome.tabs.insertCSS({
code: stylesheet,
cssOrigin: 'user',
runAt: 'document_start'
})
})
const tab = sender.tab
if (tab === undefined) {
break
}
const tabId = tab.id
if (tabId === undefined) {
break
}
shieldsPanelActions.generateClassIdStylesheet(tabId, msg.classes, msg.ids)
break
}
case 'contentScriptsLoaded': {
@@ -34,6 +34,7 @@ import {
} from '../api/shieldsAPI'
import { reloadTab } from '../api/tabsAPI'
import {
injectClassIdStylesheet,
applyAdblockCosmeticFilters,
applyCSSCosmeticFilters
} from '../api/cosmeticFilterAPI'
@@ -346,6 +347,31 @@ 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

// setTimeout is used to prevent injectClassIdStylesheet from calling
// another Redux function immediately
setTimeout(() => injectClassIdStylesheet(action.tabId, action.classes, action.ids, exceptions), 0)
break
}
case shieldsPanelTypes.COSMETIC_FILTER_RULE_EXCEPTIONS: {
const tabData = state.tabs[action.tabId]
if (!tabData) {
console.error('Active tab not found')
break
}
state = shieldsPanelState.saveCosmeticFilterRuleExceptions(state, action.tabId, action.exceptions)
chrome.tabs.sendMessage(action.tabId, {
type: 'cosmeticFilterGenericExceptions'
})
break
}
case shieldsPanelTypes.CONTENT_SCRIPTS_LOADED: {
const tabData = state.tabs[action.tabId]
if (!tabData) {
@@ -20,4 +20,6 @@ export const SET_FINAL_SCRIPTS_BLOCKED_ONCE_STATE = 'SET_FINAL_SCRIPTS_BLOCKED_O
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'
@@ -1,5 +1,3 @@
let genericExceptions: Array<string> | undefined = undefined

const queriedIds = new Set()
const queriedClasses = new Set()
const regexWhitespace = /\s/
@@ -45,8 +43,7 @@ const handleNewNodes = (newNodes: Element[]) => {
chrome.runtime.sendMessage({
type: 'classIdStylesheet',
classes,
ids,
exceptions: genericExceptions
ids
})
}

@@ -72,8 +69,6 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
const action = typeof msg === 'string' ? msg : msg.type
switch (action) {
case 'cosmeticFilterGenericExceptions': {
genericExceptions = msg.exceptions

let allNodes = Array.from(document.querySelectorAll('[id],[class]'))
handleNewNodes(allNodes)
applyCosmeticFilterMutationObserver()
@@ -112,6 +112,12 @@ export const updateResourceBlocked: shieldState.UpdateResourceBlocked = (state,
return { ...state, tabs }
}

export const saveCosmeticFilterRuleExceptions: shieldState.SaveCosmeticFilterRuleExceptions = (state, tabId, exceptions) => {
const tabs: shieldState.Tabs = { ...state.tabs }
tabs[tabId] = { ...tabs[tabId], ...{ cosmeticFilters: { ...tabs[tabId].cosmeticFilters, ruleExceptions: exceptions } } }
return { ...state, tabs }
}

export const resetBlockingStats: shieldState.ResetBlockingStats = (state, tabId) => {
const tabs: shieldState.Tabs = { ...state.tabs }
tabs[tabId] = { ...tabs[tabId], ...{ adsBlocked: 0, trackersBlocked: 0, httpsRedirected: 0, javascriptBlocked: 0, fingerprintingBlocked: 0 } }
@@ -173,6 +173,27 @@ export interface ShieldsReady {
(): ShieldsReadyReturn
}

interface GenerateClassIdStylesheetReturn {
type: types.GENERATE_CLASS_ID_STYLESHEET,
tabId: number,
classes: string[],
ids: string[]
}

export interface GenerateClassIdStylesheet {
(tabId: number, classes: string[], ids: string[]): GenerateClassIdStylesheetReturn
}

interface CosmeticFilterRuleExceptionsReturn {
type: types.COSMETIC_FILTER_RULE_EXCEPTIONS,
tabId: number,
exceptions: string[]
}

export interface CosmeticFilterRuleExceptions {
(tabId: number, exceptions: string[]): CosmeticFilterRuleExceptionsReturn
}

interface ContentScriptsLoadedReturn {
type: types.CONTENT_SCRIPTS_LOADED,
tabId: number,
@@ -201,4 +222,6 @@ export type shieldPanelActions =
SetFinalScriptsBlockedStateReturn |
SetAdvancedViewFirstAccessReturn |
ShieldsReadyReturn |
GenerateClassIdStylesheetReturn |
CosmeticFilterRuleExceptionsReturn |
ContentScriptsLoadedReturn
@@ -6,3 +6,7 @@ export type BlockTypes = 'ads' | 'trackers' | 'httpUpgradableResources' | 'javas
export type BlockOptions = 'allow' | 'block'
export type BlockFPOptions = 'allow' | 'block' | 'block_third_party'
export type BlockCookiesOptions = 'allow' | 'block' | 'block_third_party'

export interface CosmeticFilteringState {
ruleExceptions: Array<string>
}
@@ -22,4 +22,6 @@ export type SET_FINAL_SCRIPTS_BLOCKED_ONCE_STATE = typeof types.SET_FINAL_SCRIPT
export type SET_ADVANCED_VIEW_FIRST_ACCESS = typeof types.SET_ADVANCED_VIEW_FIRST_ACCESS
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
@@ -3,6 +3,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */

import { BlockOptions, BlockTypes, BlockFPOptions, BlockCookiesOptions } from '../other/blockTypes'
import { CosmeticFilteringState } from '../adblock/adblockTypes'
import { NoScriptInfo } from '../other/noScriptInfo'

export interface Tab {
@@ -29,6 +30,7 @@ export interface Tab {
trackersBlockedResources: Array<string>
httpsRedirectedResources: Array<string>
fingerprintingBlockedResources: Array<string>
cosmeticFilters: CosmeticFilteringState
}

export interface Tabs {
@@ -86,6 +88,10 @@ export interface UpdateResourceBlocked {
(state: State, tabId: number, blockType: BlockTypes, subresource: string): State
}

export interface SaveCosmeticFilterRuleExceptions {
(state: State, tabId: number, exceptions: Array<string>): State
}

export interface ResetBlockingStats {
(state: State, tabId: number): State
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.