From 64bea278814bedb9a81c05687fad0ac5751fd522 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Tue, 8 Jan 2019 07:37:50 -0500 Subject: [PATCH] Add ability to control auto-commenting at filter creation time Related issues: - https://github.com/uBlockOrigin/uBlock-issues/issues/372 - https://github.com/gorhill/uBlock/issues/93 A new advanced settings has been added: `autoCommentFilterTemplate`. Default value is `{{date}} {{origin}}`. Placeholders are identified by `{{...}}`. There are currently only three placeholders supported: - `{{date}}`: will be replaced with current date - `{{time}}`: will be replaced with current time - `{{origin}}`: will be replaced with site information on which the filter(s) was created If no placeholder is found in `autoCommentFilterTemplate`, this will disable auto-commenting. So one can use `-` to disable auto-commenting. Additionally, if auto-commenting is enabled, uBO will not emit a comment if an emitted comment would be a duplicate of the last one found in the user filter list. --- src/js/background.js | 1 + src/js/logger-ui.js | 5 ++-- src/js/messaging.js | 20 +++++++-------- src/js/scriptlets/element-picker.js | 7 +++--- src/js/storage.js | 39 +++++++++++++++++++++++++---- 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/js/background.js b/src/js/background.js index 86f1cd16a..8f4a70a93 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -40,6 +40,7 @@ const µBlock = (function() { // jshint ignore:line const hiddenSettingsDefault = { assetFetchTimeout: 30, + autoCommentFilterTemplate: '{{date}} {{origin}}', autoUpdateAssetFetchPeriod: 120, autoUpdatePeriod: 7, cacheStorageCompression: true, diff --git a/src/js/logger-ui.js b/src/js/logger-ui.js index 00a5d1034..f0db8fca6 100644 --- a/src/js/logger-ui.js +++ b/src/js/logger-ui.js @@ -882,13 +882,14 @@ var netFilteringManager = (function() { } createdStaticFilters[value] = true; if ( value !== '' ) { - var d = new Date(); messaging.send( 'loggerUI', { what: 'createUserFilter', + autoComment: true, + filters: value, + origin: targetPageDomain, pageDomain: targetPageDomain, - filters: '! ' + d.toLocaleString() + ' ' + targetPageDomain + '\n' + value } ); } diff --git a/src/js/messaging.js b/src/js/messaging.js index 63473e960..0f5d0e9a2 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -52,7 +52,7 @@ var getDomainNames = function(targets) { /******************************************************************************/ -var onMessage = function(request, sender, callback) { +const onMessage = function(request, sender, callback) { // Async switch ( request.what ) { case 'getAssetContent': @@ -84,7 +84,7 @@ var onMessage = function(request, sender, callback) { break; } - var tabId = sender && sender.tab ? sender.tab.id : 0; + const tabId = sender && sender.tab ? sender.tab.id : 0; // Sync var response; @@ -103,7 +103,7 @@ var onMessage = function(request, sender, callback) { break; case 'createUserFilter': - µb.appendUserFilters(request.filters); + µb.appendUserFilters(request.filters, request); // https://github.com/gorhill/uBlock/issues/1786 µb.cosmeticFilteringEngine.removeFromSelectorCache(request.pageDomain); break; @@ -608,15 +608,13 @@ vAPI.messaging.listen('contentscript', onMessage); /******************************************************************************/ -var µb = µBlock; +const onMessage = function(request, sender, callback) { + const µb = µBlock; -/******************************************************************************/ - -var onMessage = function(request, sender, callback) { // Async switch ( request.what ) { case 'elementPickerArguments': - var xhr = new XMLHttpRequest(); + const xhr = new XMLHttpRequest(); xhr.open('GET', 'epicker.html', true); xhr.overrideMimeType('text/html;charset=utf-8'); xhr.responseType = 'text'; @@ -632,8 +630,8 @@ var onMessage = function(request, sender, callback) { cosmeticFilters: vAPI.i18n('pickerCosmeticFilters'), cosmeticFiltersHint: vAPI.i18n('pickerCosmeticFiltersHint') }; - var reStrings = /\{\{(\w+)\}\}/g; - var replacer = function(a0, string) { + const reStrings = /\{\{(\w+)\}\}/g; + const replacer = function(a0, string) { return i18n[string]; }; @@ -657,7 +655,7 @@ var onMessage = function(request, sender, callback) { } // Sync - var response; + let response; switch ( request.what ) { case 'elementPickerEprom': diff --git a/src/js/scriptlets/element-picker.js b/src/js/scriptlets/element-picker.js index 3651e74e9..f4bf4b8cc 100644 --- a/src/js/scriptlets/element-picker.js +++ b/src/js/scriptlets/element-picker.js @@ -1144,7 +1144,7 @@ var filterChoiceFromEvent = function(ev) { /******************************************************************************/ -var onDialogClicked = function(ev) { +const onDialogClicked = function(ev) { if ( ev.isTrusted === false ) { return; } // If the dialog is hidden, clicking on it force it to become visible. @@ -1163,12 +1163,13 @@ var onDialogClicked = function(ev) { filterToDOMInterface.preview(false); userFilterFromCandidate(function(filter) { if ( !filter ) { return; } - var d = new Date(); vAPI.messaging.send( 'elementPicker', { what: 'createUserFilter', - filters: '! ' + d.toLocaleString() + ' ' + window.location.href + '\n' + filter, + autoComment: true, + filters: filter, + origin: window.location.origin, pageDomain: window.location.hostname } ); diff --git a/src/js/storage.js b/src/js/storage.js index 9bc873428..c02bf557e 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -404,9 +404,27 @@ /******************************************************************************/ -µBlock.appendUserFilters = function(filters) { +µBlock.appendUserFilters = function(filters, options) { + filters = filters.trim(); if ( filters.length === 0 ) { return; } + // https://github.com/uBlockOrigin/uBlock-issues/issues/372 + // Auto comment using user-defined template. + let comment = ''; + if ( + options instanceof Object && + options.autoComment === true && + this.hiddenSettings.autoCommentFilterTemplate.indexOf('{{') !== -1 + ) { + const d = new Date(); + comment = + '! ' + + this.hiddenSettings.autoCommentFilterTemplate + .replace('{{date}}', d.toLocaleDateString()) + .replace('{{time}}', d.toLocaleTimeString()) + .replace('{{origin}}', options.origin); + } + const onSaved = ( ) => { const compiledFilters = this.compileFilters( filters, @@ -435,11 +453,22 @@ const onLoaded = details => { if ( details.error ) { return; } + // The comment, if any, will be applied if and only if it is different + // from the last comment found in the user filter list. + if ( comment !== '' ) { + const pos = details.content.lastIndexOf(comment); + if ( + pos === -1 || + details.content.indexOf('\n!', pos + 1) !== -1 + ) { + filters = '\n' + comment + '\n' + filters; + } + } // https://github.com/chrisaljoudi/uBlock/issues/976 - // If we reached this point, the filter quite probably needs to be - // added for sure: do not try to be too smart, trying to avoid - // duplicates at this point may lead to more issues. - this.saveUserFilters(details.content.trim() + '\n\n' + filters.trim(), onSaved); + // If we reached this point, the filter quite probably needs to be + // added for sure: do not try to be too smart, trying to avoid + // duplicates at this point may lead to more issues. + this.saveUserFilters(details.content.trim() + '\n' + filters, onSaved); }; this.loadUserFilters(onLoaded);