mirror of https://github.com/gorhill/uBlock.git
Element picker: cleanup and Firefox improvements (closes #1211)
In Firefox, you can now block an element right from the Web Inspector. This was implemented by @AlexVallat -- thanks to Alex for the awesome feature enhancement.
This commit is contained in:
parent
f961cad0f0
commit
e8572bdc21
|
@ -65,7 +65,7 @@ vAPI.app.restart = function() {
|
|||
var cleanupTasks = [];
|
||||
|
||||
// This must be updated manually, every time a new task is added/removed
|
||||
var expectedNumberOfCleanups = 6; // 7 instances of cleanupTasks.push, but one is unique to fennec, and one to desktop.
|
||||
var expectedNumberOfCleanups = vAPI.fennec ? 7 : 8; // 8 instances of cleanupTasks.push, but one is unique to fennec, and two to desktop.
|
||||
|
||||
window.addEventListener('unload', function() {
|
||||
for ( var cleanup of cleanupTasks ) {
|
||||
|
@ -392,8 +392,9 @@ vAPI.tabs.registerListeners = function() {
|
|||
cleanupTasks.push(function() {
|
||||
Services.ww.unregisterNotification(windowWatcher);
|
||||
|
||||
vAPI.contextMenu.remove();
|
||||
|
||||
for ( var win of vAPI.tabs.getWindows() ) {
|
||||
vAPI.contextMenu.unregister(win.document);
|
||||
win.removeEventListener('DOMContentLoaded', windowWatcher.onReady);
|
||||
|
||||
var tabContainer;
|
||||
|
@ -1760,6 +1761,15 @@ vAPI.contextMenu.displayMenuItem = function({target}) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.contextMenu.createContextMenuItem = function(doc) {
|
||||
var menuitem = doc.createElement('menuitem');
|
||||
menuitem.setAttribute('id', this.menuItemId);
|
||||
menuitem.setAttribute('label', this.menuLabel);
|
||||
menuitem.setAttribute('image', vAPI.getURL('img/browsericons/icon16.svg'));
|
||||
menuitem.setAttribute('class', 'menuitem-iconic');
|
||||
return menuitem;
|
||||
}
|
||||
|
||||
vAPI.contextMenu.register = function(doc) {
|
||||
if ( !this.menuItemId ) {
|
||||
return;
|
||||
|
@ -1777,11 +1787,7 @@ vAPI.contextMenu.register = function(doc) {
|
|||
}
|
||||
|
||||
var contextMenu = doc.getElementById('contentAreaContextMenu');
|
||||
var menuitem = doc.createElement('menuitem');
|
||||
menuitem.setAttribute('id', this.menuItemId);
|
||||
menuitem.setAttribute('label', this.menuLabel);
|
||||
menuitem.setAttribute('image', vAPI.getURL('img/browsericons/icon16.svg'));
|
||||
menuitem.setAttribute('class', 'menuitem-iconic');
|
||||
var menuitem = this.createContextMenuItem(doc);
|
||||
menuitem.addEventListener('command', this.onCommand);
|
||||
contextMenu.addEventListener('popupshowing', this.displayMenuItem);
|
||||
contextMenu.insertBefore(menuitem, doc.getElementById('inspect-separator'));
|
||||
|
@ -1808,6 +1814,36 @@ vAPI.contextMenu.unregister = function(doc) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.contextMenu.registerForWebInspector = function(eventName, toolbox, panel) {
|
||||
var menuPopup = panel.panelDoc.getElementById("inspector-node-popup");
|
||||
var deleteMenuItem = panel.panelDoc.getElementById("node-menu-delete");
|
||||
var tiltButton = toolbox.toolboxButtons.filter(tool => tool.id === "command-button-tilt")[0];
|
||||
tiltButton = tiltButton && tiltButton.button;
|
||||
|
||||
if (menuPopup && deleteMenuItem) {
|
||||
var menuitem = vAPI.contextMenu.createContextMenuItem(panel.panelDoc);
|
||||
menuitem.addEventListener('command', function() {
|
||||
var selectedNodeFront = panel.selection.nodeFront;
|
||||
while (selectedNodeFront && selectedNodeFront.baseURI !== panel.walker.rootNode.baseURI) {
|
||||
// This is an iFrame, so we can't select it directly. Walk up the parent stack until we do
|
||||
selectedNodeFront = selectedNodeFront.parentNode();
|
||||
}
|
||||
if (selectedNodeFront) {
|
||||
selectedNodeFront.getUniqueSelector().then(selector => µBlock.elementPickerExec(vAPI.tabs.getTabId(panel.browser), selector));
|
||||
|
||||
// Turn off 3D view, if it's turned on.
|
||||
if (tiltButton && tiltButton.checked) {
|
||||
tiltButton.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
menuPopup.insertBefore(menuitem, deleteMenuItem);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.contextMenu.create = function(details, callback) {
|
||||
this.menuItemId = details.id;
|
||||
this.menuLabel = details.title;
|
||||
|
@ -1850,6 +1886,19 @@ vAPI.contextMenu.create = function(details, callback) {
|
|||
});
|
||||
};
|
||||
|
||||
// Also add a context menu to the web inspector
|
||||
if (!vAPI.fennec) {
|
||||
try {
|
||||
this.gDevTools = Cu.import('resource:///modules/devtools/gDevTools.jsm', null).gDevTools;
|
||||
} catch (ex) {
|
||||
// console.error(ex);
|
||||
}
|
||||
|
||||
if (this.gDevTools) {
|
||||
this.gDevTools.on("inspector-ready", this.registerForWebInspector);
|
||||
}
|
||||
}
|
||||
|
||||
for ( var win of vAPI.tabs.getWindows() ) {
|
||||
this.register(win.document);
|
||||
}
|
||||
|
@ -1862,6 +1911,10 @@ vAPI.contextMenu.remove = function() {
|
|||
this.unregister(win.document);
|
||||
}
|
||||
|
||||
if (!vAPI.fennec && this.gDevTools) {
|
||||
this.gDevTools.off("inspector-ready", this.registerForWebInspector);
|
||||
}
|
||||
|
||||
this.menuItemId = null;
|
||||
this.menuLabel = null;
|
||||
this.contexts = null;
|
||||
|
|
|
@ -136,11 +136,10 @@ return {
|
|||
noopFunc: function(){},
|
||||
|
||||
apiErrorCount: 0,
|
||||
contextMenuTarget: '',
|
||||
contextMenuClientX: -1,
|
||||
contextMenuClientY: -1,
|
||||
|
||||
epickerTarget: '',
|
||||
epickerTargetElementSelector: null,
|
||||
epickerEprom: null,
|
||||
|
||||
// so that I don't have to care for last comma
|
||||
|
|
|
@ -45,26 +45,8 @@ var onContextMenuClicked = function(details, tab) {
|
|||
if ( /^https?:\/\//.test(tab.url) === false ) {
|
||||
return;
|
||||
}
|
||||
var tagName = details.tagName || '';
|
||||
var src = details.frameUrl || details.srcUrl || details.linkUrl || '';
|
||||
|
||||
if ( !tagName ) {
|
||||
if ( typeof details.frameUrl === 'string' ) {
|
||||
tagName = 'iframe';
|
||||
} else if ( typeof details.srcUrl === 'string' ) {
|
||||
if ( details.mediaType === 'image' ) {
|
||||
tagName = 'img';
|
||||
} else if ( details.mediaType === 'video' ) {
|
||||
tagName = 'video';
|
||||
} else if ( details.mediaType === 'audio' ) {
|
||||
tagName = 'audio';
|
||||
}
|
||||
} else if ( typeof details.linkUrl === 'string' ) {
|
||||
tagName = 'a';
|
||||
}
|
||||
}
|
||||
|
||||
µb.elementPickerExec(tab.id, tagName + '\t' + src);
|
||||
µb.elementPickerExec(tab.id);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -128,7 +128,8 @@ if ( window.top !== window ) {
|
|||
var pickerRoot = document.getElementById(vAPI.sessionId);
|
||||
|
||||
if ( pickerRoot ) {
|
||||
return;
|
||||
// If it's already running, stop it and then allow it to restart
|
||||
pickerRoot.onload(); // Calls stopPicker
|
||||
}
|
||||
|
||||
var localMessager = vAPI.messaging.channel('element-picker.js');
|
||||
|
@ -873,53 +874,21 @@ var startPicker = function(details) {
|
|||
|
||||
highlightElements([], true);
|
||||
|
||||
var elem;
|
||||
var elem = null;
|
||||
|
||||
// If a target element was provided, use it
|
||||
if (details.targetElementSelector) {
|
||||
elem = document.querySelector(details.targetElementSelector);
|
||||
}
|
||||
|
||||
// Try using mouse position
|
||||
if ( details.clientX !== -1 ) {
|
||||
if (!elem && details.clientX !== -1) {
|
||||
elem = elementFromPoint(details.clientX, details.clientY);
|
||||
if ( elem !== null ) {
|
||||
filtersFromElement(elem);
|
||||
showDialog();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No mouse position available, use suggested target
|
||||
var target = details.target || '';
|
||||
var pos = target.indexOf('\t');
|
||||
if ( pos === -1 ) {
|
||||
return;
|
||||
}
|
||||
var srcAttrMap = {
|
||||
'a': 'href',
|
||||
'img': 'src',
|
||||
'iframe': 'src',
|
||||
'embed': 'src',
|
||||
'video': 'src',
|
||||
'audio': 'src'
|
||||
};
|
||||
var tagName = target.slice(0, pos);
|
||||
var url = target.slice(pos + 1);
|
||||
var attr = srcAttrMap[tagName];
|
||||
if ( attr === undefined ) {
|
||||
return;
|
||||
}
|
||||
var elems = document.querySelectorAll(tagName + '[' + attr + ']');
|
||||
var i = elems.length;
|
||||
var src;
|
||||
while ( i-- ) {
|
||||
elem = elems[i];
|
||||
src = elem[attr];
|
||||
if ( typeof src !== 'string' || src === '' ) {
|
||||
continue;
|
||||
}
|
||||
if ( src !== url ) {
|
||||
continue;
|
||||
}
|
||||
if (elem !== null) {
|
||||
filtersFromElement(elem);
|
||||
showDialog({ modifier: true });
|
||||
return;
|
||||
showDialog();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -574,13 +574,12 @@ var onMessage = function(request, sender, callback) {
|
|||
|
||||
callback({
|
||||
frameContent: this.responseText.replace(reStrings, replacer),
|
||||
target: µb.contextMenuTarget,
|
||||
targetElementSelector: µb.epickerTargetElementSelector,
|
||||
clientX: µb.contextMenuClientX,
|
||||
clientY: µb.contextMenuClientY,
|
||||
eprom: µb.epickerEprom
|
||||
});
|
||||
|
||||
µb.contextMenuTarget = '';
|
||||
µb.contextMenuClientX = -1;
|
||||
µb.contextMenuClientY = -1;
|
||||
};
|
||||
|
|
|
@ -276,8 +276,8 @@ var matchWhitelistDirective = function(url, hostname, directive) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.elementPickerExec = function(tabId, targetElement) {
|
||||
this.epickerTarget = targetElement || '';
|
||||
µBlock.elementPickerExec = function(tabId, targetElementSelector) {
|
||||
this.epickerTargetElementSelector = targetElementSelector;
|
||||
vAPI.tabs.injectScript(tabId, { file: 'js/element-picker.js' });
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue