Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/_locales/en/adnauseam.json
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@
"message": "SKIPPED: Clicking Disabled",
"description": "Menu & AdVault: SKIPPED: Clicking disabled"
},
"adnAdClickingStatusSkippedDomain": {
"message": "SKIPPED: Domain Exception",
"description": "Menu & AdVault: SKIPPED: Domain excluded from ad clicks"
},
"adnMenuViewLog": {
"message": "View Log",
"description": "appears in ADN popup menu"
Expand Down Expand Up @@ -451,6 +455,18 @@
"message": "Always",
"description": "English: Click Frequency - Always"
},
"clickExceptionsLabelExclude": {
"message": "Don't click ads on these domains (one per line)",
"description": "Label for click exceptions when clicking is enabled (exclusion mode)"
},
"clickExceptionsLabelInclude": {
"message": "Only click ads on these domains (one per line)",
"description": "Label for click exceptions when clicking is disabled (inclusion mode)"
},
"clickExceptionsPlaceholder": {
"message": "example.com",
"description": "Placeholder for click exceptions textarea"
},
"respectDNTPrompt": {
"message": "Make exceptions for non-tracking Ads",
"description": "English: Make exceptions for non-tracking Ads"
Expand Down
33 changes: 33 additions & 0 deletions src/css/settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,39 @@ input[type=range]:disabled::-moz-range-progress {
background: black;
}

/* Click exceptions expandable */
.clickExceptions-expander {
cursor: pointer;
}
.clickExceptions-expander .listExpander {
display: inline-block;
font-size: 14px;
color: var(--adn-blue);
fill: var(--adn-blue);
min-width: 16px;
}
.clickExceptions-expander .listExpander svg {
transform: rotate(90deg);
transform-origin: 50%;
width: 10px;
height: 10px;
transition: transform 0.2s;
}
.clickExceptions-expander.expanded .listExpander svg {
transform: rotate(180deg);
}
.clickExceptions-expander #clickingExceptions {
display: none;
width: 95%;
min-height: 80px;
margin-top: 6px;
font-size: var(--font-size-smaller);
resize: vertical;
}
.clickExceptions-expander.expanded #clickingExceptions {
display: block;
}

/* Mobile devices */
:root.mobile #localData {
max-width: 100vw;
Expand Down
24 changes: 23 additions & 1 deletion src/js/adn/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ const adnauseam = (function () {
// changes for #1657
//const pending = pendingAds();
const settings = µb.userSettings;
if (/*pending.length && */settings.clickingAds && !isAutomated()) { // no visits if automated
const hasClickInclusions = !settings.clickingAds && (settings.clickingExceptions || '').trim();
if (/*pending.length && */(settings.clickingAds || hasClickInclusions) && !isAutomated()) { // no visits if automated

// check whether an idle timeout has been specified
const idleMs = disableIdler ? 0 : settings.clickOnlyWhenIdleFor;
Expand Down Expand Up @@ -397,6 +398,22 @@ const adnauseam = (function () {
});
}

const isClickingAllowedOnDomain = function (domain) {
const exceptions = (µb.userSettings.clickingExceptions || '').trim();
if (!exceptions) return µb.userSettings.clickingAds;
const domains = exceptions.split(/\s+/).filter(Boolean);
const isInList = domains.some(function (d) {
return domain === d || domain.endsWith('.' + d);
});
if (µb.userSettings.clickingAds) {
// Toggle ON: list is exclusion (click everywhere except listed)
return !isInList;
} else {
// Toggle OFF: list is inclusion (only click on listed)
return isInList;
}
}

const visitPending = function (ad) {
let pending = ad && ad.attempts < maxAttemptsPerAd &&
ad.visitedTs <= 0 && !ad.dntAllowed && !ad.noVisit;
Expand Down Expand Up @@ -1786,6 +1803,11 @@ const adnauseam = (function () {
ad.noVisit = true;
ad.dntAllowed = true;
}
else if (!isClickingAllowedOnDomain(ad.pageDomain)) {
ad.noVisit = true;
ad.domainExcluded = true;
log('[SKIP] Domain excluded from ad clicks: ' + ad.pageDomain);
}
else {
ad.noVisit = Math.random() > µb.userSettings.clickProbability; // if true, ad will never be visited
}
Expand Down
4 changes: 3 additions & 1 deletion src/js/adn/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,9 @@ import { broadcast, onBroadcast } from '../broadcast.js';
}
} else if (status != "SkippedDisabled") {
if (ad.clickedByUser) status = "SkippedUser";
else status = "Skipped" + (ad.dntAllowed ? "DNT" : "Frequency");
else if (ad.dntAllowed) status = "SkippedDNT";
else if (ad.domainExcluded) status = "SkippedDomain";
else status = "SkippedFrequency";
}
return status;
}
Expand Down
34 changes: 34 additions & 0 deletions src/js/adn/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,17 @@ const onPreventDefault = function (ev) {
};
/******************************************************************************/

// Update the click exceptions label based on the clicking toggle state
const updateClickExceptionsLabel = function () {
const label = document.getElementById('clickExceptionsLabel');
if (!label) return;
const clickingEnabled = uDom('#clickingAds').prop('checked');
label.textContent = i18n$(clickingEnabled
? 'clickExceptionsLabelExclude'
: 'clickExceptionsLabelInclude'
);
}

// if any of 3 main toggles are off, disabled their subgroups
const updateGroupState = function () {

Expand All @@ -207,6 +218,12 @@ const updateGroupState = function () {
uDom('.clickingAds-child').prop('disabled', !uDom('#clickingAds').prop('checked'));
uDom('.clickingAds-child').parent().parent().parent().toggleClass('disabled', !uDom('#clickingAds').prop('checked'));

// Click exceptions textarea should never be disabled (used in both on/off states)
const clickExTextarea = document.getElementById('clickingExceptions');
if (clickExTextarea) clickExTextarea.disabled = false;

updateClickExceptionsLabel();

/*
blocking malware doesnt have any subgroup
uDom('.blockingMalware-child').prop('disabled', !uDom('#blockingMalware').prop('checked'));
Expand Down Expand Up @@ -320,6 +337,23 @@ const onUserSettingsReceived = function (details) {
.on('click', onPreventDefault);
});

// Click exceptions textarea
const clickExTextarea = document.getElementById('clickingExceptions');
if (clickExTextarea) {
clickExTextarea.value = details.clickingExceptions || '';
clickExTextarea.addEventListener('change', function () {
changeUserSettings('clickingExceptions', this.value);
});
}
// Expand/collapse click exceptions
const expander = document.querySelector('.clickExceptions-expander');
if (expander) {
expander.querySelector('label').addEventListener('click', function () {
expander.classList.toggle('expanded');
});
}
updateClickExceptionsLabel();

// disable warning
uDom('[data-setting-name="disableWarnings"]')
.on('change', onDisableWarningChanged)
Expand Down
3 changes: 2 additions & 1 deletion src/js/adn/vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,8 @@ function untilTime(adsets) {
function formatTargetDate(ad) {
const dntNote = i18n$('adnAllowedByDNT') + "<a class='help-mark dnt' href='https://github.com/dhowe/AdNauseam/wiki/FAQ#what-is-the-effs-do-not-track-standard-and-how-it-is-supported-in-adnauseam'> ? </a>", frequencyNote = i18n$('adnAdClickingStatusSkippedFrequency'), userNote = i18n$('adnAdClickingStatusSkippedUser');

return ad.noVisit ? (ad.clickedByUser ? userNote : (ad.dntAllowed ? dntNote : frequencyNote)) : formatDate(ad.visitedTs);
const domainNote = i18n$('adnAdClickingStatusSkippedDomain');
return ad.noVisit ? (ad.clickedByUser ? userNote : (ad.dntAllowed ? dntNote : (ad.domainExcluded ? domainNote : frequencyNote))) : formatDate(ad.visitedTs);
}

function formatDate(ts) {
Expand Down
1 change: 1 addition & 0 deletions src/js/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ const userSettingsDefault = {
blurCollectedAds: false,
hideDeadAds: false,

clickingExceptions: '', // ADN: newline-separated domain list for per-site click control
clickOnlyWhenIdleFor: 0,
noIncomingCookies: true,
noOutgoingCookies: false,
Expand Down
9 changes: 9 additions & 0 deletions src/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@
</div>
</div>
</div>
<div>
<div class="clickExceptions-expander">
<label>
<span class="fa-icon listExpander"><svg class="fa-icon_angle-up" viewBox="0 0 998 582"><path d="m 998,499 q 0,13 -10,23 l -50,50 q -10,10 -23,10 -13,0 -23,-10 L 499,179 106,572 Q 96,582 83,582 70,582 60,572 L 10,522 Q 0,512 0,499 0,486 10,476 L 476,10 q 10,-10 23,-10 13,0 23,10 l 466,466 q 10,10 10,23 z"></path></svg></span>
<span id="clickExceptionsLabel" data-i18n="clickExceptionsLabelExclude"></span>
</label>
<textarea id="clickingExceptions" dir="ltr" spellcheck="false" data-i18n-placeholder="clickExceptionsPlaceholder"></textarea>
</div>
</div>
</div>
</li>

Expand Down