diff --git a/platform/chromium/vapi-background.js b/platform/chromium/vapi-background.js
index 9c9f23106..9381cb84d 100644
--- a/platform/chromium/vapi-background.js
+++ b/platform/chromium/vapi-background.js
@@ -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
diff --git a/src/css/common.css b/src/css/common.css
index f4ed7653a..31eec4550 100644
--- a/src/css/common.css
+++ b/src/css/common.css
@@ -10,7 +10,7 @@
font-style: normal;
font-weight: normal;
line-height: 1;
- vertical-align: baseline;
+ vertical-align: middle;
}
body {
background-color: white;
diff --git a/src/css/logger-ui.css b/src/css/logger-ui.css
index cb0d6cd4c..7ad418de4 100644
--- a/src/css/logger-ui.css
+++ b/src/css/logger-ui.css
@@ -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;
}
diff --git a/src/js/background.js b/src/js/background.js
index 30f419e03..30539c3bc 100644
--- a/src/js/background.js
+++ b/src/js/background.js
@@ -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
};
diff --git a/src/js/logger-ui.js b/src/js/logger-ui.js
index c889537d1..a13e2928b 100644
--- a/src/js/logger-ui.js
+++ b/src/js/logger-ui.js
@@ -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);
});
/******************************************************************************/
diff --git a/src/js/messaging.js b/src/js/messaging.js
index 0dc9af7d7..f9c050d5a 100644
--- a/src/js/messaging.js
+++ b/src/js/messaging.js
@@ -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);
+
+/******************************************************************************/
+
+})();
+
+/******************************************************************************/
diff --git a/src/js/pagestore.js b/src/js/pagestore.js
index 0d19baa58..5bc93fda2 100644
--- a/src/js/pagestore.js
+++ b/src/js/pagestore.js
@@ -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);
- result = µb.sessionFirewall.toFilterString();
+ 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);
- result = µb.sessionFirewall.toFilterString();
+ 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;
diff --git a/src/js/popup.js b/src/js/popup.js
index 7046841f2..a46287eec 100644
--- a/src/js/popup.js
+++ b/src/js/popup.js
@@ -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();
};
diff --git a/src/js/cosmetic-logger.js b/src/js/scriptlets/cosmetic-logger.js
similarity index 96%
rename from src/js/cosmetic-logger.js
rename to src/js/scriptlets/cosmetic-logger.js
index d038d1af6..62f6b29a5 100644
--- a/src/js/cosmetic-logger.js
+++ b/src/js/scriptlets/cosmetic-logger.js
@@ -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',
diff --git a/src/js/cosmetic-off.js b/src/js/scriptlets/cosmetic-off.js
similarity index 100%
rename from src/js/cosmetic-off.js
rename to src/js/scriptlets/cosmetic-off.js
diff --git a/src/js/cosmetic-on.js b/src/js/scriptlets/cosmetic-on.js
similarity index 100%
rename from src/js/cosmetic-on.js
rename to src/js/scriptlets/cosmetic-on.js
diff --git a/src/js/cosmetic-survey.js b/src/js/scriptlets/cosmetic-survey.js
similarity index 96%
rename from src/js/cosmetic-survey.js
rename to src/js/scriptlets/cosmetic-survey.js
index 532bf9b65..f3e0890f8 100644
--- a/src/js/cosmetic-survey.js
+++ b/src/js/scriptlets/cosmetic-survey.js
@@ -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',
diff --git a/src/js/element-picker.js b/src/js/scriptlets/element-picker.js
similarity index 99%
rename from src/js/element-picker.js
rename to src/js/scriptlets/element-picker.js
index 46d0bee65..bb77b0c0e 100644
--- a/src/js/element-picker.js
+++ b/src/js/scriptlets/element-picker.js
@@ -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();
};
/******************************************************************************/
diff --git a/src/js/ublock.js b/src/js/ublock.js
index 053c9391f..e501d707b 100644
--- a/src/js/ublock.js
+++ b/src/js/ublock.js
@@ -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' });
+};
+
+/******************************************************************************/
+
})();
diff --git a/src/logger-ui.html b/src/logger-ui.html
index 85cfe30cb..9db6201bb 100644
--- a/src/logger-ui.html
+++ b/src/logger-ui.html
@@ -26,8 +26,8 @@