mirror of https://github.com/gorhill/uBlock.git
logger: UI work on URL-based dynamic filtering
This commit is contained in:
parent
c265d6747b
commit
72c930ddff
|
@ -392,6 +392,27 @@ vAPI.tabs.reload = function(tabId /*, flags*/) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
// Select a specific tab.
|
||||
|
||||
vAPI.tabs.select = function(tabId) {
|
||||
tabId = toChromiumTabId(tabId);
|
||||
if ( tabId === 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
chrome.tabs.update(tabId, { active: true }, function(tab) {
|
||||
if ( chrome.runtime.lastError ) {
|
||||
/* noop */
|
||||
}
|
||||
if ( !tab ) {
|
||||
return;
|
||||
}
|
||||
chrome.windows.update(tab.windowId, { focused: true });
|
||||
});
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.tabs.injectScript = function(tabId, details, callback) {
|
||||
var onScriptExecuted = function() {
|
||||
// https://code.google.com/p/chromium/issues/detail?id=410868#c8
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
font-style: normal;
|
||||
font-weight: normal;
|
||||
line-height: 1;
|
||||
vertical-align: baseline;
|
||||
vertical-align: middle;
|
||||
}
|
||||
body {
|
||||
background-color: white;
|
||||
|
|
|
@ -91,10 +91,10 @@ input:focus {
|
|||
width: 2.5em;
|
||||
}
|
||||
#content table > colgroup > col:nth-of-type(3) {
|
||||
width: 2.5em;
|
||||
width: 20%;
|
||||
}
|
||||
#content table > colgroup > col:nth-of-type(4) {
|
||||
width: 20%;
|
||||
width: 2.5em;
|
||||
}
|
||||
#content table > colgroup > col:nth-of-type(5) {
|
||||
width: 6em;
|
||||
|
@ -102,7 +102,7 @@ input:focus {
|
|||
#content table > colgroup > col:nth-of-type(6) {
|
||||
width: calc(100% - 16em - 20%);
|
||||
}
|
||||
body.f table tr.f {
|
||||
body.f #content table tr.f {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,12 @@ body.f table tr.f {
|
|||
body.colorBlind #content tr.blocked {
|
||||
background-color: rgba(0, 19, 110, 0.1);
|
||||
}
|
||||
#content tr.nooped {
|
||||
background-color: rgba(108, 108, 108, 0.1);
|
||||
}
|
||||
body.colorBlind #content tr.nooped {
|
||||
background-color: rgba(96, 96, 96, 0.1);
|
||||
}
|
||||
#content tr.allowed {
|
||||
background-color: rgba(0, 160, 0, 0.1);
|
||||
}
|
||||
|
@ -183,17 +189,17 @@ body:not(.popupOn) #content tr.canMtx td:nth-of-type(2) {
|
|||
body:not(.popupOn) #content tr.canMtx td:nth-of-type(2):hover {
|
||||
background: #ccc;
|
||||
}
|
||||
#content tr.cat_net td:nth-of-type(3),
|
||||
#content tr.cat_cosmetic td:nth-of-type(3) {
|
||||
#content tr.cat_net td:nth-of-type(4),
|
||||
#content tr.cat_cosmetic td:nth-of-type(4) {
|
||||
font: 12px monospace;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#content tr.cat_net td:nth-of-type(3) {
|
||||
#content tr.cat_net td:nth-of-type(4) {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
#content tr.cat_net td:nth-of-type(3):hover {
|
||||
#content tr.cat_net td:nth-of-type(4):hover {
|
||||
background: #ccc;
|
||||
}
|
||||
#content tr.cat_net td:nth-of-type(6) > span > b {
|
||||
|
@ -208,6 +214,12 @@ body:not(.popupOn) #content tr.canMtx td:nth-of-type(2):hover {
|
|||
body.colorBlind #content tr.blocked td:nth-of-type(6) b {
|
||||
background-color: rgba(0, 19, 110, 0.2);
|
||||
}
|
||||
#content tr.nooped td:nth-of-type(6) b {
|
||||
background-color: rgba(108, 108, 108, 0.2);
|
||||
}
|
||||
body.colorBlind #content tr.nooped td:nth-of-type(6) b {
|
||||
background-color: rgba(96, 96, 96, 0.2);
|
||||
}
|
||||
#content tr.allowed td:nth-of-type(6) b {
|
||||
background-color: rgba(0, 160, 0, 0.2);
|
||||
}
|
||||
|
@ -272,107 +284,125 @@ body[dir="rtl"] #popupContainer > div {
|
|||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
z-index: 400;
|
||||
}
|
||||
#urlFilteringMenu .dialog {
|
||||
background-color: white;
|
||||
border: 1px solid gray;
|
||||
max-width: 70%;
|
||||
padding: 0.2em;
|
||||
position: fixed;
|
||||
border: 2px solid white;
|
||||
left: 10%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
transform-style: preserve-3d;
|
||||
width: 80%;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div:first-child {
|
||||
padding: 0.2em 0.2em 0.4em 0.2em;
|
||||
#urlFilteringMenu .dialog table {
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div:first-child > * {
|
||||
display: inline-block;
|
||||
#urlFilteringMenu .dialog table > colgroup > col:nth-of-type(1) {
|
||||
width: 3.8em;
|
||||
}
|
||||
#urlFilteringMenu .dialog table > colgroup > col:nth-of-type(2) {
|
||||
}
|
||||
|
||||
#urlFilteringMenu .dialog td {
|
||||
border: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#urlFilteringMenu .save {
|
||||
#urlFilteringMenu .dialog > table.toolbar td.preview {
|
||||
/* http://lea.verou.me/css3patterns/ */
|
||||
background-color: #aaa;
|
||||
background-image:
|
||||
linear-gradient(
|
||||
45deg,
|
||||
#666 25%,
|
||||
transparent 25%,
|
||||
transparent 75%,
|
||||
#666 75%,
|
||||
#666
|
||||
),
|
||||
linear-gradient(
|
||||
45deg,
|
||||
#666 25%,
|
||||
transparent 25%,
|
||||
transparent 75%,
|
||||
#666 75%,
|
||||
#666
|
||||
);
|
||||
background-position:0 0, 9px 9px;
|
||||
background-size: 18px 18px;
|
||||
text-align: center;
|
||||
}
|
||||
#urlFilteringMenu .dialog > table.toolbar td.preview > * {
|
||||
max-width: 100%;
|
||||
max-height: 40vh;
|
||||
}
|
||||
#urlFilteringMenu .dialog > table.toolbar select {
|
||||
font: 14px;
|
||||
height: 1.8em;
|
||||
}
|
||||
#urlFilteringMenu .dialog > table.toolbar .fa {
|
||||
cursor: pointer;
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
#urlFilteringMenu .dialog > table.toolbar .fa.save {
|
||||
background-color: #ffe;
|
||||
border: 1px solid #ddc;
|
||||
border-radius: 4px;
|
||||
color: #888;
|
||||
cursor: pointer;
|
||||
font-size: 1.8em;
|
||||
margin-right: 0.1em;
|
||||
padding: 0.1em 0.5em;
|
||||
margin: 0.1em;
|
||||
padding: 0.25em 0.5em;
|
||||
visibility: hidden;
|
||||
}
|
||||
body.dirty #urlFilteringMenu .save {
|
||||
body.dirty #urlFilteringMenu .dialog > table.toolbar .fa.save {
|
||||
visibility: visible;
|
||||
}
|
||||
#urlFilteringMenu .save:hover {
|
||||
#urlFilteringMenu .dialog > table.toolbar .fa.save:hover {
|
||||
color: black;
|
||||
}
|
||||
#urlFilteringMenu select {
|
||||
font: inherit;
|
||||
#urlFilteringMenu .dialog > table.toolbar tr.entry {
|
||||
display: none;
|
||||
}
|
||||
#urlFilteringMenu .entries {
|
||||
font-size: 13px;
|
||||
max-height: 12em;
|
||||
#urlFilteringMenu .dialog > div.entries {
|
||||
max-height: 30vh;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
#urlFilteringMenu .entries > div {
|
||||
#urlFilteringMenu .dialog > div.header {
|
||||
background-color: #666;
|
||||
color: white;
|
||||
font-size: smaller;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry {
|
||||
background-color: #e6e6e6;
|
||||
border: 0;
|
||||
line-height: 2em;
|
||||
margin: 0;
|
||||
margin-top: 1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid white;
|
||||
font-size: 13px;
|
||||
}
|
||||
#urlFilteringMenu .entries > div:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
#urlFilteringMenu .entries > div:hover {
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry:hover {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action {
|
||||
background-color: transparent;
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td:first-of-type {
|
||||
border: 0;
|
||||
border-right: 1px solid white;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
width: 3.8em;
|
||||
height: 2em;
|
||||
width: 100%;
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action.allow {
|
||||
background-color: rgba(0, 160, 0, 0.3);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .entries > div > .action.allow {
|
||||
background-color: rgba(255, 194, 57, 0.4);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action.noop {
|
||||
background-color: rgba(108, 108, 108, 0.3);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .entries > div > .action.noop {
|
||||
background-color: rgba(96, 96, 96, 0.4);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action.block {
|
||||
background-color: rgba(192, 0, 0, 0.3);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .entries > div > .action.block {
|
||||
background-color: rgba(0, 19, 110, 0.4);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action.allow.own {
|
||||
background-color: rgba(0, 160, 0, 1);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .entries > div > .action.allow.own {
|
||||
background-color: rgba(255, 194, 57, 1);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action.noop.own {
|
||||
background-color: rgba(108, 108, 108, 1);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action.block.own {
|
||||
background-color: rgba(192, 0, 0, 1);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .entries > div > .action.block.own {
|
||||
background-color: rgba(0, 19, 110, 1);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action > span {
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action > span {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
display: inline-block;
|
||||
|
@ -381,31 +411,67 @@ body.colorBlind #urlFilteringMenu .entries > div > .action.block.own {
|
|||
visibility: hidden;
|
||||
width: 33.33%;
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action > span:before {
|
||||
content: '\00A0';
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.allow {
|
||||
background-color: rgba(0, 160, 0, 0.3);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action:not(.own):hover > span {
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.allow {
|
||||
background-color: rgba(255, 194, 57, 0.4);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.noop {
|
||||
background-color: rgba(108, 108, 108, 0.3);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.noop {
|
||||
background-color: rgba(96, 96, 96, 0.4);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.block {
|
||||
background-color: rgba(192, 0, 0, 0.3);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.block {
|
||||
background-color: rgba(0, 19, 110, 0.4);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.own.allow {
|
||||
background-color: rgba(0, 160, 0, 1);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.own.allow {
|
||||
background-color: rgba(255, 194, 57, 1);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.own.noop {
|
||||
background-color: rgba(108, 108, 108, 1);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.own.block {
|
||||
background-color: rgba(192, 0, 0, 1);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.entries tr.entry > td > div.action.own.block {
|
||||
background-color: rgba(0, 19, 110, 1);
|
||||
}
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action:not(.own):hover > span {
|
||||
opacity: 0.2;
|
||||
visibility: visible;
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action:not(.own):hover > span:hover {
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action:not(.own):hover > span:hover {
|
||||
opacity: 0.75;
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action > .allow {
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action > span.allow {
|
||||
background-color: rgb(0, 160, 0);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .entries > div > .action > .allow {
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.entries tr.entry > td > div.action > span.allow {
|
||||
background-color: rgb(255, 194, 57);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action > .noop {
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action > span.noop {
|
||||
background-color: rgb(108, 108, 108);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .action > .block {
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td > div.action > span.block {
|
||||
background-color: rgb(192, 0, 0);
|
||||
}
|
||||
body.colorBlind #urlFilteringMenu .entries > div > .action > .block {
|
||||
body.colorBlind #urlFilteringMenu .dialog > div.entries tr.entry > td > div.action > span.block {
|
||||
background-color: rgb(0, 19, 110);
|
||||
}
|
||||
#urlFilteringMenu .entries > div > .url {
|
||||
padding: 0 0.25em;
|
||||
#urlFilteringMenu .dialog > div.entries tr.entry > td.url {
|
||||
overflow: hidden;
|
||||
padding-left: 4px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -144,13 +144,14 @@ return {
|
|||
noopFunc: function(){},
|
||||
|
||||
apiErrorCount: 0,
|
||||
contextMenuTarget: '',
|
||||
contextMenuClientX: -1,
|
||||
contextMenuClientY: -1,
|
||||
|
||||
epickerTarget: '',
|
||||
epickerEprom: null,
|
||||
|
||||
scriptlets: {
|
||||
},
|
||||
|
||||
// so that I don't have to care for last comma
|
||||
dummy: 0
|
||||
};
|
||||
|
|
|
@ -92,6 +92,16 @@ var classNameFromTabId = function(tabId) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var tabIdFromClassName = function(className) {
|
||||
var matches = className.match(/(?:^| )tab_([^ ]+)(?: |$)/);
|
||||
if ( matches === null ) {
|
||||
return '';
|
||||
}
|
||||
return matches[1];
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var retextFromStaticFilteringResult = function(result) {
|
||||
var retext = result.slice(3);
|
||||
var pos = retext.indexOf('$');
|
||||
|
@ -267,23 +277,26 @@ var renderNetLogEntry = function(tr, entry) {
|
|||
tr.classList.add(filterCat.slice(0, 2));
|
||||
}
|
||||
|
||||
td = tr.cells[2];
|
||||
var filterText = filter.slice(3);
|
||||
if ( filter.lastIndexOf('sa', 0) === 0 ) {
|
||||
filterText = '@@' + filterText;
|
||||
}
|
||||
tr.cells[2].textContent = filterText;
|
||||
|
||||
td = tr.cells[3];
|
||||
if ( filter.charAt(1) === 'b' ) {
|
||||
tr.classList.add('blocked');
|
||||
td.textContent = '--';
|
||||
} else if ( filter.charAt(1) === 'a' ) {
|
||||
tr.classList.add('allowed');
|
||||
td.textContent = '++';
|
||||
} else if ( filter.charAt(1) === 'n' ) {
|
||||
tr.classList.add('nooped');
|
||||
td.textContent = '**';
|
||||
} else {
|
||||
td.textContent = '';
|
||||
}
|
||||
|
||||
var filterText = filter.slice(3);
|
||||
if ( filter.lastIndexOf('sa', 0) === 0 ) {
|
||||
filterText = '@@' + filterText;
|
||||
}
|
||||
|
||||
tr.cells[3].textContent = filterText;
|
||||
tr.cells[4].textContent = (prettyRequestTypes[type] || type);
|
||||
tr.cells[5].appendChild(nodeFromURL(url, filter));
|
||||
};
|
||||
|
@ -540,14 +553,11 @@ var pageSelectorChanged = function() {
|
|||
|
||||
var reloadTab = function() {
|
||||
var tabClass = document.getElementById('pageSelector').value;
|
||||
var matches = tabClass.match(/^tab_(.+)$/);
|
||||
if ( matches === null ) {
|
||||
var tabId = tabIdFromClassName(tabClass);
|
||||
if ( tabId === 'bts' || tabId === '' ) {
|
||||
return;
|
||||
}
|
||||
if ( matches[1] === 'bts' ) {
|
||||
return;
|
||||
}
|
||||
messager.send({ what: 'reloadTab', tabId: matches[1] });
|
||||
messager.send({ what: 'reloadTab', tabId: tabId });
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -577,11 +587,11 @@ var onMaxEntriesChanged = function() {
|
|||
|
||||
var urlFilteringMenu = (function() {
|
||||
var menu = document.querySelector('#urlFilteringMenu');
|
||||
var menuDialog = menu.querySelector('.dialog');
|
||||
var selectContext = menuDialog.querySelector('.context');
|
||||
var selectType = menuDialog.querySelector('.type');
|
||||
var menuEntries = menu.querySelector('.entries');
|
||||
var dialog = menu.querySelector('.dialog');
|
||||
var selectContext = dialog.querySelector('.context');
|
||||
var selectType = dialog.querySelector('.type');
|
||||
var menuURLs = [];
|
||||
var tabId = '';
|
||||
|
||||
var removeAllChildren = function(node) {
|
||||
while ( node.firstChild ) {
|
||||
|
@ -603,7 +613,7 @@ var urlFilteringMenu = (function() {
|
|||
continue;
|
||||
}
|
||||
colorEntry = colorEntries[url];
|
||||
node = menu.querySelector('.entries [data-url="' + url + '"]');
|
||||
node = menu.querySelector('.entry .action[data-url="' + url + '"]');
|
||||
if ( node === null ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -698,6 +708,45 @@ var urlFilteringMenu = (function() {
|
|||
}, colorize);
|
||||
return;
|
||||
}
|
||||
|
||||
// Force a reload of the tab
|
||||
if ( target.classList.contains('reload') ) {
|
||||
messager.send({
|
||||
what: 'reloadTab',
|
||||
tabId: tabId
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Hightlight corresponding element in target web page
|
||||
if ( target.classList.contains('picker') ) {
|
||||
messager.send({
|
||||
what: 'launchElementPicker',
|
||||
tabId: tabId,
|
||||
targetURL: 'img\t' + menuURLs[0],
|
||||
select: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Enable interactive tools if resource was not blocked
|
||||
var createPreviewIf = function(type, url) {
|
||||
var preview = null;
|
||||
|
||||
if ( type === 'image' ) {
|
||||
preview = document.createElement('img');
|
||||
preview.setAttribute('src', url);
|
||||
}
|
||||
|
||||
// More...
|
||||
|
||||
var container = dialog.querySelector('table.toolbar td.preview');
|
||||
container.classList.toggle('hide', preview === null);
|
||||
if ( preview === null ) {
|
||||
return;
|
||||
}
|
||||
container.appendChild(preview);
|
||||
};
|
||||
|
||||
var toggleOn = function(ev) {
|
||||
|
@ -715,6 +764,8 @@ var urlFilteringMenu = (function() {
|
|||
return;
|
||||
}
|
||||
|
||||
tabId = tabIdFromClassName(tr.className);
|
||||
|
||||
var pos, option;
|
||||
|
||||
// Fill context selector
|
||||
|
@ -747,9 +798,14 @@ var urlFilteringMenu = (function() {
|
|||
return;
|
||||
}
|
||||
|
||||
uDom(dialog).descendants('.picker').toggleClass(
|
||||
'hide',
|
||||
type !== 'image' || /(?:^| )[dlsu]b(?: |$)/.test(tr.className)
|
||||
);
|
||||
|
||||
// Shortest URL which for a valid URL filtering rule
|
||||
var candidateRootURL = matches[1] + matches[2];
|
||||
menuURLs.push(candidateRootURL);
|
||||
menuURLs.unshift(candidateRootURL);
|
||||
var candidatePath = matches[3] || '';
|
||||
pos = candidatePath.charAt(0) === '/' ? 1 : 0;
|
||||
while ( pos < candidatePath.length ) {
|
||||
|
@ -757,34 +813,33 @@ var urlFilteringMenu = (function() {
|
|||
if ( pos === -1 ) {
|
||||
pos = candidatePath.length;
|
||||
}
|
||||
menuURLs.push(candidateRootURL + candidatePath.slice(0, pos));
|
||||
menuURLs.unshift(candidateRootURL + candidatePath.slice(0, pos));
|
||||
}
|
||||
var candidateQuery = matches[4] || '';
|
||||
if ( candidateQuery !== '') {
|
||||
menuURLs.push(candidateRootURL + candidatePath + candidateQuery);
|
||||
menuURLs.unshift(candidateRootURL + candidatePath + candidateQuery);
|
||||
}
|
||||
|
||||
// Create preview whenever possible
|
||||
createPreviewIf(type, menuURLs[0]);
|
||||
|
||||
// Fill menu
|
||||
var menuEntryTemplate = document.querySelector('#templates .urlFilteringMenuEntry');
|
||||
var menuEntryTemplate = dialog.querySelector('table.toolbar tr.entry');
|
||||
var tbody = dialog.querySelector('div.entries tbody');
|
||||
|
||||
// Adding URL filtering rules
|
||||
var i = menuURLs.length;
|
||||
var url, menuEntry;
|
||||
while ( i-- ) {
|
||||
for ( var i = 0; i < menuURLs.length; i++ ) {
|
||||
url = menuURLs[i];
|
||||
menuEntry = menuEntryTemplate.cloneNode(true);
|
||||
menuEntry.children[0].setAttribute('data-url', url);
|
||||
menuEntry.children[1].textContent = url;
|
||||
menuEntries.appendChild(menuEntry);
|
||||
menuEntry.cells[0].children[0].setAttribute('data-url', url);
|
||||
menuEntry.cells[1].textContent = url;
|
||||
tbody.appendChild(menuEntry);
|
||||
}
|
||||
|
||||
colorize();
|
||||
|
||||
var rect = td.getBoundingClientRect();
|
||||
menuDialog.style.setProperty('left', rect.left + 'px');
|
||||
menuDialog.style.setProperty('top', rect.bottom + 'px');
|
||||
document.body.appendChild(menu);
|
||||
|
||||
menu.addEventListener('click', onClick, true);
|
||||
selectContext.addEventListener('change', colorize);
|
||||
selectType.addEventListener('change', colorize);
|
||||
|
@ -794,7 +849,8 @@ var urlFilteringMenu = (function() {
|
|||
if ( menu.parentNode === null ) {
|
||||
return;
|
||||
}
|
||||
removeAllChildren(menuEntries);
|
||||
uDom('table.toolbar td.preview > *').remove();
|
||||
uDom(dialog).descendants('div.entries tr').remove();
|
||||
selectContext.removeEventListener('change', colorize);
|
||||
selectType.removeEventListener('change', colorize);
|
||||
menu.removeEventListener('click', onClick, true);
|
||||
|
@ -845,8 +901,7 @@ var rowFilterer = (function() {
|
|||
continue;
|
||||
}
|
||||
// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions
|
||||
reStr = rawPart.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
|
||||
.replace(/\*/g, '.*');
|
||||
reStr = rawPart.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
if ( hardBeg ) {
|
||||
reStr = '(?:^|\\s)' + reStr;
|
||||
}
|
||||
|
@ -1003,7 +1058,7 @@ var popupManager = (function() {
|
|||
var popupObserver = null;
|
||||
var style = null;
|
||||
var styleTemplate = [
|
||||
'tr:not(.tab_{{tabId}}) {',
|
||||
'#content tr:not(.tab_{{tabId}}) {',
|
||||
'cursor: not-allowed;',
|
||||
'opacity: 0.2;',
|
||||
'}'
|
||||
|
@ -1036,11 +1091,10 @@ var popupManager = (function() {
|
|||
|
||||
var toggleOn = function(td) {
|
||||
var tr = td.parentNode;
|
||||
var matches = tr.className.match(/(?:^| )tab_([^ ]+)/);
|
||||
if ( matches === null ) {
|
||||
realTabId = localTabId = tabIdFromClassName(tr.className);
|
||||
if ( realTabId === '' ) {
|
||||
return;
|
||||
}
|
||||
realTabId = localTabId = matches[1];
|
||||
if ( localTabId === 'bts' ) {
|
||||
realTabId = noTabId;
|
||||
}
|
||||
|
@ -1115,7 +1169,7 @@ uDom.onLoad(function() {
|
|||
uDom('#clear').on('click', clearBuffer);
|
||||
uDom('#maxEntries').on('change', onMaxEntriesChanged);
|
||||
uDom('#content table').on('click', 'tr.canMtx > td:nth-of-type(2)', popupManager.toggleOn);
|
||||
uDom('#content').on('click', 'tr.cat_net > td:nth-of-type(3)', urlFilteringMenu.toggleOn);
|
||||
uDom('#content').on('click', 'tr.cat_net > td:nth-of-type(4)', urlFilteringMenu.toggleOn);
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -83,10 +83,20 @@ var onMessage = function(request, sender, callback) {
|
|||
response = µb.userSettings;
|
||||
break;
|
||||
|
||||
case 'launchElementPicker':
|
||||
// Launched from some auxiliary pages, clear context menu coords.
|
||||
µb.contextMenuClientX = µb.contextMenuClientY = -1;
|
||||
µb.elementPickerExec(request.tabId, request.targetURL);
|
||||
break;
|
||||
|
||||
case 'gotoURL':
|
||||
vAPI.tabs.open(request.details);
|
||||
break;
|
||||
|
||||
case 'scriptletGotoImageURL':
|
||||
µb.scriptletGotoImageURL(request);
|
||||
break;
|
||||
|
||||
case 'reloadTab':
|
||||
if ( vAPI.isBehindTheSceneTabId(request.tabId) === false ) {
|
||||
vAPI.tabs.reload(request.tabId);
|
||||
|
@ -322,16 +332,6 @@ var onMessage = function(request, sender, callback) {
|
|||
var response;
|
||||
|
||||
switch ( request.what ) {
|
||||
case 'gotoPick':
|
||||
// Picker launched from popup: clear context menu args
|
||||
µb.contextMenuClientX = -1;
|
||||
µb.contextMenuClientY = -1;
|
||||
µb.elementPickerExec(request.tabId);
|
||||
if ( request.select && vAPI.tabs.select ) {
|
||||
vAPI.tabs.select(request.tabId);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'hasPopupContentChanged':
|
||||
pageStore = µb.pageStoreFromTabId(request.tabId);
|
||||
var lastModified = pageStore ? pageStore.contentLastModified : 0;
|
||||
|
@ -542,80 +542,6 @@ vAPI.messaging.listen('contentscript-end.js', onMessage);
|
|||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// cosmetic-*.js
|
||||
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var µb = µBlock;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var logCosmeticFilters = function(tabId, details) {
|
||||
if ( µb.logger.isEnabled() === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selectors = details.matchedSelectors;
|
||||
|
||||
selectors.sort();
|
||||
|
||||
for ( var i = 0; i < selectors.length; i++ ) {
|
||||
µb.logger.writeOne(
|
||||
tabId,
|
||||
'cosmetic',
|
||||
'cb:##' + selectors[i],
|
||||
'dom',
|
||||
details.pageURL
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onMessage = function(request, sender, callback) {
|
||||
// Async
|
||||
switch ( request.what ) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Sync
|
||||
var response;
|
||||
|
||||
var tabId = sender && sender.tab ? sender.tab.id : 0;
|
||||
|
||||
switch ( request.what ) {
|
||||
case 'liveCosmeticFilteringData':
|
||||
var pageStore = µb.pageStoreFromTabId(tabId);
|
||||
if ( pageStore ) {
|
||||
pageStore.hiddenElementCount = request.filteredElementCount;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'logCosmeticFilteringData':
|
||||
logCosmeticFilters(tabId, request);
|
||||
break;
|
||||
|
||||
default:
|
||||
return vAPI.messaging.UNHANDLED;
|
||||
}
|
||||
|
||||
callback(response);
|
||||
};
|
||||
|
||||
vAPI.messaging.listen('cosmetic-*.js', onMessage);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// element-picker.js
|
||||
|
||||
(function() {
|
||||
|
@ -654,13 +580,13 @@ var onMessage = function(request, sender, callback) {
|
|||
|
||||
callback({
|
||||
frameContent: this.responseText.replace(reStrings, replacer),
|
||||
target: µb.contextMenuTarget,
|
||||
target: µb.epickerTarget,
|
||||
clientX: µb.contextMenuClientX,
|
||||
clientY: µb.contextMenuClientY,
|
||||
eprom: µb.epickerEprom
|
||||
});
|
||||
|
||||
µb.contextMenuTarget = '';
|
||||
µb.epickerTarget = '';
|
||||
µb.contextMenuClientX = -1;
|
||||
µb.contextMenuClientY = -1;
|
||||
};
|
||||
|
@ -1363,3 +1289,80 @@ vAPI.messaging.listen('document-blocked.js', onMessage);
|
|||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// scriptlets
|
||||
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var µb = µBlock;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var logCosmeticFilters = function(tabId, details) {
|
||||
if ( µb.logger.isEnabled() === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selectors = details.matchedSelectors;
|
||||
|
||||
selectors.sort();
|
||||
|
||||
for ( var i = 0; i < selectors.length; i++ ) {
|
||||
µb.logger.writeOne(
|
||||
tabId,
|
||||
'cosmetic',
|
||||
'cb:##' + selectors[i],
|
||||
'dom',
|
||||
details.pageURL
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onMessage = function(request, sender, callback) {
|
||||
// Async
|
||||
switch ( request.what ) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Sync
|
||||
var response;
|
||||
var tabId = sender && sender.tab ? sender.tab.id : 0;
|
||||
|
||||
switch ( request.what ) {
|
||||
case 'gotoImageURL':
|
||||
response = µb.scriptlets.gotoImageURL;
|
||||
break;
|
||||
|
||||
case 'liveCosmeticFilteringData':
|
||||
var pageStore = µb.pageStoreFromTabId(tabId);
|
||||
if ( pageStore ) {
|
||||
pageStore.hiddenElementCount = request.filteredElementCount;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'logCosmeticFilteringData':
|
||||
logCosmeticFilters(tabId, request);
|
||||
break;
|
||||
|
||||
default:
|
||||
return vAPI.messaging.UNHANDLED;
|
||||
}
|
||||
|
||||
callback(response);
|
||||
};
|
||||
|
||||
vAPI.messaging.listen('scriptlets', onMessage);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -508,12 +508,14 @@ PageStore.prototype.filterRequest = function(context) {
|
|||
// evaluation of static filtering.
|
||||
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
|
||||
µb.sessionFirewall.evaluateCellZY( context.rootHostname, context.requestHostname, context.requestType);
|
||||
if ( µb.sessionFirewall.mustBlockOrAllow() ) {
|
||||
result = µb.sessionFirewall.toFilterString();
|
||||
}
|
||||
}
|
||||
|
||||
// Static filtering never override dynamic filtering
|
||||
if ( result === '' || result.charAt(1) === 'n' ) {
|
||||
result = µb.staticNetFilteringEngine.matchString(context);
|
||||
result = µb.staticNetFilteringEngine.matchString(context) || result;
|
||||
}
|
||||
|
||||
//console.debug('cache MISS: PageStore.filterRequest("%s")', context.requestURL);
|
||||
|
@ -546,12 +548,14 @@ PageStore.prototype.filterRequestNoCache = function(context) {
|
|||
// evaluation of static filtering.
|
||||
if ( result === '' && µb.userSettings.advancedUserEnabled ) {
|
||||
µb.sessionFirewall.evaluateCellZY(context.rootHostname, context.requestHostname, context.requestType);
|
||||
if ( µb.sessionFirewall.mustBlockOrAllow() ) {
|
||||
result = µb.sessionFirewall.toFilterString();
|
||||
}
|
||||
}
|
||||
|
||||
// Static filtering never override dynamic filtering
|
||||
if ( result === '' || result.charAt(1) === 'n' ) {
|
||||
result = µb.staticNetFilteringEngine.matchString(context);
|
||||
result = µb.staticNetFilteringEngine.matchString(context) || result;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -504,10 +504,9 @@ var toggleNetFilteringSwitch = function(ev) {
|
|||
|
||||
var gotoPick = function() {
|
||||
messager.send({
|
||||
what: 'gotoPick',
|
||||
tabId: popupData.tabId,
|
||||
select: true
|
||||
});
|
||||
what: 'launchElementPicker',
|
||||
tabId: popupData.tabId
|
||||
});
|
||||
|
||||
vAPI.closePopup();
|
||||
};
|
||||
|
|
|
@ -36,7 +36,7 @@ if ( document instanceof HTMLDocument === false ) {
|
|||
}
|
||||
|
||||
// This can happen
|
||||
if ( !vAPI ) {
|
||||
if ( typeof vAPI !== 'object' ) {
|
||||
//console.debug('cosmetic-logger.js > vAPI not found');
|
||||
return;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ vAPI.loggedSelectors = loggedSelectors;
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var localMessager = vAPI.messaging.channel('cosmetic-*.js');
|
||||
var localMessager = vAPI.messaging.channel('scriptlets');
|
||||
|
||||
localMessager.send({
|
||||
what: 'logCosmeticFilteringData',
|
|
@ -36,7 +36,7 @@ if ( document instanceof HTMLDocument === false ) {
|
|||
}
|
||||
|
||||
// This can happen
|
||||
if ( !vAPI ) {
|
||||
if ( typeof vAPI !== 'object' ) {
|
||||
//console.debug('cosmetic-survey.js > vAPI not found');
|
||||
return;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ if ( injectedSelectors.length !== 0 ) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var localMessager = vAPI.messaging.channel('cosmetic-*.js');
|
||||
var localMessager = vAPI.messaging.channel('scriptlets');
|
||||
|
||||
localMessager.send({
|
||||
what: 'liveCosmeticFilteringData',
|
|
@ -917,10 +917,17 @@ var startPicker = function(details) {
|
|||
if ( src !== url ) {
|
||||
continue;
|
||||
}
|
||||
elem.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
filtersFromElement(elem);
|
||||
showDialog({ modifier: true });
|
||||
return;
|
||||
}
|
||||
|
||||
// A target was specified, but it wasn't found: abort.
|
||||
stopPicker();
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
|
@ -283,8 +283,14 @@ var matchWhitelistDirective = function(url, hostname, directive) {
|
|||
/******************************************************************************/
|
||||
|
||||
µBlock.elementPickerExec = function(tabId, targetElement) {
|
||||
if ( vAPI.isBehindTheSceneTabId(tabId) ) {
|
||||
return;
|
||||
}
|
||||
this.epickerTarget = targetElement || '';
|
||||
vAPI.tabs.injectScript(tabId, { file: 'js/element-picker.js' });
|
||||
vAPI.tabs.injectScript(tabId, { file: 'js/scriptlets/element-picker.js' });
|
||||
if ( typeof vAPI.tabs.select === 'function' ) {
|
||||
vAPI.tabs.select(tabId);
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -364,7 +370,7 @@ var matchWhitelistDirective = function(url, hostname, directive) {
|
|||
// Take action if needed
|
||||
if ( details.name === 'no-cosmetic-filtering' ) {
|
||||
vAPI.tabs.injectScript(details.tabId, {
|
||||
file: 'js/cosmetic-' + (details.state ? 'off' : 'on') + '.js',
|
||||
file: 'js/scriptlets/cosmetic-' + (details.state ? 'off' : 'on') + '.js',
|
||||
allFrames: true
|
||||
});
|
||||
return;
|
||||
|
@ -382,7 +388,7 @@ var matchWhitelistDirective = function(url, hostname, directive) {
|
|||
callback();
|
||||
return;
|
||||
}
|
||||
vAPI.tabs.injectScript(tabId, { file: 'js/cosmetic-survey.js' }, callback);
|
||||
vAPI.tabs.injectScript(tabId, { file: 'js/scriptlets/cosmetic-survey.js' }, callback);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -392,7 +398,7 @@ var matchWhitelistDirective = function(url, hostname, directive) {
|
|||
|
||||
var injectNow = function(tabId) {
|
||||
delete tabIdToTimerMap[tabId];
|
||||
vAPI.tabs.injectScript(tabId, { file: 'js/cosmetic-logger.js' });
|
||||
vAPI.tabs.injectScript(tabId, { file: 'js/scriptlets/cosmetic-logger.js' });
|
||||
};
|
||||
|
||||
var injectAsync = function(tabId) {
|
||||
|
@ -410,4 +416,14 @@ var matchWhitelistDirective = function(url, hostname, directive) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.scriptletGotoImageURL = function(details) {
|
||||
if ( vAPI.isBehindTheSceneTabId(details.tabId) ) {
|
||||
return;
|
||||
}
|
||||
this.scriptlets.gotoImageURL = details.url;
|
||||
vAPI.tabs.injectScript(details.tabId, { file: 'js/scriptlets/goto-img.js' });
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
})();
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
</div>
|
||||
|
||||
<div id="content">
|
||||
<style id="tabFilterer"></style>
|
||||
<style id="popupFilterer"></style>
|
||||
<style id="tabFilterer" scoped></style>
|
||||
<style id="popupFilterer" scoped></style>
|
||||
<table>
|
||||
<colgroup><col><col><col><col><col></colgroup>
|
||||
<tbody></tbody>
|
||||
|
@ -43,15 +43,31 @@
|
|||
<div id="hiddenTemplate"><span style="display:none;"></span></div>
|
||||
<div id="urlFilteringMenu">
|
||||
<div class="dialog">
|
||||
<div>
|
||||
<span class="fa save"></span>
|
||||
<label>Context: <select class="context"></select></label> 
|
||||
<label>Type: <select class="type"><option><option value="*">*</select></label>
|
||||
<table class="toolbar">
|
||||
<colgroup><col><col></colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2" class="hide preview">
|
||||
<tr>
|
||||
<td><span class="fa save"></span>
|
||||
<td><label>Context: <select class="context"></select></label> 
|
||||
<label>Type: <select class="type"><option><option value="*">*</select></label> 
|
||||
<span class="fa reload"></span> <span class="fa picker"></span>
|
||||
<tr class="entry">
|
||||
<td><div class="action"><span class="allow"> </span><span class="noop"> </span><span class="block"> </span></div>
|
||||
<td class="url">
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="header">Dynamic URL filtering</div>
|
||||
<div class="entries">
|
||||
<table>
|
||||
<colgroup><col><col></colgroup>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="entries"></div>
|
||||
<!-- <div class="header">Static URL filtering (TBD)</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="urlFilteringMenuEntry"><span class="action"><span class="allow"></span><span class="noop"></span><span class="block"></span></span><span class="url"></span></div>
|
||||
</div>
|
||||
|
||||
<script src="js/vapi-common.js"></script>
|
||||
|
|
Loading…
Reference in New Issue