1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-10-04 08:37:11 +02:00

new feature: element zapper

This commit is contained in:
gorhill 2017-05-27 11:51:24 -04:00
parent 8e788668b5
commit 39aeaa12a7
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
17 changed files with 191 additions and 25 deletions

View File

@ -4,6 +4,20 @@
"name": "uBlock Origin", "name": "uBlock Origin",
"version": "1.12.5.10", "version": "1.12.5.10",
"commands": {
"launch-element-zapper": {
"suggested_key": {
"default": "Alt+Z"
},
"description": "__MSG_popupTipZapper__"
},
"launch-element-picker": {
"suggested_key": {
"default": "Alt+X"
},
"description": "__MSG_popupTipPicker__"
}
},
"default_locale": "en", "default_locale": "en",
"description": "__MSG_extShortDesc__", "description": "__MSG_extShortDesc__",
"icons": { "icons": {

View File

@ -1192,6 +1192,11 @@ vAPI.contextMenu = {
/******************************************************************************/ /******************************************************************************/
/******************************************************************************/ /******************************************************************************/
vAPI.commands = chrome.commands;
/******************************************************************************/
/******************************************************************************/
vAPI.lastError = function() { vAPI.lastError = function() {
return chrome.runtime.lastError; return chrome.runtime.lastError;
}; };

View File

@ -33,5 +33,6 @@
<script src="js/rpcreceiver.js"></script> <script src="js/rpcreceiver.js"></script>
<script src="js/from-legacy.js"></script> <script src="js/from-legacy.js"></script>
<script src="js/start.js"></script> <script src="js/start.js"></script>
<script src="js/commands.js"></script>
</body> </body>
</html> </html>

View File

@ -11,6 +11,20 @@
} }
}, },
"commands": {
"launch-element-zapper": {
"suggested_key": {
"default": "Alt+Z"
},
"description": "__MSG_popupTipZapper__"
},
"launch-element-picker": {
"suggested_key": {
"default": "Alt+X"
},
"description": "__MSG_popupTipPicker__"
}
},
"default_locale": "en", "default_locale": "en",
"description": "__MSG_extShortDesc__", "description": "__MSG_extShortDesc__",
"icons": { "icons": {

View File

@ -71,6 +71,10 @@
"message":"Click to open the dashboard", "message":"Click to open the dashboard",
"description":"English: Click to open the dashboard" "description":"English: Click to open the dashboard"
}, },
"popupTipZapper":{
"message":"Enter element zapper mode",
"description":"Tooltip for the element-zapper icon in the popup panel"
},
"popupTipPicker":{ "popupTipPicker":{
"message":"Enter element picker mode", "message":"Enter element picker mode",
"description":"English: Enter element picker mode" "description":"English: Enter element picker mode"

View File

@ -32,5 +32,6 @@
<script src="js/reverselookup.js"></script> <script src="js/reverselookup.js"></script>
<script src="js/rpcreceiver.js"></script> <script src="js/rpcreceiver.js"></script>
<script src="js/start.js"></script> <script src="js/start.js"></script>
<script src="js/commands.js"></script>
</body> </body>
</html> </html>

View File

@ -167,10 +167,11 @@ body.off #switch .fa {
color: #aaa; color: #aaa;
cursor: pointer; cursor: pointer;
display: none; display: none;
min-width: 1em;
unicode-bidi: embed; unicode-bidi: embed;
} }
.tool.enabled { .tool.enabled {
display: inline; display: inline-block;
} }
.tool:hover { .tool:hover {
color: #444; color: #444;

View File

@ -141,7 +141,7 @@ svg {
cursor: not-allowed; cursor: not-allowed;
} }
svg > path:first-child { svg > path:first-child {
fill: rgba(0,0,0,0.75); fill: rgba(0,0,0,0.6);
fill-rule: evenodd; fill-rule: evenodd;
} }
svg > path + path { svg > path + path {
@ -149,6 +149,11 @@ svg > path + path {
stroke-width: 0.5px; stroke-width: 0.5px;
fill: rgba(255,63,63,0.20); fill: rgba(255,63,63,0.20);
} }
body.zap svg > path + path {
stroke: #FF0;
stroke-width: 0.5px;
fill: rgba(255,255,63,0.20);
}
body.preview svg > path { body.preview svg > path {
fill: rgba(0,0,0,0.10); fill: rgba(0,0,0,0.10);
} }

View File

@ -158,6 +158,7 @@ var µBlock = (function() { // jshint ignore:line
mouseY: -1, mouseY: -1,
mouseURL: '', mouseURL: '',
epickerTarget: '', epickerTarget: '',
epickerZap: false,
epickerEprom: null, epickerEprom: null,
scriptlets: { scriptlets: {

51
src/js/commands.js Normal file
View File

@ -0,0 +1,51 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2017 Raymond Hill
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uBlock
*/
/******************************************************************************/
'use strict';
/******************************************************************************/
(function() {
if ( vAPI.commands === undefined ) { return; }
vAPI.commands.onCommand.addListener(function(command) {
var µb = µBlock;
switch ( command ) {
case 'launch-element-zapper':
case 'launch-element-picker':
vAPI.tabs.get(null, function(tab) {
if ( tab instanceof Object === false ) {
return;
}
µb.mouseX = µb.mouseY = -1;
µb.elementPickerExec(tab.id, undefined, command === 'launch-element-zapper');
});
break;
default:
break;
}
});
})();
/******************************************************************************/

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2015 Raymond Hill Copyright (C) 2014-2017 Raymond Hill
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -19,12 +19,12 @@
Home: https://github.com/gorhill/uBlock Home: https://github.com/gorhill/uBlock
*/ */
'use strict';
/******************************************************************************/ /******************************************************************************/
µBlock.contextMenu = (function() { µBlock.contextMenu = (function() {
'use strict';
/******************************************************************************/ /******************************************************************************/
var µb = µBlock; var µb = µBlock;

View File

@ -138,7 +138,7 @@ var onMessage = function(request, sender, callback) {
case 'launchElementPicker': case 'launchElementPicker':
// Launched from some auxiliary pages, clear context menu coords. // Launched from some auxiliary pages, clear context menu coords.
µb.mouseX = µb.mouseY = -1; µb.mouseX = µb.mouseY = -1;
µb.elementPickerExec(request.tabId, request.targetURL || ''); µb.elementPickerExec(request.tabId, request.targetURL, request.zap);
break; break;
case 'gotoURL': case 'gotoURL':
@ -324,7 +324,7 @@ var popupDataFromTabId = function(tabId, tabTitle) {
r.hostnameDict = getHostnameDict(pageStore.hostnameToCountMap); r.hostnameDict = getHostnameDict(pageStore.hostnameToCountMap);
r.contentLastModified = pageStore.contentLastModified; r.contentLastModified = pageStore.contentLastModified;
r.firewallRules = getFirewallRules(rootHostname, r.hostnameDict); r.firewallRules = getFirewallRules(rootHostname, r.hostnameDict);
r.canElementPicker = rootHostname.indexOf('.') !== -1; r.canElementPicker = µb.URI.isNetworkURI(r.rawURL);
r.noPopups = µb.hnSwitches.evaluateZ('no-popups', rootHostname); r.noPopups = µb.hnSwitches.evaluateZ('no-popups', rootHostname);
r.popupBlockedCount = pageStore.popupBlockedCount; r.popupBlockedCount = pageStore.popupBlockedCount;
r.noCosmeticFiltering = µb.hnSwitches.evaluateZ('no-cosmetic-filtering', rootHostname); r.noCosmeticFiltering = µb.hnSwitches.evaluateZ('no-cosmetic-filtering', rootHostname);
@ -606,6 +606,7 @@ var onMessage = function(request, sender, callback) {
target: µb.epickerTarget, target: µb.epickerTarget,
clientX: µb.mouseX, clientX: µb.mouseX,
clientY: µb.mouseY, clientY: µb.mouseY,
zap: µb.epickerZap,
eprom: µb.epickerEprom eprom: µb.epickerEprom
}); });

View File

@ -408,6 +408,7 @@ var renderPopup = function() {
// If you think the `=== true` is pointless, you are mistaken // If you think the `=== true` is pointless, you are mistaken
uDom.nodeFromId('gotoPick').classList.toggle('enabled', popupData.canElementPicker === true); uDom.nodeFromId('gotoPick').classList.toggle('enabled', popupData.canElementPicker === true);
uDom.nodeFromId('gotoZap').classList.toggle('enabled', popupData.canElementPicker === true);
var text, var text,
blocked = popupData.pageBlockedRequestCount, blocked = popupData.pageBlockedRequestCount,
@ -587,6 +588,21 @@ var toggleNetFilteringSwitch = function(ev) {
/******************************************************************************/ /******************************************************************************/
var gotoZap = function() {
messaging.send(
'popupPanel',
{
what: 'launchElementPicker',
tabId: popupData.tabId,
zap: true
}
);
vAPI.closePopup();
};
/******************************************************************************/
var gotoPick = function() { var gotoPick = function() {
messaging.send( messaging.send(
'popupPanel', 'popupPanel',
@ -981,6 +997,7 @@ var onHideTooltip = function() {
getPopupData(tabId); getPopupData(tabId);
uDom('#switch').on('click', toggleNetFilteringSwitch); uDom('#switch').on('click', toggleNetFilteringSwitch);
uDom('#gotoZap').on('click', gotoZap);
uDom('#gotoPick').on('click', gotoPick); uDom('#gotoPick').on('click', gotoPick);
uDom('a[href]').on('click', gotoURL); uDom('a[href]').on('click', gotoURL);
uDom('h2').on('click', toggleFirewallPane); uDom('h2').on('click', toggleFirewallPane);

View File

@ -1179,7 +1179,10 @@ var showDialog = function(options) {
populate(netFilterCandidates, '#netFilters'); populate(netFilterCandidates, '#netFilters');
populate(cosmeticFilterCandidates, '#cosmeticFilters'); populate(cosmeticFilterCandidates, '#cosmeticFilters');
dialog.querySelector('ul').style.display = netFilterCandidates.length || cosmeticFilterCandidates.length ? '' : 'none'; dialog.querySelector('ul').style.display =
netFilterCandidates.length || cosmeticFilterCandidates.length
? ''
: 'none';
dialog.querySelector('#create').disabled = true; dialog.querySelector('#create').disabled = true;
// Auto-select a candidate filter // Auto-select a candidate filter
@ -1201,21 +1204,44 @@ var showDialog = function(options) {
/******************************************************************************/ /******************************************************************************/
var elementFromPoint = function(x, y) { var zap = function() {
if ( !pickerRoot ) { if ( targetElements.length === 0 ) { return; }
return null; var elem = targetElements[0],
style = window.getComputedStyle(elem);
// Heuristic to detect scroll-locking: remove such lock when detected.
if ( parseInt(style.zIndex, 10) >= 1000 || style.position === 'fixed' ) {
document.body.style.setProperty('overflow', 'auto', 'important');
document.documentElement.style.setProperty('overflow', 'auto', 'important');
} }
pickerRoot.style.pointerEvents = 'none'; elem.parentNode.removeChild(elem);
var elem = document.elementFromPoint(x, y);
if ( elem === document.body || elem === document.documentElement ) {
elem = null;
}
pickerRoot.style.pointerEvents = '';
return elem;
}; };
/******************************************************************************/ /******************************************************************************/
var elementFromPoint = (function() {
var lastX, lastY;
return function(x, y) {
if ( x !== undefined ) {
lastX = x; lastY = y;
} else if ( lastX !== undefined ) {
x = lastX; y = lastY;
} else {
return null;
}
if ( !pickerRoot ) { return null; }
pickerRoot.style.pointerEvents = 'none';
var elem = document.elementFromPoint(x, y);
if ( elem === document.body || elem === document.documentElement ) {
elem = null;
}
pickerRoot.style.pointerEvents = '';
return elem;
};
})();
/******************************************************************************/
var onSvgHovered = (function() { var onSvgHovered = (function() {
var timer = null; var timer = null;
var mx = 0, my = 0; var mx = 0, my = 0;
@ -1253,6 +1279,11 @@ var onSvgClicked = function(ev) {
if ( filtersFrom(ev.clientX, ev.clientY) === 0 ) { if ( filtersFrom(ev.clientX, ev.clientY) === 0 ) {
return; return;
} }
if ( pickerBody.classList.contains('zap') ) {
zap();
stopPicker();
return;
}
showDialog(); showDialog();
}; };
@ -1266,11 +1297,24 @@ var svgListening = function(on) {
/******************************************************************************/ /******************************************************************************/
var onKeyPressed = function(ev) { var onKeyPressed = function(ev) {
if ( ev.which === 27 ) { var elem;
// Delete
if ( ev.key === 'Delete' ) {
ev.stopPropagation();
ev.preventDefault();
zap();
elem = elementFromPoint();
highlightElements(elem ? [elem] : []);
return;
}
// Esc
if ( ev.key === 'Escape' || ev.which === 27 ) {
ev.stopPropagation(); ev.stopPropagation();
ev.preventDefault(); ev.preventDefault();
filterToDOMInterface.preview(false); filterToDOMInterface.preview(false);
stopPicker(); stopPicker();
return;
} }
}; };
@ -1360,6 +1404,7 @@ var startPicker = function(details) {
pickerBody = frameDoc.body; pickerBody = frameDoc.body;
pickerBody.setAttribute('lang', navigator.language); pickerBody.setAttribute('lang', navigator.language);
pickerBody.classList.toggle('zap', details.zap === true);
dialog = pickerBody.querySelector('aside'); dialog = pickerBody.querySelector('aside');
dialog.addEventListener('click', onDialogClicked); dialog.addEventListener('click', onDialogClicked);

View File

@ -392,11 +392,12 @@ var reInvalidHostname = /[^a-z0-9.\-\[\]:]/,
/******************************************************************************/ /******************************************************************************/
µBlock.elementPickerExec = function(tabId, targetElement) { µBlock.elementPickerExec = function(tabId, targetElement, zap) {
if ( vAPI.isBehindTheSceneTabId(tabId) ) { if ( vAPI.isBehindTheSceneTabId(tabId) ) {
return; return;
} }
this.epickerTarget = targetElement || ''; this.epickerTarget = targetElement || '';
this.epickerZap = zap || false;
this.scriptlets.inject(tabId, 'element-picker'); this.scriptlets.inject(tabId, 'element-picker');
if ( typeof vAPI.tabs.select === 'function' ) { if ( typeof vAPI.tabs.select === 'function' ) {
vAPI.tabs.select(tabId); vAPI.tabs.select(tabId);

View File

@ -403,15 +403,19 @@ URI.domainFromURI = function(uri) {
/******************************************************************************/ /******************************************************************************/
URI.isNetworkURI = function(uri) { URI.isNetworkURI = function(uri) {
return /^(?:ftps?|https?|wss?):\/\//.test(uri); return reNetworkURI.test(uri);
}; };
var reNetworkURI = /^(?:ftps?|https?|wss?):\/\//;
/******************************************************************************/ /******************************************************************************/
URI.isNetworkScheme = function(scheme) { URI.isNetworkScheme = function(scheme) {
return /^(?:ftps?|https?|wss?)$/.test(scheme); return reNetworkScheme.test(scheme);
}; };
var reNetworkScheme = /^(?:ftps?|https?|wss?)$/;
/******************************************************************************/ /******************************************************************************/
// Normalize the way µBlock expects it // Normalize the way µBlock expects it

View File

@ -16,9 +16,10 @@
<p id="switch" data-i18n-tip="popupPowerSwitchInfo" data-tip-position="under"><span class="fa">&#xf011;</span></p> <p id="switch" data-i18n-tip="popupPowerSwitchInfo" data-tip-position="under"><span class="fa">&#xf011;</span></p>
<h2 id="dfToggler" data-i18n="popupBlockedRequestPrompt">&nbsp;</h2> <h2 id="dfToggler" data-i18n="popupBlockedRequestPrompt">&nbsp;</h2>
<p class="statName"> <p class="statName">
<span data-i18n="popupBlockedOnThisPagePrompt">&nbsp;</span>&ensp; <span data-i18n="popupBlockedOnThisPagePrompt">&nbsp;</span>&ensp;<!--
<span id="gotoPick" class="fa tool" data-i18n-tip="popupTipPicker">&#xf1fb;</span>&ensp; --><span id="gotoZap" class="fa tool" data-i18n-tip="popupTipZapper">&#xf0e7;</span>&ensp;<!--
<a href="logger-ui.html" class="fa tool enabled" data-i18n-tip="popupTipLog">&#xf022;</a> --><span id="gotoPick" class="fa tool" data-i18n-tip="popupTipPicker">&#xf1fb;</span>&ensp;<!--
--><a href="logger-ui.html" class="fa tool enabled" data-i18n-tip="popupTipLog">&#xf022;</a>
</p> </p>
<p class="statValue" id="page-blocked">?</p> <p class="statValue" id="page-blocked">?</p>
<div id="refresh" class="fa">&#xf021;</div> <div id="refresh" class="fa">&#xf021;</div>