This commit is contained in:
Raymond Hill 2018-07-22 08:14:02 -04:00
parent 5f5cdf9bb4
commit d5f40b90f6
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
7 changed files with 114 additions and 64 deletions

View File

@ -588,8 +588,12 @@
"description":"Used in the static filtering wizard" "description":"Used in the static filtering wizard"
}, },
"loggerStaticFilteringFinderSentence1":{ "loggerStaticFilteringFinderSentence1":{
"message":"Static filter {{filter}} found in:", "message":"Static filter <code>{{filter}}</code> found in:",
"description":"Below this sentence, the filter lists in which the filter was found" "description":"Below this sentence, the filter list(s) in which the filter was found"
},
"loggerStaticFilteringFinderSentence2":{
"message":"Static filter <code>{{filter}}</code> could not be found in any of the currently enabled filter lists",
"description":"Message to show when a filter cannot be found in any filter lists"
}, },
"aboutChangelog":{ "aboutChangelog":{
"message":"Change log", "message":"Change log",

View File

@ -13,7 +13,6 @@
user-select: none; user-select: none;
-moz-user-select: none; -moz-user-select: none;
-webkit-user-select: none; -webkit-user-select: none;
vertical-align: middle;
} }
body { body {
background-color: white; background-color: white;

View File

@ -599,6 +599,18 @@ body.colorBlind #netFilteringDialog .dialog > div.containers > div.dynamic tr.e
#filterFinderDialog .dialog ul { #filterFinderDialog .dialog ul {
font-size: larger; font-size: larger;
} }
#filterFinderDialog .filterFinderListEntry a {
text-decoration: none;
}
#filterFinderDialog .filterFinderListEntry a.fa {
opacity: 0.8;
}
#filterFinderDialog .filterFinderListEntry a.fa:hover {
opacity: 1;
}
#filterFinderDialog .filterFinderListEntry a[href=""]:nth-of-type(2) {
display: none;
}
#filterFinderDialog .dialog > *:first-child { #filterFinderDialog .dialog > *:first-child {
margin-top: 0; margin-top: 0;
} }

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2016 Raymond Hill Copyright (C) 2014-present Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -94,7 +94,8 @@ var safeTextToDOM = function(text, parent) {
if ( text === '' ) { return; } if ( text === '' ) { return; }
// Fast path (most common). // Fast path (most common).
if ( text.indexOf('<') === -1 ) { if ( text.indexOf('<') === -1 ) {
return parent.appendChild(safeTextToTextNode(text)); parent.appendChild(safeTextToTextNode(text));
return;
} }
// Slow path. // Slow path.
// `<p>` no longer allowed. Code below can be remove once all <p>'s are // `<p>` no longer allowed. Code below can be remove once all <p>'s are
@ -102,7 +103,7 @@ var safeTextToDOM = function(text, parent) {
text = text.replace(/^<p>|<\/p>/g, '') text = text.replace(/^<p>|<\/p>/g, '')
.replace(/<p>/g, '\n\n'); .replace(/<p>/g, '\n\n');
// Parse allowed HTML tags. // Parse allowed HTML tags.
var matches = reSafeTags.exec(text); let matches = reSafeTags.exec(text);
if ( matches === null ) { if ( matches === null ) {
matches = reSafeLink.exec(text); matches = reSafeLink.exec(text);
if ( matches === null ) { if ( matches === null ) {
@ -114,7 +115,7 @@ var safeTextToDOM = function(text, parent) {
} }
} }
safeTextToDOM(matches[1], parent); safeTextToDOM(matches[1], parent);
var node = safeTextToTagNode(matches[2]) || parent; let node = safeTextToTagNode(matches[2]) || parent;
safeTextToDOM(matches[3], node); safeTextToDOM(matches[3], node);
parent.appendChild(node); parent.appendChild(node);
safeTextToDOM(matches[4], parent); safeTextToDOM(matches[4], parent);
@ -122,6 +123,42 @@ var safeTextToDOM = function(text, parent) {
/******************************************************************************/ /******************************************************************************/
vAPI.i18n.safeTemplateToDOM = function(id, dict, parent) {
if ( parent === undefined ) {
parent = document.createDocumentFragment();
}
let textin = vAPI.i18n(id);
if ( textin === '' ) {
return parent;
}
if ( textin.indexOf('{{') === -1 ) {
safeTextToDOM(textin, parent);
return parent;
}
let re = /\{\{\w+\}\}/g;
let textout = '';
for (;;) {
let match = re.exec(textin);
if ( match === null ) {
textout += textin;
break;
}
textout += textin.slice(0, match.index);
let prop = match[0].slice(2, -2);
if ( dict.hasOwnProperty(prop) ) {
textout += dict[prop].replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
} else {
textout += prop;
}
textin = textin.slice(re.lastIndex);
}
safeTextToDOM(textout, parent);
return parent;
};
/******************************************************************************/
// Helper to deal with the i18n'ing of HTML files. // Helper to deal with the i18n'ing of HTML files.
vAPI.i18n.render = function(context) { vAPI.i18n.render = function(context) {
var docu = document; var docu = document;

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. uBlock Origin - a browser extension to block requests.
Copyright (C) 2015-2018 Raymond Hill Copyright (C) 2015-present Raymond Hill
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -21,12 +21,12 @@
/* global uDom */ /* global uDom */
'use strict';
/******************************************************************************/ /******************************************************************************/
(function() { (function() {
'use strict';
/******************************************************************************/ /******************************************************************************/
var logger = self.logger = { var logger = self.logger = {
@ -1266,21 +1266,18 @@ var netFilteringManager = (function() {
/******************************************************************************/ /******************************************************************************/
var reverseLookupManager = (function() { var reverseLookupManager = (function() {
var reSentence1 = /\{\{filter\}\}/g; let filterFinderDialog = uDom.nodeFromId('filterFinderDialog');
var sentence1Template = vAPI.i18n('loggerStaticFilteringFinderSentence1'); let rawFilter = '';
var filterFinderDialog = uDom.nodeFromId('filterFinderDialog');
var removeAllChildren = function(node) { let removeAllChildren = function(node) {
while ( node.firstChild ) { while ( node.firstChild ) {
node.removeChild(node.firstChild); node.removeChild(node.firstChild);
} }
}; };
var onClick = function(ev) { // Clicking outside the dialog will close the dialog
var target = ev.target; let onClick = function(ev) {
if ( ev.target.classList.contains('modalDialog') ) {
// click outside the dialog proper
if ( target.classList.contains('modalDialog') ) {
toggleOff(); toggleOff();
return; return;
} }
@ -1288,42 +1285,30 @@ var reverseLookupManager = (function() {
ev.stopPropagation(); ev.stopPropagation();
}; };
var nodeFromFilter = function(filter, lists) { let nodeFromFilter = function(filter, lists) {
if ( Array.isArray(lists) === false || lists.length === 0 ) { if ( Array.isArray(lists) === false || lists.length === 0 ) {
return null; return;
} }
var node,
p = document.createElement('p');
reSentence1.lastIndex = 0; let p = document.createElement('p');
var matches = reSentence1.exec(sentence1Template);
if ( matches === null ) {
node = document.createTextNode(sentence1Template);
} else {
node = uDom.nodeFromSelector('#filterFinderDialogSentence1 > span').cloneNode(true);
node.childNodes[0].textContent = sentence1Template.slice(0, matches.index);
// https://github.com/gorhill/uBlock/issues/2753
node.childNodes[1].textContent = filter.length <= 1024
? filter
: filter.slice(0, 1023) + '…';
node.childNodes[2].textContent = sentence1Template.slice(reSentence1.lastIndex);
}
p.appendChild(node);
var ul = document.createElement('ul'); vAPI.i18n.safeTemplateToDOM(
var list, li; 'loggerStaticFilteringFinderSentence1',
for ( var i = 0; i < lists.length; i++ ) { { filter: filter },
list = lists[i]; p
li = document.createElement('li'); );
let ul = document.createElement('ul');
for ( let list of lists ) {
let li = document.querySelector('#filterFinderListEntry > li')
.cloneNode(true);
let a = li.querySelector('a:nth-of-type(1)');
a.href += encodeURIComponent(list.assetKey);
a.textContent = list.title;
if ( list.supportURL ) { if ( list.supportURL ) {
node = document.createElement('a'); a = li.querySelector('a:nth-of-type(2)');
node.textContent = list.title; a.setAttribute('href', list.supportURL);
node.setAttribute('href', list.supportURL);
node.setAttribute('target', '_blank');
} else {
node = document.createTextNode(list.title);
} }
li.appendChild(node);
ul.appendChild(li); ul.appendChild(li);
} }
p.appendChild(ul); p.appendChild(ul);
@ -1331,30 +1316,37 @@ var reverseLookupManager = (function() {
return p; return p;
}; };
var reverseLookupDone = function(response) { let reverseLookupDone = function(response) {
if ( typeof response !== 'object' ) { if ( response instanceof Object === false ) {
return; response = {};
} }
var dialog = filterFinderDialog.querySelector('.dialog'); let dialog = filterFinderDialog.querySelector('.dialog');
removeAllChildren(dialog); removeAllChildren(dialog);
for ( var filter in response ) { for ( let filter in response ) {
var p = nodeFromFilter(filter, response[filter]); let p = nodeFromFilter(filter, response[filter]);
if ( p === null ) { continue; } if ( p === undefined ) { continue; }
dialog.appendChild(p); dialog.appendChild(p);
} }
// https://github.com/gorhill/uBlock/issues/2179
if ( dialog.childElementCount === 0 ) {
vAPI.i18n.safeTemplateToDOM(
'loggerStaticFilteringFinderSentence2',
{ filter: rawFilter },
dialog
);
}
document.body.appendChild(filterFinderDialog); document.body.appendChild(filterFinderDialog);
filterFinderDialog.addEventListener('click', onClick, true); filterFinderDialog.addEventListener('click', onClick, true);
}; };
var toggleOn = function(ev) { let toggleOn = function(ev) {
var row = ev.target.parentElement; let row = ev.target.parentElement;
var rawFilter = row.cells[2].textContent; rawFilter = row.cells[2].textContent;
if ( rawFilter === '' ) { if ( rawFilter === '' ) { return; }
return;
}
if ( row.classList.contains('cat_net') ) { if ( row.classList.contains('cat_net') ) {
messaging.send( messaging.send(
@ -1379,9 +1371,10 @@ var reverseLookupManager = (function() {
} }
}; };
var toggleOff = function() { let toggleOff = function() {
filterFinderDialog.removeEventListener('click', onClick, true); filterFinderDialog.removeEventListener('click', onClick, true);
document.body.removeChild(filterFinderDialog); document.body.removeChild(filterFinderDialog);
rawFilter = '';
}; };
return { return {

View File

@ -238,6 +238,7 @@ var fromCosmeticFilter = function(details) {
response[found] = []; response[found] = [];
} }
response[found].push({ response[found].push({
assetKey: assetKey,
title: entry.title, title: entry.title,
supportURL: entry.supportURL supportURL: entry.supportURL
}); });

View File

@ -106,13 +106,17 @@
<div id="filterFinderDialog" class="modalDialog"> <div id="filterFinderDialog" class="modalDialog">
<div class="dialog"></div> <div class="dialog"></div>
</div> </div>
<ul id="filterFinderListEntry">
<li class="filterFinderListEntry">
<a href="asset-viewer.html?url=" target="_blank"></a>
<a href="" class="fa" target="_blank">&#xf015;</span></li>
</ul>
<div id="cosmeticFilteringDialog" class="modalDialog"> <div id="cosmeticFilteringDialog" class="modalDialog">
<div class="dialog"> <div class="dialog">
<textarea class="cosmeticFilters" value=""></textarea> <textarea class="cosmeticFilters" value=""></textarea>
<button id="createCosmeticFilters" class="custom important" type="button" data-i18n="pickerCreate"></button> <button id="createCosmeticFilters" class="custom important" type="button" data-i18n="pickerCreate"></button>
</div> </div>
</div> </div>
<div id="filterFinderDialogSentence1"><span><span></span><code></code><span></span></span></div>
</div> </div>
<script src="js/vapi.js"></script> <script src="js/vapi.js"></script>