mirror of
https://github.com/gorhill/uBlock.git
synced 2024-09-15 15:32:28 +02:00
this fixes #257
This commit is contained in:
parent
b920b49d7d
commit
8d839d0230
@ -25,6 +25,7 @@
|
|||||||
<script src="js/tab.js"></script>
|
<script src="js/tab.js"></script>
|
||||||
<script src="js/traffic.js"></script>
|
<script src="js/traffic.js"></script>
|
||||||
<script src="js/messaging-handlers.js"></script>
|
<script src="js/messaging-handlers.js"></script>
|
||||||
|
<script src="js/contextmenu.js"></script>
|
||||||
<script src="js/start.js"></script>
|
<script src="js/start.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -54,6 +54,7 @@ return {
|
|||||||
userSettings: {
|
userSettings: {
|
||||||
autoUpdate: true,
|
autoUpdate: true,
|
||||||
collapseBlocked: true,
|
collapseBlocked: true,
|
||||||
|
contextMenuEnabled: false,
|
||||||
externalLists: defaultExternalLists,
|
externalLists: defaultExternalLists,
|
||||||
logRequests: false,
|
logRequests: false,
|
||||||
parseAllABPHideFilters: true,
|
parseAllABPHideFilters: true,
|
||||||
@ -114,6 +115,7 @@ return {
|
|||||||
noopFunc: function(){},
|
noopFunc: function(){},
|
||||||
|
|
||||||
apiErrorCount: 0,
|
apiErrorCount: 0,
|
||||||
|
elementPickerTarget: '',
|
||||||
|
|
||||||
// so that I don't have to care for last comma
|
// so that I don't have to care for last comma
|
||||||
dummy: 0
|
dummy: 0
|
||||||
|
104
js/contextmenu.js
Normal file
104
js/contextmenu.js
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
µBlock - a Chromium browser extension to block requests.
|
||||||
|
Copyright (C) 2014 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* global */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// New namespace
|
||||||
|
|
||||||
|
µBlock.contextMenu = (function() {
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var µb = µBlock;
|
||||||
|
var enabled = false;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var onContextMenuClicked = function(details, tab) {
|
||||||
|
if ( details.menuItemId !== 'blockElement' ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( tab === undefined ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( /^https?:\/\//.test(tab.url) === false ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var tagName = '';
|
||||||
|
var src = '';
|
||||||
|
if ( typeof details.frameUrl === 'string' ) {
|
||||||
|
tagName = 'iframe';
|
||||||
|
src = details.frameUrl;
|
||||||
|
} 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';
|
||||||
|
}
|
||||||
|
src = details.srcUrl;
|
||||||
|
} else if ( typeof details.linkUrl === 'string' ) {
|
||||||
|
tagName = 'a';
|
||||||
|
src = details.linkUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( src === '' ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
µb.elementPickerExec(tab.id, tagName + '\t' + src);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var toggleMenu = function(on) {
|
||||||
|
// This needs to be local scope: we can't reuse it for more than one
|
||||||
|
// menu creation call.
|
||||||
|
var menuCreateDetails = {
|
||||||
|
id: 'blockElement',
|
||||||
|
title: chrome.i18n.getMessage('pickerContextMenuEntry'),
|
||||||
|
contexts: ['frame', 'link', 'image', 'video'],
|
||||||
|
documentUrlPatterns: ['https://*/*', 'http://*/*']
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( on === true && enabled === false ) {
|
||||||
|
chrome.contextMenus.create(menuCreateDetails);
|
||||||
|
chrome.contextMenus.onClicked.addListener(onContextMenuClicked);
|
||||||
|
enabled = true;
|
||||||
|
} else if ( on !== true && enabled === true ) {
|
||||||
|
chrome.contextMenus.onClicked.removeListener(onContextMenuClicked);
|
||||||
|
chrome.contextMenus.remove(menuCreateDetails.id);
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
return {
|
||||||
|
toggle: toggleMenu
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
})();
|
@ -229,6 +229,10 @@ var svgOcean = null;
|
|||||||
var svgIslands = null;
|
var svgIslands = null;
|
||||||
var divDialog = null;
|
var divDialog = null;
|
||||||
var taCandidate = null;
|
var taCandidate = null;
|
||||||
|
var urlNormalizer = null;
|
||||||
|
|
||||||
|
var netFilterCandidates = [];
|
||||||
|
var cosmeticFilterCandidates = [];
|
||||||
|
|
||||||
var targetElements = [];
|
var targetElements = [];
|
||||||
var svgWidth = 0;
|
var svgWidth = 0;
|
||||||
@ -329,7 +333,7 @@ var removeElements = function(elems) {
|
|||||||
|
|
||||||
// Extract the best possible net filter, i.e. as specific as possible.
|
// Extract the best possible net filter, i.e. as specific as possible.
|
||||||
|
|
||||||
var netFilterFromElement = function(elem) {
|
var netFilterFromElement = function(elem, out) {
|
||||||
if ( elem === null ) {
|
if ( elem === null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -344,14 +348,31 @@ var netFilterFromElement = function(elem) {
|
|||||||
if ( typeof src !== 'string' || src.length === 0 ) {
|
if ( typeof src !== 'string' || src.length === 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return src.replace(/^https?:\/\//, '||').replace(/\?.*$/, '');
|
// Remove fragment
|
||||||
|
var pos = src.indexOf('#');
|
||||||
|
if ( pos !== -1 ) {
|
||||||
|
src = src.slice(0, pos);
|
||||||
|
}
|
||||||
|
// Feed the attribute to a link element, then retrieve back: this
|
||||||
|
// should normalize it.
|
||||||
|
urlNormalizer.href = src;
|
||||||
|
src = urlNormalizer.href;
|
||||||
|
// Anchor absolute filter to hostname
|
||||||
|
src = src.replace(/^https?:\/\//, '||');
|
||||||
|
out.push(src);
|
||||||
|
// Suggest a less narrow filter if possible
|
||||||
|
pos = src.indexOf('?');
|
||||||
|
if ( pos !== -1 ) {
|
||||||
|
src = src.slice(0, pos);
|
||||||
|
out.push(src);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// Extract the best possible cosmetic filter, i.e. as specific as possible.
|
// Extract the best possible cosmetic filter, i.e. as specific as possible.
|
||||||
|
|
||||||
var cosmeticFilterFromElement = function(elem) {
|
var cosmeticFilterFromElement = function(elem, out) {
|
||||||
if ( elem === null ) {
|
if ( elem === null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -417,42 +438,73 @@ var cosmeticFilterFromElement = function(elem) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return '##' + prefix + suffix.join('');
|
out.push('##' + prefix + suffix.join(''));
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var selectorFromCandidate = function() {
|
var filtersFromElement = function(elem) {
|
||||||
var selector = '';
|
netFilterCandidates.length = 0;
|
||||||
var v = taCandidate.value;
|
cosmeticFilterCandidates.length = 0;
|
||||||
if ( v.slice(0, 2) === '##' ) {
|
while ( elem && elem !== document.body ) {
|
||||||
selector = v.replace('##', '');
|
netFilterFromElement(elem, netFilterCandidates);
|
||||||
} else {
|
cosmeticFilterFromElement(elem, cosmeticFilterCandidates);
|
||||||
if ( v.slice(0, 2) === '||' ) {
|
elem = elem.parentNode;
|
||||||
v = v.replace('||', '');
|
|
||||||
}
|
|
||||||
selector = '[src*="' + v + '"]';
|
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
if ( document.querySelector(selector) === null ) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return selector;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var elementsFromFilter = function(filter) {
|
||||||
|
var out = [];
|
||||||
|
|
||||||
|
// Cosmetic filters: these are straight CSS selectors
|
||||||
|
// TODO: This is still not working well for a[href], because there are
|
||||||
|
// many ways to compose a valid href to the same effective URL.
|
||||||
|
// One idea is to normalize all a[href] on the page, but for now I will
|
||||||
|
// wait and see, as I prefer to refrain from tampering with the page
|
||||||
|
// content if I can avoid it.
|
||||||
|
if ( filter.slice(0, 2) === '##' ) {
|
||||||
|
try {
|
||||||
|
out = document.querySelectorAll(filter.replace('##', ''));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Net filters: we need to lookup manually -- translating into a
|
||||||
|
// foolproof CSS selector is just not possible
|
||||||
|
if ( filter.slice(0, 2) === '||' ) {
|
||||||
|
filter = filter.replace('||', '');
|
||||||
|
}
|
||||||
|
var elems = document.querySelectorAll('[src]');
|
||||||
|
var i = elems.length;
|
||||||
|
var elem;
|
||||||
|
while ( i-- ) {
|
||||||
|
elem = elems[i];
|
||||||
|
if ( typeof elem.src !== 'string' ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( elem.src.indexOf(filter) !== -1 ) {
|
||||||
|
out.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://www.youtube.com/watch?v=YI2XuIOW3gM
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var userFilterFromCandidate = function() {
|
var userFilterFromCandidate = function() {
|
||||||
if ( selectorFromCandidate() === '' ) {
|
var v = taCandidate.value;
|
||||||
|
|
||||||
|
var elems = elementsFromFilter(v);
|
||||||
|
if ( elems.length === 0 ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var v = taCandidate.value;
|
|
||||||
|
|
||||||
// Cosmetic filter?
|
// Cosmetic filter?
|
||||||
if ( v.slice(0, 2) === '##' ) {
|
if ( v.slice(0, 2) === '##' ) {
|
||||||
return window.location.hostname + v;
|
return window.location.hostname + v;
|
||||||
@ -468,52 +520,62 @@ var userFilterFromCandidate = function() {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var onCandidateChanged = function(ev) {
|
var onCandidateChanged = function() {
|
||||||
var selector = selectorFromCandidate();
|
var elems = elementsFromFilter(taCandidate.value);
|
||||||
divDialog.querySelector('#create').disabled = selector === '';
|
divDialog.querySelector('#create').disabled = elems.length === 0;
|
||||||
if ( selector === '' ) {
|
highlightElements(elems);
|
||||||
highlightElements([]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
highlightElements(document.querySelectorAll(selector));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var candidateFromClickEvent = function(ev) {
|
var candidateFromFilterChoice = function(filterChoice) {
|
||||||
var target = ev.target;
|
var slot = filterChoice.slot;
|
||||||
if ( !target ) {
|
var filters = filterChoice.filters;
|
||||||
|
var filter = filters[slot];
|
||||||
|
|
||||||
|
if ( filter === undefined ) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bare
|
|
||||||
if ( ev.ctrlKey || ev.metaKey ) {
|
|
||||||
return target.textContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For net filters there no such thing as a path
|
// For net filters there no such thing as a path
|
||||||
if ( target.textContent.charAt(0) !== '#' ) {
|
if ( filterChoice.type === 'net' || filterChoice.modifier ) {
|
||||||
return target.textContent;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return path: the target element, then all siblings prepended
|
// Return path: the target element, then all siblings prepended
|
||||||
var selector = [];
|
var selector = [];
|
||||||
while ( target ) {
|
var filter;
|
||||||
if ( target.nodeType !== 1 || target.tagName.toLowerCase() !== 'li' ) {
|
for ( ; slot < filters.length; slot++ ) {
|
||||||
continue;
|
filter = filters[slot];
|
||||||
}
|
selector.unshift(filter.replace(/^##/, ''));
|
||||||
selector.unshift(target.textContent.replace(/^##/, ''));
|
|
||||||
// Stop at any element with an id: these are unique in a web page
|
// Stop at any element with an id: these are unique in a web page
|
||||||
if ( target.textContent.slice(0, 3) === '###' ) {
|
if ( filter.slice(0, 3) === '###' ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
target = target.nextSibling;
|
|
||||||
}
|
}
|
||||||
return '##' + selector.join(' > ');
|
return '##' + selector.join(' > ');
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var filterChoiceFromEvent = function(ev) {
|
||||||
|
var li = ev.target;
|
||||||
|
var isNetFilter = li.textContent.slice(0, 2) !== '##';
|
||||||
|
var r = {
|
||||||
|
type: isNetFilter ? 'net' : 'cosmetic',
|
||||||
|
filters: isNetFilter ? netFilterCandidates : cosmeticFilterCandidates,
|
||||||
|
slot: 0,
|
||||||
|
modifier: ev.ctrlKey || ev.metaKey
|
||||||
|
};
|
||||||
|
while ( li.previousSibling !== null ) {
|
||||||
|
li = li.previousSibling;
|
||||||
|
r.slot += 1;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var onDialogClicked = function(ev) {
|
var onDialogClicked = function(ev) {
|
||||||
if ( ev.target === null ) {
|
if ( ev.target === null ) {
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
@ -523,7 +585,7 @@ var onDialogClicked = function(ev) {
|
|||||||
var filter = userFilterFromCandidate();
|
var filter = userFilterFromCandidate();
|
||||||
if ( filter ) {
|
if ( filter ) {
|
||||||
messaging.tell({ what: 'createUserFilter', filters: filter });
|
messaging.tell({ what: 'createUserFilter', filters: filter });
|
||||||
removeElements(document.querySelectorAll(selectorFromCandidate()));
|
removeElements(elementsFromFilter(taCandidate.value));
|
||||||
stopPicker();
|
stopPicker();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -537,7 +599,7 @@ var onDialogClicked = function(ev) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if ( ev.target.tagName.toLowerCase() === 'li' && pickerRootDistance(ev.target) === 5 ) {
|
else if ( ev.target.tagName.toLowerCase() === 'li' && pickerRootDistance(ev.target) === 5 ) {
|
||||||
taCandidate.value = candidateFromClickEvent(ev);
|
taCandidate.value = candidateFromFilterChoice(filterChoiceFromEvent(ev));
|
||||||
onCandidateChanged();
|
onCandidateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,28 +620,51 @@ var removeAllChildren = function(parent) {
|
|||||||
// TODO: for convenience I could provide a small set of net filters instead
|
// TODO: for convenience I could provide a small set of net filters instead
|
||||||
// of just a single one. Truncating the right-most part of the path etc.
|
// of just a single one. Truncating the right-most part of the path etc.
|
||||||
|
|
||||||
var showDialog = function(filters) {
|
var showDialog = function(options) {
|
||||||
var divNet = divDialog.querySelector('ul > li:nth-of-type(1) > ul');
|
|
||||||
var divCosmetic = divDialog.querySelector('ul > li:nth-of-type(2) > ul');
|
|
||||||
removeAllChildren(divCosmetic);
|
|
||||||
removeAllChildren(divNet);
|
|
||||||
var filter, li;
|
|
||||||
for ( var i = 0; i < filters.length; i++ ) {
|
|
||||||
filter = filters[i];
|
|
||||||
li = document.createElement('li');
|
|
||||||
li.textContent = filter;
|
|
||||||
if ( filter.indexOf('##') === 0 ) {
|
|
||||||
divCosmetic.appendChild(li);
|
|
||||||
} else {
|
|
||||||
divNet.appendChild(li);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
divDialog.querySelector('ul > li:nth-of-type(1)').style.display = divNet.firstChild ? '' : 'none';
|
|
||||||
divDialog.querySelector('ul > li:nth-of-type(2)').style.display = divCosmetic.firstChild ? '' : 'none';
|
|
||||||
divDialog.querySelector('ul').style.display = divNet.firstChild || divCosmetic.firstChild ? '' : 'none';
|
|
||||||
taCandidate.value = '';
|
|
||||||
divDialog.querySelector('#create').disabled = true;
|
|
||||||
pausePicker();
|
pausePicker();
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// Create lists of candidate filters
|
||||||
|
var populate = function(src, des) {
|
||||||
|
var root = divDialog.querySelector(des);
|
||||||
|
var ul = root.querySelector('ul');
|
||||||
|
removeAllChildren(ul);
|
||||||
|
var li;
|
||||||
|
for ( var i = 0; i < src.length; i++ ) {
|
||||||
|
li = document.createElement('li');
|
||||||
|
li.textContent = src[i];
|
||||||
|
ul.appendChild(li);
|
||||||
|
}
|
||||||
|
root.style.display = src.length !== 0 ? '' : 'none';
|
||||||
|
};
|
||||||
|
|
||||||
|
populate(netFilterCandidates, 'ul > li:nth-of-type(1)');
|
||||||
|
populate(cosmeticFilterCandidates, 'ul > li:nth-of-type(2)');
|
||||||
|
|
||||||
|
divDialog.querySelector('ul').style.display = netFilterCandidates.length || cosmeticFilterCandidates.length ? '' : 'none';
|
||||||
|
divDialog.querySelector('#create').disabled = true;
|
||||||
|
|
||||||
|
// Auto-select a candidate filter
|
||||||
|
var filterChoice = {
|
||||||
|
type: '',
|
||||||
|
filters: [],
|
||||||
|
slot: 0,
|
||||||
|
modifier: options.modifier || false
|
||||||
|
};
|
||||||
|
if ( netFilterCandidates.length ) {
|
||||||
|
filterChoice.type = 'net';
|
||||||
|
filterChoice.filters = netFilterCandidates;
|
||||||
|
} else if ( cosmeticFilterCandidates.length ) {
|
||||||
|
filterChoice.type = 'cosmetic';
|
||||||
|
filterChoice.filters = cosmeticFilterCandidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
taCandidate.value = '';
|
||||||
|
if ( filterChoice.type !== '' ) {
|
||||||
|
taCandidate.value = candidateFromFilterChoice(filterChoice);
|
||||||
|
onCandidateChanged();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -604,18 +689,8 @@ var onSvgClicked = function() {
|
|||||||
if ( pickerPaused() ) {
|
if ( pickerPaused() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
filtersFromElement(targetElements[0]);
|
||||||
var filter;
|
showDialog();
|
||||||
var filters = [];
|
|
||||||
for ( var elem = targetElements[0]; elem && elem !== document.body; elem = elem.parentNode ) {
|
|
||||||
if ( filter = cosmeticFilterFromElement(elem) ) {
|
|
||||||
filters.push(filter);
|
|
||||||
}
|
|
||||||
if ( filter = netFilterFromElement(elem) ) {
|
|
||||||
filters.push(filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
showDialog(filters);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -646,6 +721,9 @@ var onScrolled = function(ev) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Let's have the element picker code flushed from memory when no longer
|
||||||
|
// in use: to ensure this, release all local references.
|
||||||
|
|
||||||
var stopPicker = function() {
|
var stopPicker = function() {
|
||||||
if ( pickerRoot !== null ) {
|
if ( pickerRoot !== null ) {
|
||||||
document.removeEventListener('keydown', onKeyPressed);
|
document.removeEventListener('keydown', onKeyPressed);
|
||||||
@ -655,7 +733,11 @@ var stopPicker = function() {
|
|||||||
svgRoot.removeEventListener('mousemove', onSvgHovered);
|
svgRoot.removeEventListener('mousemove', onSvgHovered);
|
||||||
svgRoot.removeEventListener('click', onSvgClicked);
|
svgRoot.removeEventListener('click', onSvgClicked);
|
||||||
document.body.removeChild(pickerRoot);
|
document.body.removeChild(pickerRoot);
|
||||||
pickerRoot = divDialog = svgRoot = svgOcean = svgIslands = taCandidate = null;
|
pickerRoot =
|
||||||
|
divDialog =
|
||||||
|
svgRoot = svgOcean = svgIslands =
|
||||||
|
taCandidate =
|
||||||
|
urlNormalizer = null;
|
||||||
messaging.stop();
|
messaging.stop();
|
||||||
}
|
}
|
||||||
targetElements = [];
|
targetElements = [];
|
||||||
@ -685,6 +767,7 @@ var startPicker = function() {
|
|||||||
'color: #000;',
|
'color: #000;',
|
||||||
'font: 12px sans-serif;',
|
'font: 12px sans-serif;',
|
||||||
'margin: 0;',
|
'margin: 0;',
|
||||||
|
'max-width: none;',
|
||||||
'outline: 0;',
|
'outline: 0;',
|
||||||
'overflow: visible;',
|
'overflow: visible;',
|
||||||
'padding: 0;',
|
'padding: 0;',
|
||||||
@ -710,6 +793,9 @@ var startPicker = function() {
|
|||||||
'color: #999;',
|
'color: #999;',
|
||||||
'background-color: #ccc;',
|
'background-color: #ccc;',
|
||||||
'}',
|
'}',
|
||||||
|
'.µBlock button#create:not(:disabled) {',
|
||||||
|
'background-color: #ffdca8;',
|
||||||
|
'}',
|
||||||
'.µBlock > svg {',
|
'.µBlock > svg {',
|
||||||
'position: absolute;',
|
'position: absolute;',
|
||||||
'top: 0;',
|
'top: 0;',
|
||||||
@ -782,6 +868,17 @@ var startPicker = function() {
|
|||||||
'text-align: left;',
|
'text-align: left;',
|
||||||
'overflow: hidden;',
|
'overflow: hidden;',
|
||||||
'}',
|
'}',
|
||||||
|
'.µBlock > div > ul > li:not(:first-child) {',
|
||||||
|
'margin-top: 0.5em;',
|
||||||
|
'}',
|
||||||
|
'.µBlock > div > ul > li > span:nth-of-type(1) {',
|
||||||
|
'font-weight: bold;',
|
||||||
|
'}',
|
||||||
|
'.µBlock > div > ul > li > span:nth-of-type(2) {',
|
||||||
|
'margin: 0 0 0 1em;',
|
||||||
|
'font-size: smaller;',
|
||||||
|
'color: gray;',
|
||||||
|
'}',
|
||||||
'.µBlock > div > ul > li > ul {',
|
'.µBlock > div > ul > li > ul {',
|
||||||
'margin: 0 0 0 1em;',
|
'margin: 0 0 0 1em;',
|
||||||
'list-style-type: none;',
|
'list-style-type: none;',
|
||||||
@ -832,8 +929,8 @@ var startPicker = function() {
|
|||||||
'</div>',
|
'</div>',
|
||||||
'</div>',
|
'</div>',
|
||||||
'<ul>',
|
'<ul>',
|
||||||
'<li>.<ul></ul>',
|
'<li><span>.</span><ul></ul>',
|
||||||
'<li>.<ul></ul>',
|
'<li><span>.</span><span>.</span><ul></ul>',
|
||||||
'</ul>',
|
'</ul>',
|
||||||
''
|
''
|
||||||
].join('');
|
].join('');
|
||||||
@ -845,6 +942,7 @@ var startPicker = function() {
|
|||||||
divDialog.addEventListener('click', onDialogClicked);
|
divDialog.addEventListener('click', onDialogClicked);
|
||||||
taCandidate = divDialog.querySelector('textarea');
|
taCandidate = divDialog.querySelector('textarea');
|
||||||
taCandidate.addEventListener('input', onCandidateChanged);
|
taCandidate.addEventListener('input', onCandidateChanged);
|
||||||
|
urlNormalizer = document.createElement('a');
|
||||||
window.addEventListener('scroll', onScrolled);
|
window.addEventListener('scroll', onScrolled);
|
||||||
document.addEventListener('keydown', onKeyPressed);
|
document.addEventListener('keydown', onKeyPressed);
|
||||||
};
|
};
|
||||||
@ -855,12 +953,59 @@ startPicker();
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
messaging.ask({ what: 'i18n' }, function(details) {
|
messaging.ask({ what: 'elementPickerArguments' }, function(details) {
|
||||||
divDialog.querySelector('#create').firstChild.nodeValue = details.create;
|
var i18nMap = {
|
||||||
divDialog.querySelector('#pick').firstChild.nodeValue = details.pick;
|
'#create': 'create',
|
||||||
divDialog.querySelector('#quit').firstChild.nodeValue = details.quit;
|
'#pick': 'pick',
|
||||||
divDialog.querySelector('ul > li:nth-of-type(1)').firstChild.nodeValue = details.netFilters;
|
'#quit': 'quit',
|
||||||
divDialog.querySelector('ul > li:nth-of-type(2)').firstChild.nodeValue = details.cosmeticFilters;
|
'ul > li:nth-of-type(1) > span:nth-of-type(1)': 'netFilters',
|
||||||
|
'ul > li:nth-of-type(2) > span:nth-of-type(1)': 'cosmeticFilters',
|
||||||
|
'ul > li:nth-of-type(2) > span:nth-of-type(2)': 'cosmeticFiltersHint'
|
||||||
|
|
||||||
|
};
|
||||||
|
for ( var k in i18nMap ) {
|
||||||
|
if ( i18nMap.hasOwnProperty(k) === false ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
divDialog.querySelector(k).firstChild.nodeValue = details.i18n[i18nMap[k]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-select a specific target, if any, and if possible
|
||||||
|
var targetElement = details.targetElement || '';
|
||||||
|
var pos = targetElement.indexOf('\t');
|
||||||
|
if ( pos === -1 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var srcAttrMap = {
|
||||||
|
'a': 'href',
|
||||||
|
'img': 'src',
|
||||||
|
'iframe': 'src',
|
||||||
|
'video': 'src',
|
||||||
|
'audio': 'src'
|
||||||
|
};
|
||||||
|
var tagName = targetElement.slice(0, pos);
|
||||||
|
var url = targetElement.slice(pos + 1);
|
||||||
|
var attr = srcAttrMap[tagName];
|
||||||
|
if ( attr === undefined ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var elems = document.querySelectorAll(tagName + '[' + attr + ']');
|
||||||
|
var i = elems.length;
|
||||||
|
var elem, src;
|
||||||
|
while ( i-- ) {
|
||||||
|
elem = elems[i];
|
||||||
|
src = elem.getAttribute(attr);
|
||||||
|
if ( src === null || src === '' ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
urlNormalizer.href = src;
|
||||||
|
src = urlNormalizer.href;
|
||||||
|
if ( src === url ) {
|
||||||
|
filtersFromElement(elem);
|
||||||
|
showDialog({ modifier: true });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -24,14 +24,17 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// popup.js
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
// popup.js
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var µb = µBlock;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var getStats = function(request) {
|
var getStats = function(request) {
|
||||||
var µb = µBlock;
|
|
||||||
var r = {
|
var r = {
|
||||||
globalBlockedRequestCount: µb.localSettings.blockedRequestCount,
|
globalBlockedRequestCount: µb.localSettings.blockedRequestCount,
|
||||||
globalAllowedRequestCount: µb.localSettings.allowedRequestCount,
|
globalAllowedRequestCount: µb.localSettings.allowedRequestCount,
|
||||||
@ -72,26 +75,28 @@ var onMessage = function(request, sender, callback) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'toggleNetFiltering':
|
case 'toggleNetFiltering':
|
||||||
µBlock.toggleNetFilteringSwitch(
|
µb.toggleNetFilteringSwitch(
|
||||||
request.url,
|
request.url,
|
||||||
request.scope,
|
request.scope,
|
||||||
request.state
|
request.state
|
||||||
);
|
);
|
||||||
µBlock.updateBadgeAsync(request.tabId);
|
µb.updateBadgeAsync(request.tabId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'gotoPick':
|
case 'gotoPick':
|
||||||
chrome.tabs.executeScript(request.tabId, { file: 'js/element-picker.js' });
|
µb.elementPickerExec(request.tabId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return µBlock.messaging.defaultHandler(request, sender, callback);
|
return µb.messaging.defaultHandler(request, sender, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(response);
|
callback(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
µBlock.messaging.listen('popup.js', onMessage);
|
µb.messaging.listen('popup.js', onMessage);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -102,8 +107,12 @@ var onMessage = function(request, sender, callback) {
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var µb = µBlock;
|
var µb = µBlock;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
var onMessage = function(request, sender, callback) {
|
||||||
// Async
|
// Async
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
@ -135,6 +144,8 @@ var onMessage = function(request, sender, callback) {
|
|||||||
|
|
||||||
µb.messaging.listen('contentscript-start.js', onMessage);
|
µb.messaging.listen('contentscript-start.js', onMessage);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -144,6 +155,8 @@ var onMessage = function(request, sender, callback) {
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var µb = µBlock;
|
var µb = µBlock;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -256,6 +269,8 @@ var onMessage = function(details, sender, callback) {
|
|||||||
|
|
||||||
µb.messaging.listen('contentscript-end.js', onMessage);
|
µb.messaging.listen('contentscript-end.js', onMessage);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -265,6 +280,12 @@ var onMessage = function(details, sender, callback) {
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var µb = µBlock;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
var onMessage = function(request, sender, callback) {
|
||||||
// Async
|
// Async
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
@ -276,28 +297,35 @@ var onMessage = function(request, sender, callback) {
|
|||||||
var response;
|
var response;
|
||||||
|
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
case 'i18n':
|
case 'elementPickerArguments':
|
||||||
response = {
|
response = {
|
||||||
create: chrome.i18n.getMessage('pickerCreate'),
|
i18n: {
|
||||||
pick: chrome.i18n.getMessage('pickerPick'),
|
create: chrome.i18n.getMessage('pickerCreate'),
|
||||||
quit: chrome.i18n.getMessage('pickerQuit'),
|
pick: chrome.i18n.getMessage('pickerPick'),
|
||||||
netFilters: chrome.i18n.getMessage('pickerNetFilters'),
|
quit: chrome.i18n.getMessage('pickerQuit'),
|
||||||
cosmeticFilters: chrome.i18n.getMessage('pickerCosmeticFilters')
|
netFilters: chrome.i18n.getMessage('pickerNetFilters'),
|
||||||
|
cosmeticFilters: chrome.i18n.getMessage('pickerCosmeticFilters'),
|
||||||
|
cosmeticFiltersHint: chrome.i18n.getMessage('pickerCosmeticFiltersHint')
|
||||||
|
},
|
||||||
|
targetElement: µb.elementPickerTarget
|
||||||
};
|
};
|
||||||
|
µb.elementPickerTarget = '';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'createUserFilter':
|
case 'createUserFilter':
|
||||||
µBlock.appendUserFilters(request.filters);
|
µb.appendUserFilters(request.filters);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return µBlock.messaging.defaultHandler(request, sender, callback);
|
return µb.messaging.defaultHandler(request, sender, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(response);
|
callback(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
µBlock.messaging.listen('element-picker.js', onMessage);
|
µb.messaging.listen('element-picker.js', onMessage);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -308,8 +336,13 @@ var onMessage = function(request, sender, callback) {
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var µb = µBlock;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var getLists = function(callback) {
|
var getLists = function(callback) {
|
||||||
var µb = µBlock;
|
|
||||||
var r = {
|
var r = {
|
||||||
available: null,
|
available: null,
|
||||||
current: µb.remoteBlacklists,
|
current: µb.remoteBlacklists,
|
||||||
@ -334,8 +367,6 @@ var getLists = function(callback) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
var onMessage = function(request, sender, callback) {
|
||||||
var µb = µBlock;
|
|
||||||
|
|
||||||
// Async
|
// Async
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
case 'getLists':
|
case 'getLists':
|
||||||
@ -369,7 +400,9 @@ var onMessage = function(request, sender, callback) {
|
|||||||
callback(response);
|
callback(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
µBlock.messaging.listen('3p-filters.js', onMessage);
|
µb.messaging.listen('3p-filters.js', onMessage);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -380,9 +413,13 @@ var onMessage = function(request, sender, callback) {
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
/******************************************************************************/
|
||||||
var µb = µBlock;
|
|
||||||
|
|
||||||
|
var µb = µBlock;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var onMessage = function(request, sender, callback) {
|
||||||
// Async
|
// Async
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
case 'readUserFilters':
|
case 'readUserFilters':
|
||||||
@ -406,7 +443,9 @@ var onMessage = function(request, sender, callback) {
|
|||||||
callback(response);
|
callback(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
µBlock.messaging.listen('1p-filters.js', onMessage);
|
µb.messaging.listen('1p-filters.js', onMessage);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -417,9 +456,13 @@ var onMessage = function(request, sender, callback) {
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
/******************************************************************************/
|
||||||
var µb = µBlock;
|
|
||||||
|
|
||||||
|
var µb = µBlock;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var onMessage = function(request, sender, callback) {
|
||||||
// Async
|
// Async
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
default:
|
default:
|
||||||
@ -446,7 +489,9 @@ var onMessage = function(request, sender, callback) {
|
|||||||
callback(response);
|
callback(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
µBlock.messaging.listen('whitelist.js', onMessage);
|
µb.messaging.listen('whitelist.js', onMessage);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -457,6 +502,12 @@ var onMessage = function(request, sender, callback) {
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var µb = µBlock;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var getPageDetails = function(µb, tabId) {
|
var getPageDetails = function(µb, tabId) {
|
||||||
var r = {
|
var r = {
|
||||||
blockedRequests: [],
|
blockedRequests: [],
|
||||||
@ -510,8 +561,6 @@ var getPageDetails = function(µb, tabId) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
var onMessage = function(request, sender, callback) {
|
||||||
var µb = µBlock;
|
|
||||||
|
|
||||||
// Async
|
// Async
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
default:
|
default:
|
||||||
@ -537,7 +586,9 @@ var onMessage = function(request, sender, callback) {
|
|||||||
callback(response);
|
callback(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
µBlock.messaging.listen('stats.js', onMessage);
|
µb.messaging.listen('stats.js', onMessage);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -548,9 +599,13 @@ var onMessage = function(request, sender, callback) {
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var onMessage = function(request, sender, callback) {
|
/******************************************************************************/
|
||||||
var µb = µBlock;
|
|
||||||
|
|
||||||
|
var µb = µBlock;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var onMessage = function(request, sender, callback) {
|
||||||
// Async
|
// Async
|
||||||
switch ( request.what ) {
|
switch ( request.what ) {
|
||||||
|
|
||||||
@ -570,7 +625,9 @@ var onMessage = function(request, sender, callback) {
|
|||||||
callback(response);
|
callback(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
µBlock.messaging.listen('about.js', onMessage);
|
µb.messaging.listen('about.js', onMessage);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -55,6 +55,12 @@ var onUserSettingsReceived = function(details) {
|
|||||||
.on('change', function(){
|
.on('change', function(){
|
||||||
changeUserSettings('showIconBadge', this.checked);
|
changeUserSettings('showIconBadge', this.checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
uDom('#context-menu-enabled')
|
||||||
|
.prop('checked', details.contextMenuEnabled === true)
|
||||||
|
.on('change', function(){
|
||||||
|
changeUserSettings('contextMenuEnabled', this.checked);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
messaging.ask({ what: 'userSettings' }, onUserSettingsReceived);
|
messaging.ask({ what: 'userSettings' }, onUserSettingsReceived);
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
var settingsLoaded = function(store) {
|
var settingsLoaded = function(store) {
|
||||||
µBlock.userSettings = store;
|
µBlock.userSettings = store;
|
||||||
if ( typeof callback === 'function' ) {
|
if ( typeof callback === 'function' ) {
|
||||||
callback();
|
callback(store);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -666,7 +666,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// User settings are in memory
|
// User settings are in memory
|
||||||
var onUserSettingsReady = function() {
|
var onUserSettingsReady = function(settings) {
|
||||||
|
µb.contextMenu.toggle(settings.contextMenuEnabled);
|
||||||
µb.fromSelfie(onSelfieReady);
|
µb.fromSelfie(onSelfieReady);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
22
js/ublock.js
22
js/ublock.js
@ -184,10 +184,8 @@
|
|||||||
// Return all settings if none specified.
|
// Return all settings if none specified.
|
||||||
|
|
||||||
µBlock.changeUserSettings = function(name, value) {
|
µBlock.changeUserSettings = function(name, value) {
|
||||||
var µb = µBlock;
|
|
||||||
|
|
||||||
if ( name === undefined ) {
|
if ( name === undefined ) {
|
||||||
return µb.userSettings;
|
return this.userSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( typeof name !== 'string' || name === '' ) {
|
if ( typeof name !== 'string' || name === '' ) {
|
||||||
@ -195,12 +193,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do not allow an unknown user setting to be created
|
// Do not allow an unknown user setting to be created
|
||||||
if ( µb.userSettings[name] === undefined ) {
|
if ( this.userSettings[name] === undefined ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( value === undefined ) {
|
if ( value === undefined ) {
|
||||||
return µb.userSettings[name];
|
return this.userSettings[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-change
|
// Pre-change
|
||||||
@ -210,15 +208,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change
|
// Change
|
||||||
µb.userSettings[name] = value;
|
this.userSettings[name] = value;
|
||||||
|
|
||||||
// Post-change
|
// Post-change
|
||||||
switch ( name ) {
|
switch ( name ) {
|
||||||
|
case 'contextMenuEnabled':
|
||||||
|
this.contextMenu.toggle(value === true);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
µb.saveUserSettings();
|
this.saveUserSettings();
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -242,3 +243,10 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
µBlock.elementPickerExec = function(tabId, targetElement) {
|
||||||
|
this.elementPickerTarget = targetElement || '';
|
||||||
|
chrome.tabs.executeScript(tabId, { file: 'js/element-picker.js' });
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "__MSG_extName__",
|
"name": "__MSG_extName__",
|
||||||
"short_name": "µBlock",
|
"short_name": "µBlock",
|
||||||
"version": "0.6.4.0",
|
"version": "0.6.5.0",
|
||||||
"description": "__MSG_extShortDesc__",
|
"description": "__MSG_extShortDesc__",
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "img/icon_16.png",
|
"16": "img/icon_16.png",
|
||||||
@ -38,6 +38,7 @@
|
|||||||
"minimum_chrome_version": "22.0",
|
"minimum_chrome_version": "22.0",
|
||||||
"options_page": "dashboard.html",
|
"options_page": "dashboard.html",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"contextMenus",
|
||||||
"downloads",
|
"downloads",
|
||||||
"storage",
|
"storage",
|
||||||
"tabs",
|
"tabs",
|
||||||
|
@ -17,6 +17,7 @@ ul {
|
|||||||
<ul>
|
<ul>
|
||||||
<li><input id="collapse-blocked" type="checkbox"> <label data-i18n="settingsCollapseBlockedPrompt"></label>
|
<li><input id="collapse-blocked" type="checkbox"> <label data-i18n="settingsCollapseBlockedPrompt"></label>
|
||||||
<li><input id="icon-badge" type="checkbox"> <label data-i18n="settingsIconBadgePrompt"></label>
|
<li><input id="icon-badge" type="checkbox"> <label data-i18n="settingsIconBadgePrompt"></label>
|
||||||
|
<li><input id="context-menu-enabled" type="checkbox"><label data-i18n="settingsContextMenuPrompt"></label>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<script src="js/udom.js"></script>
|
<script src="js/udom.js"></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user