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",
"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",
"description": "__MSG_extShortDesc__",
"icons": {

View File

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

View File

@ -33,5 +33,6 @@
<script src="js/rpcreceiver.js"></script>
<script src="js/from-legacy.js"></script>
<script src="js/start.js"></script>
<script src="js/commands.js"></script>
</body>
</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",
"description": "__MSG_extShortDesc__",
"icons": {

View File

@ -71,6 +71,10 @@
"message":"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":{
"message":"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/rpcreceiver.js"></script>
<script src="js/start.js"></script>
<script src="js/commands.js"></script>
</body>
</html>

View File

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

View File

@ -141,7 +141,7 @@ svg {
cursor: not-allowed;
}
svg > path:first-child {
fill: rgba(0,0,0,0.75);
fill: rgba(0,0,0,0.6);
fill-rule: evenodd;
}
svg > path + path {
@ -149,6 +149,11 @@ svg > path + path {
stroke-width: 0.5px;
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 {
fill: rgba(0,0,0,0.10);
}

View File

@ -158,6 +158,7 @@ var µBlock = (function() { // jshint ignore:line
mouseY: -1,
mouseURL: '',
epickerTarget: '',
epickerZap: false,
epickerEprom: null,
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.
Copyright (C) 2014-2015 Raymond Hill
Copyright (C) 2014-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
@ -19,12 +19,12 @@
Home: https://github.com/gorhill/uBlock
*/
'use strict';
/******************************************************************************/
µBlock.contextMenu = (function() {
'use strict';
/******************************************************************************/
var µb = µBlock;

View File

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

View File

@ -408,6 +408,7 @@ var renderPopup = function() {
// If you think the `=== true` is pointless, you are mistaken
uDom.nodeFromId('gotoPick').classList.toggle('enabled', popupData.canElementPicker === true);
uDom.nodeFromId('gotoZap').classList.toggle('enabled', popupData.canElementPicker === true);
var text,
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() {
messaging.send(
'popupPanel',
@ -981,6 +997,7 @@ var onHideTooltip = function() {
getPopupData(tabId);
uDom('#switch').on('click', toggleNetFilteringSwitch);
uDom('#gotoZap').on('click', gotoZap);
uDom('#gotoPick').on('click', gotoPick);
uDom('a[href]').on('click', gotoURL);
uDom('h2').on('click', toggleFirewallPane);

View File

@ -1179,7 +1179,10 @@ var showDialog = function(options) {
populate(netFilterCandidates, '#netFilters');
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;
// Auto-select a candidate filter
@ -1201,10 +1204,32 @@ var showDialog = function(options) {
/******************************************************************************/
var elementFromPoint = function(x, y) {
if ( !pickerRoot ) {
var zap = function() {
if ( targetElements.length === 0 ) { return; }
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');
}
elem.parentNode.removeChild(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 ) {
@ -1212,7 +1237,8 @@ var elementFromPoint = function(x, y) {
}
pickerRoot.style.pointerEvents = '';
return elem;
};
};
})();
/******************************************************************************/
@ -1253,6 +1279,11 @@ var onSvgClicked = function(ev) {
if ( filtersFrom(ev.clientX, ev.clientY) === 0 ) {
return;
}
if ( pickerBody.classList.contains('zap') ) {
zap();
stopPicker();
return;
}
showDialog();
};
@ -1266,11 +1297,24 @@ var svgListening = function(on) {
/******************************************************************************/
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.preventDefault();
filterToDOMInterface.preview(false);
stopPicker();
return;
}
};
@ -1360,6 +1404,7 @@ var startPicker = function(details) {
pickerBody = frameDoc.body;
pickerBody.setAttribute('lang', navigator.language);
pickerBody.classList.toggle('zap', details.zap === true);
dialog = pickerBody.querySelector('aside');
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) ) {
return;
}
this.epickerTarget = targetElement || '';
this.epickerZap = zap || false;
this.scriptlets.inject(tabId, 'element-picker');
if ( typeof vAPI.tabs.select === 'function' ) {
vAPI.tabs.select(tabId);

View File

@ -403,15 +403,19 @@ URI.domainFromURI = 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) {
return /^(?:ftps?|https?|wss?)$/.test(scheme);
return reNetworkScheme.test(scheme);
};
var reNetworkScheme = /^(?:ftps?|https?|wss?)$/;
/******************************************************************************/
// 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>
<h2 id="dfToggler" data-i18n="popupBlockedRequestPrompt">&nbsp;</h2>
<p class="statName">
<span data-i18n="popupBlockedOnThisPagePrompt">&nbsp;</span>&ensp;
<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>
<span data-i18n="popupBlockedOnThisPagePrompt">&nbsp;</span>&ensp;<!--
--><span id="gotoZap" class="fa tool" data-i18n-tip="popupTipZapper">&#xf0e7;</span>&ensp;<!--
--><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 class="statValue" id="page-blocked">?</p>
<div id="refresh" class="fa">&#xf021;</div>