mirror of https://github.com/gorhill/uBlock.git
Merge branch 'master' of https://github.com/gorhill/uBlock
This commit is contained in:
commit
6debe11315
|
@ -35,6 +35,10 @@
|
|||
"message":"µBlock — Network request log",
|
||||
"description":"Title for the network request log window"
|
||||
},
|
||||
"statsFilterPrompt":{
|
||||
"message":"filter log entries",
|
||||
"description": "English: filter log entries"
|
||||
},
|
||||
"aboutPageName":{
|
||||
"message":"About",
|
||||
"description":"appears as tab name in dashboard"
|
||||
|
|
|
@ -10,32 +10,35 @@ body {
|
|||
width: 100%;
|
||||
}
|
||||
#toolbar {
|
||||
padding: 8px 0;
|
||||
background-color: white;
|
||||
border: 0;
|
||||
box-sizing: border-box;
|
||||
height: 36px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
width: 4em;
|
||||
width: 100%;
|
||||
}
|
||||
#toolbar .button {
|
||||
background-color: white;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: large;
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
margin: 0;
|
||||
padding: 0.5em 0;
|
||||
padding: 8px;
|
||||
}
|
||||
#toolbar .button:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
body.filterOff #toolbar #filterButton {
|
||||
opacity: 0.25;
|
||||
}
|
||||
#content {
|
||||
width: calc(100% - 4em);
|
||||
}
|
||||
body[dir="ltr"] #content {
|
||||
margin-left: 4em;
|
||||
}
|
||||
body[dir="rtl"] #content {
|
||||
margin-right: 4em;
|
||||
margin-top: 36px;
|
||||
}
|
||||
#content table {
|
||||
border: 0;
|
||||
|
@ -55,6 +58,9 @@ body[dir="rtl"] #content {
|
|||
#content table tr.maindoc {
|
||||
background-color: #eee;
|
||||
}
|
||||
body:not(.filterOff) #content table tr.hidden {
|
||||
display: none;
|
||||
}
|
||||
#content table tr td {
|
||||
border: 1px solid #ccc;
|
||||
padding: 3px;
|
||||
|
@ -63,6 +69,7 @@ body[dir="rtl"] #content {
|
|||
#content table tr td:nth-of-type(1) {
|
||||
padding: 3px 0;
|
||||
text-align: center;
|
||||
white-space: pre;
|
||||
}
|
||||
#content table tr td:nth-of-type(2) {
|
||||
white-space: normal;
|
||||
|
|
|
@ -10,12 +10,15 @@
|
|||
<div id="toolbar">
|
||||
<span id="reload" class="button fa"></span>
|
||||
<span id="clear" class="button fa"></span>
|
||||
</div><!-- DO NOT REMOVE --><div id="content">
|
||||
<span id="filterButton" class="button fa"></span><input id="filterExpression" type="text" placeholder="statsFilterPrompt">
|
||||
</div>
|
||||
<div id="content">
|
||||
<table><tbody></tbody></table>
|
||||
</div>
|
||||
<script src="js/vapi-common.js"></script>
|
||||
<script src="js/vapi-client.js"></script>
|
||||
<script src="js/udom.js"></script>
|
||||
<script src="js/i18n.js"></script>
|
||||
<script src="js/devtool-log.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -85,7 +85,7 @@ return {
|
|||
|
||||
// read-only
|
||||
systemSettings: {
|
||||
compiledMagic: 'fkaywfqahncj',
|
||||
compiledMagic: 'shztbfhkfjit',
|
||||
selfieMagic: 'spqmeuaftfra'
|
||||
},
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ var doc = document;
|
|||
var body = doc.body;
|
||||
var tbody = doc.querySelector('#content tbody');
|
||||
var rowJunkyard = [];
|
||||
var reFilter = null;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -101,15 +102,15 @@ var renderLogEntry = function(entry) {
|
|||
var tr = createRow();
|
||||
if ( entry.result.charAt(1) === 'b' ) {
|
||||
tr.classList.add('blocked');
|
||||
tr.cells[0].textContent = '\u2009\u2212\u2009';
|
||||
tr.cells[0].textContent = ' \u2212\u00A0';
|
||||
} else if ( entry.result.charAt(1) === 'a' ) {
|
||||
tr.classList.add('allowed');
|
||||
if ( entry.result.charAt(0) === 'm' ) {
|
||||
tr.classList.add('mirrored');
|
||||
}
|
||||
tr.cells[0].textContent = '\u2009+\u2009';
|
||||
tr.cells[0].textContent = ' +\u00A0';
|
||||
} else {
|
||||
tr.cells[0].textContent = '\u2009\u00A0\u2009';
|
||||
tr.cells[0].textContent = ' ';
|
||||
}
|
||||
if ( entry.type === 'main_frame' ) {
|
||||
tr.classList.add('maindoc');
|
||||
|
@ -118,9 +119,10 @@ var renderLogEntry = function(entry) {
|
|||
if ( entry.result.lastIndexOf('sa', 0) === 0 ) {
|
||||
filterText = '@@' + filterText;
|
||||
}
|
||||
tr.cells[1].textContent = filterText;
|
||||
tr.cells[2].textContent = entry.type;
|
||||
tr.cells[1].textContent = filterText + ' ';
|
||||
tr.cells[2].textContent = entry.type + ' ';
|
||||
vAPI.insertHTML(tr.cells[3], renderURL(entry.url, entry.result));
|
||||
applyFilterToRow(tr);
|
||||
tbody.insertBefore(tr, tbody.firstChild);
|
||||
};
|
||||
|
||||
|
@ -196,6 +198,102 @@ var reloadTab = function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var applyFilterToRow = function(row) {
|
||||
var re = reFilter;
|
||||
if ( re === null || re.test(row.textContent) ) {
|
||||
row.classList.remove('hidden');
|
||||
} else {
|
||||
row.classList.add('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var applyFilter = function() {
|
||||
if ( reFilter === null ) {
|
||||
unapplyFilter();
|
||||
return;
|
||||
}
|
||||
var row = document.querySelector('#content tr');
|
||||
if ( row === null ) {
|
||||
return;
|
||||
}
|
||||
var re = reFilter;
|
||||
while ( row !== null ) {
|
||||
if ( re.test(row.textContent) ) {
|
||||
row.classList.remove('hidden');
|
||||
} else {
|
||||
row.classList.add('hidden');
|
||||
}
|
||||
row = row.nextSibling;
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var unapplyFilter = function() {
|
||||
var row = document.querySelector('#content tr');
|
||||
if ( row === null ) {
|
||||
return;
|
||||
}
|
||||
while ( row !== null ) {
|
||||
row.classList.remove('hidden');
|
||||
row = row.nextSibling;
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onFilterButton = function() {
|
||||
uDom('body').toggleClass('filterOff');
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onFilterChanged = function() {
|
||||
var filterRaw = uDom('#filterExpression').val().trim();
|
||||
|
||||
if ( filterRaw === '') {
|
||||
reFilter = null;
|
||||
unapplyFilter();
|
||||
return;
|
||||
}
|
||||
|
||||
var filterParts = filterRaw
|
||||
.replace(/^\s*-(\s+|$)/, '−\xA0')
|
||||
.replace(/^\s*\\+(\s+|$)/, '\\+\xA0')
|
||||
.split(/\s+/);
|
||||
var n = filterParts.length;
|
||||
for ( var i = 0; i < n; i++ ) {
|
||||
filterParts[i] = filterParts[i].replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
reFilter = new RegExp(filterParts.join('.*\\s+.*'));
|
||||
|
||||
applyFilter();
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var onFilterChangedAsync = (function() {
|
||||
var timer = null;
|
||||
|
||||
var commit = function() {
|
||||
timer = null;
|
||||
onFilterChanged();
|
||||
};
|
||||
|
||||
var changed = function() {
|
||||
if ( timer !== null ) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timer = setTimeout(commit, 750);
|
||||
};
|
||||
|
||||
return changed;
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uDom.onLoad(function() {
|
||||
// Extract the tab id of the page we need to pull the log
|
||||
var matches = window.location.search.match(/[\?&]tabId=([^&]+)/);
|
||||
|
@ -207,6 +305,8 @@ uDom.onLoad(function() {
|
|||
|
||||
uDom('#reload').on('click', reloadTab);
|
||||
uDom('#clear').on('click', clearBuffer);
|
||||
uDom('#filterButton').on('click', onFilterButton);
|
||||
uDom('#filterExpression').on('input', onFilterChangedAsync);
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -36,6 +36,12 @@ uDom.onLoad(function() {
|
|||
elem.attr('title', title);
|
||||
}
|
||||
});
|
||||
uDom('[placeholder]').forEach(function(elem) {
|
||||
var placeholder = vAPI.i18n(elem.attr('placeholder'));
|
||||
if ( placeholder ) {
|
||||
elem.attr('placeholder', placeholder);
|
||||
}
|
||||
});
|
||||
uDom('[data-i18n-tip]').forEach(function(elem) {
|
||||
elem.attr(
|
||||
'data-tip',
|
||||
|
|
|
@ -921,6 +921,40 @@ FilterGenericHnAnchored.fromSelfie = function(s) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
var FilterGenericHnAnchoredHostname = function(s, hostname) {
|
||||
FilterGenericHnAnchored.call(this, s);
|
||||
this.hostname = hostname;
|
||||
};
|
||||
FilterGenericHnAnchoredHostname.prototype = Object.create(FilterGenericHnAnchored.prototype);
|
||||
|
||||
FilterGenericHnAnchoredHostname.prototype.match = function(url) {
|
||||
if ( pageHostnameRegister.slice(-this.hostname.length) !== this.hostname ) {
|
||||
return false;
|
||||
}
|
||||
return FilterGenericHnAnchored.prototype.match.call(this. url);
|
||||
};
|
||||
|
||||
FilterGenericHnAnchoredHostname.fid = FilterGenericHnAnchoredHostname.prototype.fid = '||_h';
|
||||
|
||||
FilterGenericHnAnchoredHostname.prototype.toString = function() {
|
||||
return '||' + this.s + '$domain=' + this.hostname;
|
||||
};
|
||||
|
||||
FilterGenericHnAnchoredHostname.prototype.toSelfie = function() {
|
||||
return this.s + '\t' + this.hostname;
|
||||
};
|
||||
|
||||
FilterGenericHnAnchoredHostname.compile = function(details, hostname) {
|
||||
return details.f + '\t' + hostname;
|
||||
};
|
||||
|
||||
FilterGenericHnAnchoredHostname.fromSelfie = function(s) {
|
||||
var pos = s.indexOf('\t');
|
||||
return new FilterGenericHnAnchoredHostname(s.slice(0, pos), s.slice(pos + 1));
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// With many wildcards, a regex is best.
|
||||
|
||||
// Ref: regex escaper taken from:
|
||||
|
@ -1417,6 +1451,9 @@ var getHostnameBasedFilterClass = function(details) {
|
|||
var s = details.f;
|
||||
var wcOffset = s.indexOf('*');
|
||||
if ( wcOffset !== -1 ) {
|
||||
if ( details.hostnameAnchored ) {
|
||||
return FilterGenericHnAnchoredHostname;
|
||||
}
|
||||
if ( s.indexOf('*', wcOffset + 1) !== -1 ) {
|
||||
return details.anchor === 0 ? FilterManyWildcardsHostname : null;
|
||||
}
|
||||
|
@ -1735,17 +1772,23 @@ var findFirstGoodToken = function(s) {
|
|||
reGoodToken.lastIndex = 0;
|
||||
var matches;
|
||||
while ( matches = reGoodToken.exec(s) ) {
|
||||
if ( s.charAt(reGoodToken.lastIndex) === '*' ) {
|
||||
continue;
|
||||
}
|
||||
if ( badTokens.hasOwnProperty(matches[0]) ) {
|
||||
continue;
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
// No good token found, try again without minding "bad" tokens
|
||||
reGoodToken.lastIndex = 0;
|
||||
while ( matches = reGoodToken.exec(s) ) {
|
||||
if ( s.charAt(reGoodToken.lastIndex) === '*' ) {
|
||||
continue;
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
// No good token found, just return the first token from left
|
||||
reGoodToken.lastIndex = 0;
|
||||
return reGoodToken.exec(s);
|
||||
return null;
|
||||
};
|
||||
|
||||
var findHostnameToken = function(s) {
|
||||
|
@ -1753,6 +1796,8 @@ var findHostnameToken = function(s) {
|
|||
return reHostnameToken.exec(s);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterParser.prototype.makeToken = function() {
|
||||
if ( this.isRegex ) {
|
||||
this.token = '*';
|
||||
|
@ -1774,7 +1819,7 @@ FilterParser.prototype.makeToken = function() {
|
|||
}
|
||||
|
||||
matches = findFirstGoodToken(this.f);
|
||||
if ( !matches || matches[0].length === 0 ) {
|
||||
if ( matches === null || matches[0].length === 0 ) {
|
||||
return;
|
||||
}
|
||||
this.tokenBeg = matches.index;
|
||||
|
@ -1864,7 +1909,8 @@ FilterContainer.prototype.factories = {
|
|||
'//': FilterRegex,
|
||||
'//h': FilterRegexHostname,
|
||||
'{h}': FilterHostnameDict,
|
||||
'||_': FilterGenericHnAnchored
|
||||
'||_': FilterGenericHnAnchored,
|
||||
'||_h': FilterGenericHnAnchoredHostname
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue