Compare commits

...

9 commits
v1.0 ... master

13 changed files with 487 additions and 322 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.kdev4/
*.kdev4

View file

@ -1,5 +1,10 @@
# Unchecker
[![Version on addons.mozilla.org](https://img.shields.io/amo/v/unchecker?logo=Firefox)](https://addons.mozilla.org/en-US/firefox/addon/unchecker/)
[![Rating on addons.mozilla.org](https://img.shields.io/amo/rating/unchecker)](https://addons.mozilla.org/en-US/firefox/addon/unchecker/reviews/)
<a href="https://addons.mozilla.org/en-US/firefox/addon/unchecker/"><img src="https://dev.ad5001.eu/img/badges/en/amo.svg" width="300"></img></a>
GDPR introduced many new privacy standards around the world, but it seems like that some providers requires you to untick a lot of checkboxes to protect your privacy atleast a little more.
Although this is illegal, a lot of companies uses theses techniques as opt-out from advertising and data-collections. This also only apply to European users, so international ones are still subject to unfair opt-outs.
@ -10,6 +15,10 @@ This extension is rather simple and allows you to check or uncheck all your chec
One button and no more checkboxes ticked.
This extension also features another functionality for websites that do not use checkboxes, but buttons instead: the "Click all similar buttons" feature.
![Image of unchecker's context menu](https://apps.ad5001.eu/img/en/unchecker/contextmenu.png)
By using this feature on an "Off" or "Disable" button, it click all buttons with the same label, similar to how all checkboxes are unticked when using the normal button.
## "I've seen an issue"
If you have any issue (like a website not working), don't hesitate to create an issue on https://github.com/Ad5001/unchecker/issues
If you have any issue (like a website not working), don't hesitate to create an issue on https://git.ad5001.eu/Ad5001/unchecker/issues

View file

@ -1,90 +0,0 @@
const UNCHK_SCRIPT = `
function disable_checkboxes(element){
document.body.querySelectorAll('input[type="checkbox"]').forEach(function(el){
el.checked = false
})
}
disable_checkboxes(document.body)
document.body.querySelectorAll('iframe').forEach(function(el){disable_checkboxes(el.contentDocument || el.contentWindow.document)})
`
const CHK_SCRIPT = `
function check_checkboxes(element){
document.body.querySelectorAll('input[type="checkbox"]').forEach(function(el){
el.checked = true
})
}
check_checkboxes(document.body)
document.body.querySelectorAll('iframe').forEach(function(el){check_checkboxes(el.contentDocument || el.contentWindow.document)})
`
const TITLE_APPLY = "Uncheck all checkboxes";
const TITLE_REMOVE = "Check all checkboxes";
const APPLICABLE_PROTOCOLS = ["http:", "https:"];
/*
Toggle Script: based on the current title, insert or remove the Script.
Update the page action's title and icon to reflect its state.
*/
function toggleScript(tab) {
function gotTitle(title) {
if (title === TITLE_APPLY) {
browser.browserAction.setIcon({tabId: tab.id, path: "icons/off.svg"});
browser.browserAction.setTitle({tabId: tab.id, title: TITLE_REMOVE});
browser.tabs.executeScript({
code: UNCHK_SCRIPT
});
} else {
browser.browserAction.setIcon({tabId: tab.id, path: "icons/on.svg"});
browser.browserAction.setTitle({tabId: tab.id, title: TITLE_APPLY});
browser.tabs.executeScript({
code: CHK_SCRIPT
});
}
}
var gettingTitle = browser.browserAction.getTitle({tabId: tab.id});
gettingTitle.then(gotTitle);
}
/*
Returns true only if the URL's protocol is in APPLICABLE_PROTOCOLS.
*/
function protocolIsApplicable(url) {
var anchor = document.createElement('a');
anchor.href = url;
return APPLICABLE_PROTOCOLS.includes(anchor.protocol);
}
/*
Initialize the page action: set icon and title, then show.
Only operates on tabs whose URL's protocol is applicable.
*/
function initializebrowserAction(tab) {
if (protocolIsApplicable(tab.url)) {
browser.browserAction.setIcon({tabId: tab.id, path: "icons/on.svg"});
browser.browserAction.setTitle({tabId: tab.id, title: TITLE_APPLY});
browser.browserAction.show(tab.id);
}
}
/*
When first loaded, initialize the page action for all tabs.
*/
var gettingAllTabs = browser.tabs.query({});
gettingAllTabs.then((tabs) => {
for (let tab of tabs) {
initializebrowserAction(tab);
}
});
/*
Each time a tab is updated, reset the page action for that tab.
*/
browser.tabs.onUpdated.addListener((id, changeInfo, tab) => {
initializebrowserAction(tab);
});
/*
Toggle Script when the page action is clicked.
*/
browser.browserAction.onClicked.addListener(toggleScript);

75
clickall.js Normal file
View file

@ -0,0 +1,75 @@
/**
* Unchecker - Simple extension letting you uncheck all checkboxes on a page
* Copyright (c) Ad5001 2021-2023
*
* 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/.
**/
// This file handles all clicking automaticly all similar buttons (e.g : same text & element name)
const clickAllScript = (targetElementId) => {
let bound, selectedElements, clickedButton, buttonText, classes, query, sameElements
// Get the potential selected button
bound = browser.menus.getTargetElement(targetElementId).getBoundingClientRect()
selectedElements = document.elementsFromPoint(bound.x+bound.width/2, bound.y+bound.height/2)
// Leftover debug for positioning
//console.log(bound, browser.menus.getTargetElement(targetElementId), selectedElements)
//var div = document.createElement("div"); div.style.background = "black"; div.style.position = "absolute";
//div.style.left = bound.x+bound.width/2-5 +"px"; div.style.top = bound.y+bound.height/2-5 + "px";
//div.style.width = "10px"; div.style.height = "10px";
//document.body.appendChild(div);
selectedElements = selectedElements.filter(x => ["BUTTON","A","INPUT"].indexOf(x.tagName) > -1)
// If a button is selected
if(selectedElements.length > 0) {
clickedButton = selectedElements[0]
// Gather element that will be used in similar buttons (same text content).
buttonText = clickedButton.textContent.trim()
// Find the similar buttons
query = clickedButton.localName + (clickedButton.tagName == "INPUT" ? "[type=" + clickedButton.type + "]" : "")
sameElements = document.querySelectorAll(query)
sameElements = Array.from(sameElements).filter(btn => btn.textContent.trim() == buttonText)
// Click them automaticly.
sameElements.forEach(btn => {
btn.click()
})
}
}
// Requires targetElementId to be defined beforehands
const CLICK_ALL_TITLE = "Click all similar buttons"
const CLICK_ALL_MENU_CONTEXTS = ["all"]
function clickAllSimilarButtons(info, tab) {
browser.scripting.executeScript({
target: {
tabId: tab.id,
frameIds: [ info.frameId ],
},
func: clickAllScript,
args: [ info.targetElementId ]
})
}
/**
* Creating menu.
*/
if(browser.menus) { // Not supported on Firefox for Android
browser.menus.create({
id: "unchecker-clickall",
title: CLICK_ALL_TITLE,
icons: {
"16": "icons/click.svg",
"32": "icons/click.svg"
},
contexts: CLICK_ALL_MENU_CONTEXTS,
});
browser.menus.onClicked.addListener((info, tab) => {
if(info.menuItemId == "unchecker-clickall")
clickAllSimilarButtons(info, tab)
})
}

10
icons/click.svg Normal file
View file

@ -0,0 +1,10 @@
<svg id="SVGRoot" width="32" height="32" version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g fill="#808080">
<path d="m15.78 7.583 16 12.279-6.78 1.138 4.256 8.676-3.902 1.907-4.281-8.758-5.293 4.581z"/>
<g fill-rule="evenodd" stroke-width="1.8898">
<path d="m0 3v12s0 3 3 3h9v-4h-6s-2 0-2-2v-6c0-2 2-2 2-2h20c2 0 2 2 2 2v6l4 3.1172v-12.117c0-3-3-3-3-3h-26s-3 0-3 3z"/>
<path d="m0 19h4s0 2 2 2h6v4h-8c-4 0-4-4-4-4z"/>
<path d="m0 26h4s0 2 2 2h6v4h-8c-4 0-4-4-4-4z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 523 B

BIN
icons/off.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -1,100 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="20px"
version="1.1"
viewBox="0 0 20 20"
width="20px"
id="svg12"
sodipodi:docname="off.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata16">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1008"
id="namedview14"
showgrid="false"
inkscape:zoom="16"
inkscape:cx="16.458466"
inkscape:cy="9.7844187"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg12"
inkscape:measure-start="0,0"
inkscape:measure-end="0,0" />
<desc
id="desc4" />
<defs
id="defs6" />
<g
id="Page-1"
transform="matrix(0.5,0,0,0.5,0,5)"
style="fill:#333333;fill-rule:evenodd;stroke:none;stroke-width:1">
<g
id="Core"
transform="translate(-170,-86)"
style="fill:#333333">
<g
id="check-circle-outline-blank"
transform="translate(170,86)"
style="fill:#333333">
<path
d="M 10,0 C 4.5,0 0,4.5 0,10 0,15.5 4.5,20 10,20 15.5,20 20,15.5 20,10 20,4.5 15.5,0 10,0 Z m 0.0078,17 C 5.6078125,17 3.0054175,14.4 3.0054175,10 3.0054175,5.6 5.6,3 10,3 c 4.4,0 8,2.6 8,7 0,4.4 -3.592187,7 -7.992187,7 z"
id="Shape"
inkscape:connector-curvature="0"
style="fill:#333333"
sodipodi:nodetypes="ssssssssss" />
</g>
</g>
</g>
<rect
style="fill:#333333;stroke-width:1.14508271"
id="rect3724"
width="10"
height="1.4978296"
x="5"
y="5" />
<path
id="Shape-3"
style="fill:#333333;fill-rule:evenodd;stroke:none;stroke-width:0.5"
d="m 15,5 c -1.017755,0 -1.962173,0.3127537 -2.75,0.84375 0.06776,-0.00146 0.135653,-0.00264 0.203125,-0.00391 0.07613,-0.00143 0.150419,-0.00252 0.226563,-0.00195 0.107746,0.00134 0.215832,0.013662 0.322265,0.029297 0.05838,0.00958 0.116918,0.017699 0.175781,0.023437 0.03789,0.00358 0.07532,0.00511 0.113282,0.00781 0.580099,0.04116 0.886095,0.3036967 0.978515,0.59375 0.0069,-0.00202 0.0044,-0.00987 0.01367,-0.00977 0.0087,9.5e-5 0.01863,4.569e-4 0.02734,0 0.01238,-7.539e-4 0.02471,-0.00151 0.03711,-0.00195 0.01247,-7.873e-4 0.02467,-7.906e-4 0.03711,-0.00195 0.01191,-0.00129 0.02325,-0.00269 0.03516,-0.00391 0.01032,-0.00105 0.0209,-0.00131 0.03125,-0.00195 0.0094,-5.48e-4 0.01993,-0.00162 0.0293,-0.00195 0.0077,-2.774e-4 0.01376,1.611e-4 0.02148,0 0.0069,-1.759e-4 0.01459,-0.0014 0.02149,-0.00195 0.0088,-6.666e-4 0.01848,4.1e-4 0.02734,0 0.0089,-1.831e-4 0.01652,-0.00124 0.02539,-0.00195 0.0096,-7.737e-4 0.01964,-0.00142 0.0293,-0.00195 0.0087,-4.687e-4 0.01669,-0.00172 0.02539,-0.00195 0.01071,-2.653e-4 0.02248,1.18e-4 0.0332,0 0.01016,-1.074e-4 0.02109,6.47e-5 0.03125,0 0.0083,-4.83e-5 0.01518,3.37e-5 0.02344,0 h 0.0078 c 0.03112,-1.145e-4 0.04211,0.011967 0.04297,0.025391 0.0032,4.11e-5 0.0063,8.44e-5 0.0098,0 0.0067,-2.785e-4 0.01282,-6.63e-4 0.01953,0 0.0073,1.893e-4 0.01461,0.00413 0.02148,0.00586 0.002,6.216e-4 0.0039,0.00162 0.0059,0.00195 0.0091,-0.00812 0.0092,-0.021484 0.0293,-0.021484 h 0.02344 0.0039 c 0.01171,0 0.01082,0.00813 0.01758,0.011719 0.0082,-0.00404 0.0064,-0.013672 0.01953,-0.013672 h 0.01758 0.01563 c 0.02707,0 0.035,0.014347 0.04102,0.027344 0.002,-4.51e-5 0.0039,0 0.0059,0 2.2,0 3.498047,1.3 3.498047,3.5 0,2.2 -1.301953,3.5 -3.501953,3.5 -0.0027,0 -0.0052,7.3e-5 -0.0078,0 -0.0081,0.0091 -0.01029,0.02096 -0.03125,0.02148 -0.0095,2.39e-4 -0.01786,-4.07e-4 -0.02734,0 -0.0083,3.76e-4 -0.01709,0.0012 -0.02539,0.002 -0.0084,7.66e-4 -0.0071,-0.0066 -0.01367,-0.0078 -0.0059,6.91e-4 -0.01163,0.0016 -0.01758,0.002 -0.0086,6.27e-4 -0.01673,0.0021 -0.02539,0.002 h -0.02344 -0.02539 -0.02734 -0.02734 -0.02344 c -0.0024,0 -0.0017,-0.0018 -0.0039,-0.002 -0.132239,0.349342 -1.840827,0.622525 -0.816406,0.992188 -0.01305,-0.0033 -0.03016,-0.0066 -0.04492,-0.0098 -0.0065,-0.0014 -0.0069,7.6e-5 -0.01172,-0.002 0.0093,-0.0011 0.007,-5.28e-4 -0.01367,-0.002 -0.03387,-0.0018 -0.0677,-0.0039 -0.101562,-0.0059 -0.01115,-6.69e-4 -0.02205,-0.0013 -0.0332,-0.002 -0.07846,-0.0052 -0.156196,-0.01103 -0.234374,-0.01953 -0.09564,-0.01086 -0.190534,-0.02318 -0.285157,-0.04102 -0.118534,-0.02245 -0.236979,-0.04664 -0.353515,-0.07813 -0.101479,-0.02835 -0.20318,-0.05719 -0.302735,-0.0918 -0.07283,-0.0246 -0.147154,-0.04915 -0.216797,-0.08203 -0.03706,-0.01699 -0.07384,-0.03472 -0.111328,-0.05078 C 12.993489,14.675558 13.959976,15 15,15 c 2.75,0 5,-2.25 5,-5 0,-2.75 -2.25,-5 -5,-5 z m -2.625,7.710938 c 0.0015,0.0029 0.0044,0.0049 0.0059,0.0078 0.0072,0.0031 0.01426,0.0066 0.02149,0.0098 -0.0088,-0.0062 -0.01858,-0.01128 -0.02734,-0.01758 z" />
<rect
style="fill:#333333;stroke-width:1.14615846"
id="rect3724-6"
width="10"
height="1.5006453"
x="5"
y="13.5" />
<circle
style="fill:#333333;stroke-width:1.42857134"
id="path3807"
cx="5"
cy="10"
r="5" />
<svg width="20px" height="20px" version="1.1" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="m5 5c-2.77 0-5 2.23-5 5s2.23 5 5 5h10c2.77 0 5-2.23 5-5s-2.23-5-5-5h-10zm0 2h10c1.662 0 3 1.338 3 3s-1.338 3-3 3h-10c-1.662 0-3-1.338-3-3s1.338-3 3-3z" fill="#808080" fill-rule="evenodd" stroke-width="1.8898"/>
<rect y="5" width="10" height="10" ry="5" fill="#808080" fill-rule="evenodd" stroke-width="2.0692"/>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 432 B

View file

@ -1,104 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="20px"
version="1.1"
viewBox="0 0 20 20"
width="20px"
id="svg12"
sodipodi:docname="on.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata16">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1008"
id="namedview14"
showgrid="false"
inkscape:zoom="16"
inkscape:cx="16.458466"
inkscape:cy="9.7844187"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg12"
inkscape:measure-start="0,0"
inkscape:measure-end="0,0" />
<desc
id="desc4" />
<defs
id="defs6" />
<g
id="Page-1"
transform="matrix(-0.5,0,0,0.5,20,5)"
style="fill:#333333;fill-rule:evenodd;stroke:none;stroke-width:1">
<g
id="Core"
transform="translate(-170,-86)"
style="fill:#333333">
<g
id="check-circle-outline-blank"
transform="translate(170,86)"
style="fill:#333333">
<path
d="M 10,0 C 4.5,0 0,4.5 0,10 0,15.5 4.5,20 10,20 15.5,20 20,15.5 20,10 20,4.5 15.5,0 10,0 Z m 0.0078,17 C 5.6078125,17 3.0054175,14.4 3.0054175,10 3.0054175,5.6 5.6,3 10,3 c 4.4,0 8,2.6 8,7 0,4.4 -3.592187,7 -7.992187,7 z"
id="Shape"
inkscape:connector-curvature="0"
style="fill:#333333"
sodipodi:nodetypes="ssssssssss" />
</g>
</g>
</g>
<rect
style="fill:#0000ff;stroke-width:1.14508271"
id="rect3724"
width="10"
height="1.4978296"
x="-15"
y="5"
transform="scale(-1,1)" />
<path
id="Shape-3"
style="fill:#0000ff;fill-rule:evenodd;stroke:none;stroke-width:0.5"
d="M 5,5 C 6.017755,5 6.962173,5.3127537 7.75,5.84375 7.68224,5.84229 7.614347,5.84111 7.546875,5.83984 7.470745,5.83841 7.396456,5.83732 7.320312,5.83789 7.212566,5.83923 7.10448,5.851552 6.998047,5.867187 6.939667,5.876767 6.881129,5.884886 6.822266,5.890624 c -0.03789,0.00358 -0.07532,0.00511 -0.113282,0.00781 -0.580099,0.04116 -0.886095,0.3036967 -0.978515,0.59375 -0.0069,-0.00202 -0.0044,-0.00987 -0.01367,-0.00977 -0.0087,9.5e-5 -0.01863,4.569e-4 -0.02734,0 -0.01238,-7.539e-4 -0.02471,-0.00151 -0.03711,-0.00195 -0.01247,-7.873e-4 -0.02467,-7.906e-4 -0.03711,-0.00195 -0.01191,-0.00129 -0.02325,-0.00269 -0.03516,-0.00391 -0.01032,-0.00105 -0.0209,-0.00131 -0.03125,-0.00195 -0.0094,-5.48e-4 -0.01993,-0.00162 -0.0293,-0.00195 -0.0077,-2.774e-4 -0.01376,1.611e-4 -0.02148,0 -0.0069,-1.759e-4 -0.01459,-0.0014 -0.02149,-0.00195 -0.0088,-6.666e-4 -0.01848,4.1e-4 -0.02734,0 -0.0089,-1.831e-4 -0.01652,-0.00124 -0.02539,-0.00195 -0.0096,-7.737e-4 -0.01964,-0.00142 -0.0293,-0.00195 -0.0087,-4.687e-4 -0.01669,-0.00172 -0.02539,-0.00195 -0.01071,-2.653e-4 -0.02248,1.18e-4 -0.0332,0 -0.01016,-1.074e-4 -0.02109,6.47e-5 -0.03125,0 -0.0083,-4.83e-5 -0.01518,3.37e-5 -0.02344,0 h -0.0078 c -0.03112,-1.145e-4 -0.04211,0.011967 -0.04297,0.025391 -0.0032,4.11e-5 -0.0063,8.44e-5 -0.0098,0 -0.0067,-2.785e-4 -0.01282,-6.63e-4 -0.01953,0 -0.0073,1.893e-4 -0.01461,0.00413 -0.02148,0.00586 -0.002,6.216e-4 -0.0039,0.00162 -0.0059,0.00195 -0.0091,-0.00812 -0.0092,-0.021484 -0.0293,-0.021484 h -0.02344 -0.0039 c -0.01171,0 -0.01082,0.00813 -0.01758,0.011719 -0.0082,-0.00404 -0.0064,-0.013672 -0.01953,-0.013672 h -0.01758 -0.01563 c -0.02707,0 -0.035,0.014347 -0.04102,0.027344 -0.002,-4.51e-5 -0.0039,0 -0.0059,0 -2.2,0 -3.498047,1.3 -3.498047,3.5 0,2.2 1.301953,3.5 3.501953,3.5 0.0027,0 0.0052,7.3e-5 0.0078,0 0.0081,0.0091 0.01029,0.02096 0.03125,0.02148 0.0095,2.39e-4 0.01786,-4.07e-4 0.02734,0 0.0083,3.76e-4 0.01709,0.0012 0.02539,0.002 0.0084,7.66e-4 0.0071,-0.0066 0.01367,-0.0078 0.0059,6.91e-4 0.01163,0.0016 0.01758,0.002 0.0086,6.27e-4 0.01673,0.0021 0.02539,0.002 h 0.02344 0.02539 0.02734 0.02734 0.02344 c 0.0024,0 0.0017,-0.0018 0.0039,-0.002 0.132239,0.349342 1.840827,0.622525 0.816406,0.992188 0.01305,-0.0033 0.03016,-0.0066 0.04492,-0.0098 0.0065,-0.0014 0.0069,7.6e-5 0.01172,-0.002 -0.0093,-0.0011 -0.007,-5.28e-4 0.01367,-0.002 0.03387,-0.0018 0.0677,-0.0039 0.101562,-0.0059 0.01115,-6.69e-4 0.02205,-0.0013 0.0332,-0.002 0.07846,-0.0052 0.156196,-0.01103 0.234374,-0.01953 0.09564,-0.01086 0.190534,-0.02318 0.285157,-0.04102 0.118534,-0.02245 0.236979,-0.04664 0.353515,-0.07813 0.101479,-0.02835 0.20318,-0.05719 0.302735,-0.0918 0.07283,-0.0246 0.147154,-0.04915 0.216797,-0.08203 0.03706,-0.01699 0.07384,-0.03472 0.111328,-0.05078 C 7.006511,14.675558 6.040024,15 5,15 2.25,15 0,12.75 0,10 0,7.25 2.25,5 5,5 Z m 2.625,7.710938 c -0.0015,0.0029 -0.0044,0.0049 -0.0059,0.0078 -0.0072,0.0031 -0.01426,0.0066 -0.02149,0.0098 0.0088,-0.0062 0.01858,-0.01128 0.02734,-0.01758 z"
inkscape:connector-curvature="0" />
<rect
style="fill:#0000ff;stroke-width:1.14615846"
id="rect3724-6"
width="10"
height="1.5006453"
x="-15"
y="13.5"
transform="scale(-1,1)" />
<circle
style="fill:#0000ff;stroke-width:1.42857134"
id="path3807"
cx="-15"
cy="10"
r="5"
transform="scale(-1,1)" />
<svg width="20px" height="20px" version="1.1" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="m5 5c-2.77 0-5 2.23-5 5s2.23 5 5 5h10c2.77 0 5-2.23 5-5s-2.23-5-5-5h-10zm0 2h10c1.662 0 3 1.338 3 3s-1.338 3-3 3h-10c-1.662 0-3-1.338-3-3s1.338-3 3-3z" fill="#2a7fff" fill-rule="evenodd" stroke-width="1.8898"/>
<rect x="10" y="5" width="10" height="10" ry="5" fill="#2a7fff" fill-rule="evenodd" stroke-width="2.0692"/>
</svg>

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 439 B

View file

@ -1,34 +1,42 @@
{
"description": "Simple extension letting you uncheck all checkboxes on a page.",
"manifest_version": 2,
"name": "unchecker",
"version": "1.0",
"author": "Ad5001",
"developer": {
"name": "Ad5001",
"url": "https://ad5001.eu"
},
"applications": {
"gecko": {
"id": "unchecker@ad5001.eu",
"strict_min_version": "42.0"
}
},
"homepage_url": "https://github.com/Ad5001/unchecker",
"description": "Simple extension letting you uncheck all checkboxes on a page.",
"manifest_version": 3,
"name": "unchecker",
"version": "1.2.2",
"author": "Ad5001",
"developer": {
"name": "Ad5001",
"url": "https://ad5001.eu"
},
"browser_specific_settings": {
"gecko": {
"id": "unchecker@ad5001.eu",
"strict_min_version": "113.0"
},
"gecko_android": {
"strict_min_version": "113.0"
}
},
"homepage_url": "https://apps.ad5001.eu/unchecker/",
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": "icons/off.svg",
"browser_style": true
},
"permissions": [
"activeTab",
"tabs"
]
"background": {
"scripts": ["uncheck.js", "clickall.js"]
},
"action": {
"default_icon": "icons/on.svg",
"default_title": "Uncheck all checkboxes"
},
"icons": {
"48": "icons/off.svg",
"96": "icons/off.svg"
},
"permissions": [
"activeTab",
"tabs",
"menus",
"scripting"
]
}

86
test/frame.html Normal file
View file

@ -0,0 +1,86 @@
<!--
* Unchecker - Simple extension letting you uncheck all checkboxes on a page
* Copyright (c) Ad5001 2021-2023
*
* 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/.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Unchecker tests in iframe</title>
<style>
legend {
background-color: #000;
color: #fff;
padding: 3px 6px;
}
.toggled {
border-color: blue;
}
input {
margin: .4rem;
}
</style>
<script src="test.js"></script>
</head>
<body>
<fieldset>
<legend>Example radio list</legend>
<input type="radio" id="choice-value1" name="choice-value">
<label for="choice-value">Example, irrelevant choice value 1</label><br/>
<input type="radio" id="choice-value2" name="choice-value">
<label for="choice-value">Example, irrelevant choice value 2</label><br/>
</fieldset>
<br>
<fieldset>
<legend>Third party partners example</legend>
<input type="checkbox" id="ga-choice" checked="true">
<label for="ga-choice">Google Analytics</label><br/>
<input type="checkbox" id="facebook-ads" checked="true">
<label for="facebook-ads">Facebook Partnering</label><br/>
<input type="checkbox" id="amazon-sales" checked="true">
<label for="amazon-sales">Amazon</label><br/>
<input type="checkbox" id="salesforce" checked="true">
<label for="salesforce">Salesforce</label><br/>
</fieldset>
<br>
<fieldset>
<legend>Third party partners second</legend>
<table>
<tr>
<td>Google Analytics</td>
<td><button role="toggle" class="toggled" name="ga-choice">On</button></td>
<td><button role="toggle" name="ga-choice">Off</button></td>
</tr>
<tr>
<td>Facebook Partnering</td>
<td><button role="toggle" class="toggled" name="facebook-ads">On</button></td>
<td><button role="toggle" name="facebook-ads">Off</button></td>
</tr>
<tr>
<td>Amazon</td>
<td><button role="toggle" class="toggled" name="amazon-sales">On</button></td>
<td><button role="toggle" name="amazon-sales">Off</button></td>
</tr>
<tr>
<td>Salesforce</td>
<td><button role="toggle" class="toggled" name="salesforce">On</button></td>
<td><button role="toggle" name="salesforce">Off</button></td>
</tr>
</table>
</fieldset>
</body>
</html>

94
test/test.html Normal file
View file

@ -0,0 +1,94 @@
<!--
* Unchecker - Simple extension letting you uncheck all checkboxes on a page
* Copyright (c) Ad5001 2021-2023
*
* 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/.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Unchecker tests</title>
<style>
legend {
background-color: #000;
color: #fff;
padding: 3px 6px;
}
.toggled {
border-color: blue;
}
input {
margin: .4rem;
}
iframe {
width: 100%;
height: 500px;
}
</style>
<script src="test.js"></script>
</head>
<body>
<fieldset>
<legend>Example radio list</legend>
<input type="radio" id="choice-value1" name="choice-value">
<label for="choice-value">Example, irrelevant choice value 1</label><br/>
<input type="radio" id="choice-value2" name="choice-value">
<label for="choice-value">Example, irrelevant choice value 2</label><br/>
</fieldset>
<br>
<fieldset>
<legend>Third party partners example</legend>
<input type="checkbox" id="ga-choice" checked="true">
<label for="ga-choice">Google Analytics</label><br/>
<input type="checkbox" id="facebook-ads" checked="true">
<label for="facebook-ads">Facebook Partnering</label><br/>
<input type="checkbox" id="amazon-sales" checked="true">
<label for="amazon-sales">Amazon</label><br/>
<input type="checkbox" id="salesforce" checked="true">
<label for="salesforce">Salesforce</label><br/>
</fieldset>
<br>
<fieldset>
<legend>Third party partners second</legend>
<table>
<tr>
<td>Google Analytics</td>
<td><button role="toggle" class="toggled" name="ga-choice">On</button></td>
<td><button role="toggle" name="ga-choice">Off</button></td>
</tr>
<tr>
<td>Facebook Partnering</td>
<td><button role="toggle" class="toggled" name="facebook-ads">On</button></td>
<td><button role="toggle" name="facebook-ads">Off</button></td>
</tr>
<tr>
<td>Amazon</td>
<td><button role="toggle" class="toggled" name="amazon-sales">On</button></td>
<td><button role="toggle" name="amazon-sales">Off</button></td>
</tr>
<tr>
<td>Salesforce</td>
<td><button role="toggle" class="toggled" name="salesforce">On</button></td>
<td><button role="toggle" name="salesforce">Off</button></td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>IFramed tests</legend>
<iframe src="./frame.html"></iframe>
</body>
</html>

18
test/test.js Normal file
View file

@ -0,0 +1,18 @@
/**
* Unchecker - Simple extension letting you uncheck all checkboxes on a page
* Copyright (c) Ad5001 2021
*
* 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/.
**/
window.addEventListener("load", () => {
document.querySelectorAll("button[role=toggle]").forEach(button => {
button.addEventListener("click", () => {
Array.from(document.querySelectorAll("button[role=toggle]")).filter(btn => btn.name == button.name).forEach(btn => {
btn.classList.remove("toggled")
})
button.classList.add("toggled")
})
})
})

148
uncheck.js Normal file
View file

@ -0,0 +1,148 @@
/**
* Unchecker - Simple extension letting you uncheck all checkboxes on a page
* Copyright (c) Ad5001 2021-2023
*
* 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/.
**/
const uncheckAll = () => {
document.body.querySelectorAll('input[type="checkbox"]').forEach(function(el){
el.checked = false
})
}
const checkAll = () => {
document.body.querySelectorAll('input[type="checkbox"]').forEach(function(el){
el.checked = true
})
}
const TITLE_UNCHECK = "Uncheck all checkboxes"
const TITLE_CHECK = "Check all checkboxes"
const APPLICABLE_PROTOCOLS = ["http:", "https:"]
const MENU_CONTEXTS = ["all"]
/**
* Toggle Script: based on the current title, insert or remove the Script.
* Update the page actions title and icon, aswell as the context menu item to reflect its state.
**/
function toggleScript(tab) {
function gotTitle(title) {
console.log((title === TITLE_UNCHECK ? "Unchecking all checkboxes..." : "Checking all checkboxes...") + " at tab " + tab.id)
if(title === TITLE_UNCHECK) {
browser.action.setIcon({tabId: tab.id, path: "icons/off.svg"})
browser.action.setTitle({tabId: tab.id, title: TITLE_CHECK})
browser.scripting.executeScript({
func: uncheckAll,
target: {
tabId: tab.id,
allFrames: true
}
})
if(browser.menus)
browser.menus.update("unchecker-main", {
title: TITLE_CHECK,
icons: {
"16": "icons/off.svg"
}
})
} else {
browser.action.setIcon({tabId: tab.id, path: "icons/on.svg"})
browser.action.setTitle({tabId: tab.id, title: TITLE_UNCHECK})
browser.scripting.executeScript({
func: checkAll,
target: {
tabId: tab.id,
allFrames: true,
}
})
if(browser.menus)
browser.menus.update("unchecker-main", {
title: TITLE_UNCHECK,
icons: {
"16": "icons/on.svg"
}
})
}
}
browser.action.getTitle({tabId: tab.id}).then(gotTitle)
}
/**
* Returns true only if the URL's protocol is in APPLICABLE_PROTOCOLS.
**/
function protocolIsApplicable(url) {
let anchor = document.createElement('a')
anchor.href = url
return APPLICABLE_PROTOCOLS.includes(anchor.protocol)
}
/**
* Initialize the page action set icon and title, then show.
* Only operates on tabs whose URL's protocol is applicable.
**/
function initializebrowserAction(tab, createMenu) {
// console.log("Initializing browser action for tab", tab, createMenu)
if(protocolIsApplicable(tab.url)) {
browser.action.setIcon({tabId: tab.id, path: "icons/on.svg"})
browser.action.setTitle({tabId: tab.id, title: TITLE_UNCHECK})
}
if(createMenu && browser.menus) {
browser.menus.remove("unchecker-main").then(function() {
browser.menus.create({
id: "unchecker-main",
title: TITLE_UNCHECK,
icons: {
"16": "icons/on.svg"
},
contexts: MENU_CONTEXTS
})
})
}
}
/**
* Create the default context menu for the main function.
*/
if(browser.menus) { // Not supported on Firefox for Android
browser.menus.create({
id: "unchecker-main",
title: TITLE_UNCHECK,
icons: {
"16": "icons/on.svg"
},
contexts: MENU_CONTEXTS
})
browser.menus.onClicked.addListener((info, tab) => {
if(info.menuItemId == "unchecker-main")
toggleScript(tab)
})
}
/**
* When first loaded, initialize the page action for all tabs.
**/
browser.tabs.query({}).then((tabs) => {
for(let tab of tabs) {
initializebrowserAction(tab, false)
}
});
/**
* Each time a tab is updated, reset the page browser.action.for that tab.
**/
browser.tabs.onUpdated.addListener((id, changeInfo, tab) => {
initializebrowserAction(tab, true)
});
/**
* Toggle Script when the page browser.action.is clicked.
**/
browser.action.onClicked.addListener(toggleScript)