mirror of https://github.com/gorhill/uBlock.git
Add option to filter by HTTP method in static network filters
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/2117 Option: `method=` Value: a list of `|`-separated lowercased method names. Negated method names are allowed. These are valid methods: - connect - delete - get - head - options - patch - post - put As per DNR's own documentation: - https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/#type-RequestMethod The logger shows the method used for every network request. It's possible to filter the logger output for most-common methods: `get`, `head`, `post`.
This commit is contained in:
parent
e5a9b066ec
commit
b6981877ba
|
@ -5,6 +5,7 @@
|
|||
"esversion": 8,
|
||||
"globals": {
|
||||
"chrome": false, // global variable in Chromium, Chrome, Opera
|
||||
"globalThis": false,
|
||||
"self": false,
|
||||
"vAPI": false,
|
||||
"URLSearchParams": false,
|
||||
|
|
|
@ -176,8 +176,8 @@ const µBlock = { // jshint ignore:line
|
|||
|
||||
// Read-only
|
||||
systemSettings: {
|
||||
compiledMagic: 50, // Increase when compiled format changes
|
||||
selfieMagic: 50, // Increase when selfie format changes
|
||||
compiledMagic: 51, // Increase when compiled format changes
|
||||
selfieMagic: 51, // Increase when selfie format changes
|
||||
},
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/759#issuecomment-546654501
|
||||
|
@ -285,6 +285,7 @@ const µBlock = { // jshint ignore:line
|
|||
this.fromTabId(tabId); // Must be called AFTER tab context management
|
||||
this.realm = '';
|
||||
this.id = details.requestId;
|
||||
this.setMethod(details.method);
|
||||
this.setURL(details.url);
|
||||
this.aliasURL = details.aliasURL || undefined;
|
||||
if ( this.itype !== this.SUB_FRAME ) {
|
||||
|
@ -337,24 +338,31 @@ const µBlock = { // jshint ignore:line
|
|||
}
|
||||
|
||||
toLogger() {
|
||||
this.tstamp = Date.now();
|
||||
if ( this.domain === undefined ) {
|
||||
void this.getDomain();
|
||||
}
|
||||
if ( this.docDomain === undefined ) {
|
||||
void this.getDocDomain();
|
||||
}
|
||||
if ( this.tabDomain === undefined ) {
|
||||
void this.getTabDomain();
|
||||
}
|
||||
const filters = this.filter;
|
||||
const details = {
|
||||
id: this.id,
|
||||
tstamp: Date.now(),
|
||||
realm: this.realm,
|
||||
method: this.getMethodName(),
|
||||
type: this.stype,
|
||||
tabId: this.tabId,
|
||||
tabDomain: this.getTabDomain(),
|
||||
tabHostname: this.getTabHostname(),
|
||||
docDomain: this.getDocDomain(),
|
||||
docHostname: this.getDocHostname(),
|
||||
domain: this.getDomain(),
|
||||
hostname: this.getHostname(),
|
||||
url: this.url,
|
||||
aliasURL: this.aliasURL,
|
||||
filter: undefined,
|
||||
};
|
||||
// Many filters may have been applied to the current context
|
||||
if ( Array.isArray(filters) === false ) {
|
||||
return logger.writeOne(this);
|
||||
if ( Array.isArray(this.filter) === false ) {
|
||||
details.filter = this.filter;
|
||||
return logger.writeOne(details);
|
||||
}
|
||||
for ( const filter of filters ) {
|
||||
this.filter = filter;
|
||||
logger.writeOne(this);
|
||||
for ( const filter of this.filter ) {
|
||||
details.filter = filter;
|
||||
logger.writeOne(details);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -84,6 +84,48 @@ const typeStrToIntMap = {
|
|||
'other': OTHER,
|
||||
};
|
||||
|
||||
const METHOD_NONE = 0;
|
||||
const METHOD_CONNECT = 1 << 1;
|
||||
const METHOD_DELETE = 1 << 2;
|
||||
const METHOD_GET = 1 << 3;
|
||||
const METHOD_HEAD = 1 << 4;
|
||||
const METHOD_OPTIONS = 1 << 5;
|
||||
const METHOD_PATCH = 1 << 6;
|
||||
const METHOD_POST = 1 << 7;
|
||||
const METHOD_PUT = 1 << 8;
|
||||
|
||||
const methodStrToBitMap = {
|
||||
'': METHOD_NONE,
|
||||
'connect': METHOD_CONNECT,
|
||||
'delete': METHOD_DELETE,
|
||||
'get': METHOD_GET,
|
||||
'head': METHOD_HEAD,
|
||||
'options': METHOD_OPTIONS,
|
||||
'patch': METHOD_PATCH,
|
||||
'post': METHOD_POST,
|
||||
'put': METHOD_PUT,
|
||||
'CONNECT': METHOD_CONNECT,
|
||||
'DELETE': METHOD_DELETE,
|
||||
'GET': METHOD_GET,
|
||||
'HEAD': METHOD_HEAD,
|
||||
'OPTIONS': METHOD_OPTIONS,
|
||||
'PATCH': METHOD_PATCH,
|
||||
'POST': METHOD_POST,
|
||||
'PUT': METHOD_PUT,
|
||||
};
|
||||
|
||||
const methodBitToStrMap = new Map([
|
||||
[ METHOD_NONE, '' ],
|
||||
[ METHOD_CONNECT, 'connect' ],
|
||||
[ METHOD_DELETE, 'delete' ],
|
||||
[ METHOD_GET, 'get' ],
|
||||
[ METHOD_HEAD, 'head' ],
|
||||
[ METHOD_OPTIONS, 'options' ],
|
||||
[ METHOD_PATCH, 'patch' ],
|
||||
[ METHOD_POST, 'post' ],
|
||||
[ METHOD_PUT, 'put' ],
|
||||
]);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const FilteringContext = class {
|
||||
|
@ -94,7 +136,8 @@ const FilteringContext = class {
|
|||
this.tstamp = 0;
|
||||
this.realm = '';
|
||||
this.id = undefined;
|
||||
this.itype = 0;
|
||||
this.method = 0;
|
||||
this.itype = NO_TYPE;
|
||||
this.stype = undefined;
|
||||
this.url = undefined;
|
||||
this.aliasURL = undefined;
|
||||
|
@ -133,6 +176,7 @@ const FilteringContext = class {
|
|||
fromFilteringContext(other) {
|
||||
this.realm = other.realm;
|
||||
this.type = other.type;
|
||||
this.method = other.method;
|
||||
this.url = other.url;
|
||||
this.hostname = other.hostname;
|
||||
this.domain = other.domain;
|
||||
|
@ -358,6 +402,23 @@ const FilteringContext = class {
|
|||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
setMethod(a) {
|
||||
this.method = methodStrToBitMap[a] || 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
getMethodName() {
|
||||
return FilteringContext.getMethodName(this.method);
|
||||
}
|
||||
|
||||
static getMethod(a) {
|
||||
return methodStrToBitMap[a] || 0;
|
||||
}
|
||||
|
||||
static getMethodName(a) {
|
||||
return methodBitToStrMap.get(a) || '';
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -386,6 +447,16 @@ FilteringContext.prototype.INLINE_ANY = FilteringContext.INLINE_ANY = INLINE_ANY
|
|||
FilteringContext.prototype.PING_ANY = FilteringContext.PING_ANY = PING_ANY;
|
||||
FilteringContext.prototype.SCRIPT_ANY = FilteringContext.SCRIPT_ANY = SCRIPT_ANY;
|
||||
|
||||
FilteringContext.prototype.METHOD_NONE = FilteringContext.METHOD_NONE = METHOD_NONE;
|
||||
FilteringContext.prototype.METHOD_CONNECT = FilteringContext.METHOD_CONNECT = METHOD_CONNECT;
|
||||
FilteringContext.prototype.METHOD_DELETE = FilteringContext.METHOD_DELETE = METHOD_DELETE;
|
||||
FilteringContext.prototype.METHOD_GET = FilteringContext.METHOD_GET = METHOD_GET;
|
||||
FilteringContext.prototype.METHOD_HEAD = FilteringContext.METHOD_HEAD = METHOD_HEAD;
|
||||
FilteringContext.prototype.METHOD_OPTIONS = FilteringContext.METHOD_OPTIONS = METHOD_OPTIONS;
|
||||
FilteringContext.prototype.METHOD_PATCH = FilteringContext.METHOD_PATCH = METHOD_PATCH;
|
||||
FilteringContext.prototype.METHOD_POST = FilteringContext.METHOD_POST = METHOD_POST;
|
||||
FilteringContext.prototype.METHOD_PUT = FilteringContext.METHOD_PUT = METHOD_PUT;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
export { FilteringContext };
|
||||
|
|
|
@ -36,6 +36,16 @@ const logDate = new Date();
|
|||
const logDateTimezoneOffset = logDate.getTimezoneOffset() * 60000;
|
||||
const loggerEntries = [];
|
||||
|
||||
const COLUMN_TIMESTAMP = 0;
|
||||
const COLUMN_FILTER = 1;
|
||||
const COLUMN_MESSAGE = 1;
|
||||
const COLUMN_RESULT = 2;
|
||||
const COLUMN_INITIATOR = 3;
|
||||
const COLUMN_PARTYNESS = 4;
|
||||
const COLUMN_METHOD = 5;
|
||||
const COLUMN_TYPE = 6;
|
||||
const COLUMN_URL = 7;
|
||||
|
||||
let filteredLoggerEntries = [];
|
||||
let filteredLoggerEntryVoidedCount = 0;
|
||||
|
||||
|
@ -211,7 +221,6 @@ const LogEntry = function(details) {
|
|||
this[prop] = details[prop];
|
||||
}
|
||||
}
|
||||
this.type = details.stype || details.type;
|
||||
if ( details.aliasURL !== undefined ) {
|
||||
this.aliased = true;
|
||||
}
|
||||
|
@ -233,6 +242,7 @@ LogEntry.prototype = {
|
|||
domain: '',
|
||||
filter: undefined,
|
||||
id: '',
|
||||
method: '',
|
||||
realm: '',
|
||||
tabDomain: '',
|
||||
tabHostname: '',
|
||||
|
@ -413,17 +423,20 @@ const parseLogEntry = function(details) {
|
|||
textContent.push('');
|
||||
}
|
||||
|
||||
// Cell 5
|
||||
// Cell 5: method
|
||||
textContent.push(entry.method || '');
|
||||
|
||||
// Cell 6
|
||||
textContent.push(
|
||||
normalizeToStr(prettyRequestTypes[entry.type] || entry.type)
|
||||
);
|
||||
|
||||
// Cell 6
|
||||
// Cell 7
|
||||
textContent.push(normalizeToStr(details.url));
|
||||
|
||||
// Hidden cells -- useful for row-filtering purpose
|
||||
|
||||
// Cell 7
|
||||
// Cell 8
|
||||
if ( entry.aliased ) {
|
||||
textContent.push(`aliasURL=${details.aliasURL}`);
|
||||
}
|
||||
|
@ -534,49 +547,56 @@ const viewPort = (( ) => {
|
|||
: 0;
|
||||
});
|
||||
const reservedWidth =
|
||||
cellWidths[0] + cellWidths[2] + cellWidths[4] + cellWidths[5];
|
||||
cellWidths[6] = 0.5;
|
||||
if ( cellWidths[1] === 0 && cellWidths[3] === 0 ) {
|
||||
cellWidths[6] = 1;
|
||||
} else if ( cellWidths[1] === 0 ) {
|
||||
cellWidths[3] = 0.35;
|
||||
cellWidths[6] = 0.65;
|
||||
} else if ( cellWidths[3] === 0 ) {
|
||||
cellWidths[1] = 0.35;
|
||||
cellWidths[6] = 0.65;
|
||||
cellWidths[COLUMN_TIMESTAMP] +
|
||||
cellWidths[COLUMN_RESULT] +
|
||||
cellWidths[COLUMN_PARTYNESS] +
|
||||
cellWidths[COLUMN_METHOD] +
|
||||
cellWidths[COLUMN_TYPE];
|
||||
cellWidths[COLUMN_URL] = 0.5;
|
||||
if ( cellWidths[COLUMN_FILTER] === 0 && cellWidths[COLUMN_INITIATOR] === 0 ) {
|
||||
cellWidths[COLUMN_URL] = 1;
|
||||
} else if ( cellWidths[COLUMN_FILTER] === 0 ) {
|
||||
cellWidths[COLUMN_INITIATOR] = 0.35;
|
||||
cellWidths[COLUMN_URL] = 0.65;
|
||||
} else if ( cellWidths[COLUMN_INITIATOR] === 0 ) {
|
||||
cellWidths[COLUMN_FILTER] = 0.35;
|
||||
cellWidths[COLUMN_URL] = 0.65;
|
||||
} else {
|
||||
cellWidths[1] = 0.25;
|
||||
cellWidths[3] = 0.25;
|
||||
cellWidths[6] = 0.5;
|
||||
cellWidths[COLUMN_FILTER] = 0.25;
|
||||
cellWidths[COLUMN_INITIATOR] = 0.25;
|
||||
cellWidths[COLUMN_URL] = 0.5;
|
||||
}
|
||||
const style = qs$('#vwRendererRuntimeStyles');
|
||||
const cssRules = [
|
||||
'#vwContent .logEntry {',
|
||||
` height: ${newLineHeight}px;`,
|
||||
'}',
|
||||
'#vwContent .logEntry > div > span:nth-of-type(1) {',
|
||||
` width: ${cellWidths[0]}px;`,
|
||||
`#vwContent .logEntry > div > span:nth-of-type(${COLUMN_TIMESTAMP+1}) {`,
|
||||
` width: ${cellWidths[COLUMN_TIMESTAMP]}px;`,
|
||||
'}',
|
||||
'#vwContent .logEntry > div > span:nth-of-type(2) {',
|
||||
` width: calc(calc(100% - ${reservedWidth}px) * ${cellWidths[1]});`,
|
||||
`#vwContent .logEntry > div > span:nth-of-type(${COLUMN_FILTER+1}) {`,
|
||||
` width: calc(calc(100% - ${reservedWidth}px) * ${cellWidths[COLUMN_FILTER]});`,
|
||||
'}',
|
||||
'#vwContent .logEntry > div.messageRealm > span:nth-of-type(2) {',
|
||||
` width: calc(100% - ${cellWidths[0]}px);`,
|
||||
`#vwContent .logEntry > div.messageRealm > span:nth-of-type(${COLUMN_MESSAGE+1}) {`,
|
||||
` width: calc(100% - ${cellWidths[COLUMN_MESSAGE]}px);`,
|
||||
'}',
|
||||
'#vwContent .logEntry > div > span:nth-of-type(3) {',
|
||||
` width: ${cellWidths[2]}px;`,
|
||||
`#vwContent .logEntry > div > span:nth-of-type(${COLUMN_RESULT+1}) {`,
|
||||
` width: ${cellWidths[COLUMN_RESULT]}px;`,
|
||||
'}',
|
||||
'#vwContent .logEntry > div > span:nth-of-type(4) {',
|
||||
` width: calc(calc(100% - ${reservedWidth}px) * ${cellWidths[3]});`,
|
||||
`#vwContent .logEntry > div > span:nth-of-type(${COLUMN_INITIATOR+1}) {`,
|
||||
` width: calc(calc(100% - ${reservedWidth}px) * ${cellWidths[COLUMN_INITIATOR]});`,
|
||||
'}',
|
||||
'#vwContent .logEntry > div > span:nth-of-type(5) {',
|
||||
` width: ${cellWidths[4]}px;`,
|
||||
`#vwContent .logEntry > div > span:nth-of-type(${COLUMN_PARTYNESS+1}) {`,
|
||||
` width: ${cellWidths[COLUMN_PARTYNESS]}px;`,
|
||||
'}',
|
||||
'#vwContent .logEntry > div > span:nth-of-type(6) {',
|
||||
` width: ${cellWidths[5]}px;`,
|
||||
`#vwContent .logEntry > div > span:nth-of-type(${COLUMN_METHOD+1}) {`,
|
||||
` width: ${cellWidths[COLUMN_METHOD]}px;`,
|
||||
'}',
|
||||
'#vwContent .logEntry > div > span:nth-of-type(7) {',
|
||||
` width: calc(calc(100% - ${reservedWidth}px) * ${cellWidths[6]});`,
|
||||
`#vwContent .logEntry > div > span:nth-of-type(${COLUMN_TYPE+1}) {`,
|
||||
` width: ${cellWidths[COLUMN_TYPE]}px;`,
|
||||
'}',
|
||||
`#vwContent .logEntry > div > span:nth-of-type(${COLUMN_URL+1}) {`,
|
||||
` width: calc(calc(100% - ${reservedWidth}px) * ${cellWidths[COLUMN_URL]});`,
|
||||
'}',
|
||||
'',
|
||||
];
|
||||
|
@ -651,8 +671,8 @@ const viewPort = (( ) => {
|
|||
}
|
||||
|
||||
// Timestamp
|
||||
span = div.children[0];
|
||||
span.textContent = cells[0];
|
||||
span = div.children[COLUMN_TIMESTAMP];
|
||||
span.textContent = cells[COLUMN_TIMESTAMP];
|
||||
|
||||
// Tab id
|
||||
if ( details.tabId !== undefined ) {
|
||||
|
@ -666,8 +686,8 @@ const viewPort = (( ) => {
|
|||
if ( details.type !== undefined ) {
|
||||
dom.attr(div, 'data-type', details.type);
|
||||
}
|
||||
span = div.children[1];
|
||||
span.textContent = cells[1];
|
||||
span = div.children[COLUMN_MESSAGE];
|
||||
span.textContent = cells[COLUMN_MESSAGE];
|
||||
return div;
|
||||
}
|
||||
|
||||
|
@ -692,23 +712,23 @@ const viewPort = (( ) => {
|
|||
dom.attr(div, 'data-modifier', '');
|
||||
}
|
||||
}
|
||||
span = div.children[1];
|
||||
if ( renderFilterToSpan(span, cells[1]) === false ) {
|
||||
span.textContent = cells[1];
|
||||
span = div.children[COLUMN_FILTER];
|
||||
if ( renderFilterToSpan(span, cells[COLUMN_FILTER]) === false ) {
|
||||
span.textContent = cells[COLUMN_FILTER];
|
||||
}
|
||||
|
||||
// Event
|
||||
if ( cells[2] === '--' ) {
|
||||
if ( cells[COLUMN_RESULT] === '--' ) {
|
||||
dom.attr(div, 'data-status', '1');
|
||||
} else if ( cells[2] === '++' ) {
|
||||
} else if ( cells[COLUMN_RESULT] === '++' ) {
|
||||
dom.attr(div, 'data-status', '2');
|
||||
} else if ( cells[2] === '**' ) {
|
||||
} else if ( cells[COLUMN_RESULT] === '**' ) {
|
||||
dom.attr(div, 'data-status', '3');
|
||||
} else if ( cells[2] === '<<' ) {
|
||||
} else if ( cells[COLUMN_RESULT] === '<<' ) {
|
||||
divcl.add('redirect');
|
||||
}
|
||||
span = div.children[2];
|
||||
span.textContent = cells[2];
|
||||
span = div.children[COLUMN_RESULT];
|
||||
span.textContent = cells[COLUMN_RESULT];
|
||||
|
||||
// Origins
|
||||
if ( details.tabHostname ) {
|
||||
|
@ -717,12 +737,12 @@ const viewPort = (( ) => {
|
|||
if ( details.docHostname ) {
|
||||
dom.attr(div, 'data-dochn', details.docHostname);
|
||||
}
|
||||
span = div.children[3];
|
||||
span.textContent = cells[3];
|
||||
span = div.children[COLUMN_INITIATOR];
|
||||
span.textContent = cells[COLUMN_INITIATOR];
|
||||
|
||||
// Partyness
|
||||
if (
|
||||
cells[4] !== '' &&
|
||||
cells[COLUMN_PARTYNESS] !== '' &&
|
||||
details.realm === 'network' &&
|
||||
details.domain !== undefined
|
||||
) {
|
||||
|
@ -733,12 +753,16 @@ const viewPort = (( ) => {
|
|||
text += ` \u21d2 ${details.domain}`;
|
||||
dom.attr(div, 'data-parties', text);
|
||||
}
|
||||
span = div.children[4];
|
||||
span.textContent = cells[4];
|
||||
span = div.children[COLUMN_PARTYNESS];
|
||||
span.textContent = cells[COLUMN_PARTYNESS];
|
||||
|
||||
// Method
|
||||
span = div.children[COLUMN_METHOD];
|
||||
span.textContent = cells[COLUMN_METHOD];
|
||||
|
||||
// Type
|
||||
span = div.children[5];
|
||||
span.textContent = cells[5];
|
||||
span = div.children[COLUMN_TYPE];
|
||||
span.textContent = cells[COLUMN_TYPE];
|
||||
|
||||
// URL
|
||||
let re;
|
||||
|
@ -747,7 +771,7 @@ const viewPort = (( ) => {
|
|||
} else if ( filteringType === 'dynamicUrl' ) {
|
||||
re = regexFromURLFilteringResult(filter.rule.join(' '));
|
||||
}
|
||||
nodeFromURL(div.children[6], cells[6], re);
|
||||
nodeFromURL(div.children[COLUMN_URL], cells[COLUMN_URL], re);
|
||||
|
||||
// Alias URL (CNAME, etc.)
|
||||
if ( cells.length > 7 ) {
|
||||
|
@ -1468,7 +1492,7 @@ const reloadTab = function(ev) {
|
|||
};
|
||||
|
||||
const filterFromTargetRow = function() {
|
||||
return dom.text(targetRow.children[1]);
|
||||
return dom.text(targetRow.children[COLUMN_FILTER]);
|
||||
};
|
||||
|
||||
const aliasURLFromID = function(id) {
|
||||
|
@ -1476,13 +1500,13 @@ const reloadTab = function(ev) {
|
|||
for ( const entry of loggerEntries ) {
|
||||
if ( entry.id !== id || entry.aliased ) { continue; }
|
||||
const fields = entry.textContent.split('\t');
|
||||
return fields[6] || '';
|
||||
return fields[COLUMN_URL] || '';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
const toSummaryPaneFilterNode = async function(receiver, filter) {
|
||||
receiver.children[1].textContent = filter;
|
||||
receiver.children[COLUMN_FILTER].textContent = filter;
|
||||
if ( dom.cl.has(targetRow, 'canLookup') === false ) { return; }
|
||||
const isException = reIsExceptionFilter.test(filter);
|
||||
let isExcepted = false;
|
||||
|
@ -1498,7 +1522,7 @@ const reloadTab = function(ev) {
|
|||
};
|
||||
|
||||
const fillSummaryPaneFilterList = async function(rows) {
|
||||
const rawFilter = targetRow.children[1].textContent;
|
||||
const rawFilter = targetRow.children[COLUMN_FILTER].textContent;
|
||||
|
||||
const nodeFromFilter = function(filter, lists) {
|
||||
const fragment = document.createDocumentFragment();
|
||||
|
@ -1561,7 +1585,7 @@ const reloadTab = function(ev) {
|
|||
} else if ( dom.cl.has(targetRow, 'extendedRealm') ) {
|
||||
const response = await messaging.send('loggerUI', {
|
||||
what: 'listsFromCosmeticFilter',
|
||||
url: targetRow.children[6].textContent,
|
||||
url: targetRow.children[COLUMN_URL].textContent,
|
||||
rawFilter: rawFilter,
|
||||
});
|
||||
handleResponse(response);
|
||||
|
@ -1619,19 +1643,19 @@ const reloadTab = function(ev) {
|
|||
// Partyness
|
||||
text = dom.attr(tr, 'data-parties') || '';
|
||||
if ( text !== '' ) {
|
||||
rows[5].children[1].textContent = `(${trch[4].textContent})\u2002${text}`;
|
||||
rows[5].children[1].textContent = `(${trch[COLUMN_PARTYNESS].textContent})\u2002${text}`;
|
||||
} else {
|
||||
rows[5].style.display = 'none';
|
||||
}
|
||||
// Type
|
||||
text = trch[5].textContent;
|
||||
text = trch[COLUMN_TYPE].textContent;
|
||||
if ( text !== '' ) {
|
||||
rows[6].children[1].textContent = text;
|
||||
} else {
|
||||
rows[6].style.display = 'none';
|
||||
}
|
||||
// URL
|
||||
const canonicalURL = trch[6].textContent;
|
||||
const canonicalURL = trch[COLUMN_URL].textContent;
|
||||
if ( canonicalURL !== '' ) {
|
||||
const attr = dom.attr(tr, 'data-status') || '';
|
||||
if ( attr !== '' ) {
|
||||
|
@ -1640,7 +1664,7 @@ const reloadTab = function(ev) {
|
|||
dom.attr(rows[7], 'data-modifier', '');
|
||||
}
|
||||
}
|
||||
rows[7].children[1].appendChild(dom.clone(trch[6]));
|
||||
rows[7].children[1].appendChild(dom.clone(trch[COLUMN_URL]));
|
||||
} else {
|
||||
rows[7].style.display = 'none';
|
||||
}
|
||||
|
@ -1846,8 +1870,8 @@ const reloadTab = function(ev) {
|
|||
if ( targetRow === null ) { return; }
|
||||
ev.stopPropagation();
|
||||
targetTabId = tabIdFromAttribute(targetRow);
|
||||
targetType = targetRow.children[5].textContent.trim() || '';
|
||||
targetURLs = createTargetURLs(targetRow.children[6].textContent);
|
||||
targetType = targetRow.children[COLUMN_TYPE].textContent.trim() || '';
|
||||
targetURLs = createTargetURLs(targetRow.children[COLUMN_URL].textContent);
|
||||
targetPageHostname = dom.attr(targetRow, 'data-tabhn') || '';
|
||||
targetFrameHostname = dom.attr(targetRow, 'data-dochn') || '';
|
||||
|
||||
|
@ -2640,7 +2664,7 @@ const loggerSettings = (( ) => {
|
|||
maxEntryCount: 2000, // per-tab
|
||||
maxLoadCount: 20, // per-tab
|
||||
},
|
||||
columns: [ true, true, true, true, true, true, true, true ],
|
||||
columns: [ true, true, true, true, true, true, true, true, true ],
|
||||
linesPerEntry: 4,
|
||||
};
|
||||
|
||||
|
|
|
@ -511,7 +511,7 @@ browser.runtime.onUpdateAvailable.addListener(details => {
|
|||
if ( selfieIsValid ) {
|
||||
µb.supportStats.allReadyAfter += ' (selfie)';
|
||||
}
|
||||
ubolog(`All ready ${µb.supportStats.allReadyAfter} ms after launch`);
|
||||
ubolog(`All ready ${µb.supportStats.allReadyAfter} after launch`);
|
||||
|
||||
// <<<<< end of private scope
|
||||
})();
|
||||
|
|
|
@ -2377,7 +2377,8 @@ const OPTTokenShide = 37;
|
|||
const OPTTokenXhr = 38;
|
||||
const OPTTokenWebrtc = 39;
|
||||
const OPTTokenWebsocket = 40;
|
||||
const OPTTokenCount = 41;
|
||||
const OPTTokenMethod = 41;
|
||||
const OPTTokenCount = 42;
|
||||
|
||||
//const OPTPerOptionMask = 0x0000ff00;
|
||||
const OPTCanNegate = 1 << 8;
|
||||
|
@ -2481,6 +2482,7 @@ Parser.prototype.OPTTokenFrame = OPTTokenFrame;
|
|||
Parser.prototype.OPTTokenXhr = OPTTokenXhr;
|
||||
Parser.prototype.OPTTokenWebrtc = OPTTokenWebrtc;
|
||||
Parser.prototype.OPTTokenWebsocket = OPTTokenWebsocket;
|
||||
Parser.prototype.OPTTokenMethod = OPTTokenMethod;
|
||||
|
||||
Parser.prototype.OPTCanNegate = OPTCanNegate;
|
||||
Parser.prototype.OPTBlockOnly = OPTBlockOnly;
|
||||
|
@ -2527,6 +2529,7 @@ const netOptionTokenDescriptors = new Map([
|
|||
[ 'inline-script', OPTTokenInlineScript | OPTNonNetworkType | OPTCanNegate | OPTNonCspableType | OPTNonRedirectableType ],
|
||||
[ 'match-case', OPTTokenMatchCase ],
|
||||
[ 'media', OPTTokenMedia | OPTCanNegate | OPTNetworkType | OPTModifiableType | OPTRedirectableType | OPTNonCspableType ],
|
||||
[ 'method', OPTTokenMethod | OPTNetworkType | OPTMustAssign ],
|
||||
[ 'mp4', OPTTokenMp4 | OPTNetworkType | OPTBlockOnly | OPTModifierType ],
|
||||
[ '_', OPTTokenNoop ],
|
||||
[ 'object', OPTTokenObject | OPTCanNegate | OPTNetworkType | OPTModifiableType | OPTRedirectableType | OPTNonCspableType ],
|
||||
|
@ -2586,6 +2589,7 @@ Parser.netOptionTokenIds = new Map([
|
|||
[ 'inline-script', OPTTokenInlineScript ],
|
||||
[ 'match-case', OPTTokenMatchCase ],
|
||||
[ 'media', OPTTokenMedia ],
|
||||
[ 'method', OPTTokenMethod ],
|
||||
[ 'mp4', OPTTokenMp4 ],
|
||||
[ '_', OPTTokenNoop ],
|
||||
[ 'object', OPTTokenObject ],
|
||||
|
@ -2635,6 +2639,7 @@ Parser.netOptionTokenNames = new Map([
|
|||
[ OPTTokenInlineScript, 'inline-script' ],
|
||||
[ OPTTokenMatchCase, 'match-case' ],
|
||||
[ OPTTokenMedia, 'media' ],
|
||||
[ OPTTokenMethod, 'method' ],
|
||||
[ OPTTokenMp4, 'mp4' ],
|
||||
[ OPTTokenNoop, '_' ],
|
||||
[ OPTTokenObject, 'object' ],
|
||||
|
|
|
@ -199,6 +199,7 @@ const INVALID_TOKEN_HASH = 0xFFFFFFFF;
|
|||
// See the following as short-lived registers, used during evaluation. They are
|
||||
// valid until the next evaluation.
|
||||
|
||||
let $requestMethodBit = 0;
|
||||
let $requestTypeValue = 0;
|
||||
let $requestURL = '';
|
||||
let $requestURLRaw = '';
|
||||
|
@ -1265,6 +1266,82 @@ registerFilterClass(FilterRegex);
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
const FilterMethod = class {
|
||||
static match(idata) {
|
||||
if ( $requestMethodBit === 0 ) { return false; }
|
||||
const methodBits = filterData[idata+1];
|
||||
const notMethodBits = filterData[idata+2];
|
||||
return (methodBits !== 0 && ($requestMethodBit & methodBits) !== 0) ||
|
||||
(notMethodBits !== 0 && ($requestMethodBit & notMethodBits) === 0);
|
||||
}
|
||||
|
||||
static compile(details) {
|
||||
return [ FilterMethod.fid, details.methodBits, details.notMethodBits ];
|
||||
}
|
||||
|
||||
static fromCompiled(args) {
|
||||
const idata = filterDataAllocLen(3);
|
||||
filterData[idata+0] = args[0]; // fid
|
||||
filterData[idata+1] = args[1]; // methodBits
|
||||
filterData[idata+2] = args[2]; // notMethodBits
|
||||
return idata;
|
||||
}
|
||||
|
||||
static dnrFromCompiled(args, rule) {
|
||||
rule.condition = rule.condition || {};
|
||||
const rc = rule.condition;
|
||||
let methodBits = args[1];
|
||||
let notMethodBits = args[2];
|
||||
if ( methodBits !== 0 && rc.requestMethods === undefined ) {
|
||||
rc.requestMethods = [];
|
||||
}
|
||||
if ( notMethodBits !== 0 && rc.excludedRequestMethods === undefined ) {
|
||||
rc.excludedRequestMethods = [];
|
||||
}
|
||||
for ( let i = 1; methodBits !== 0 || notMethodBits !== 0; i++ ) {
|
||||
const bit = 1 << i;
|
||||
const methodName = FilteringContext.getMethodName(bit);
|
||||
if ( (methodBits & bit) !== 0 ) {
|
||||
methodBits &= ~bit;
|
||||
rc.requestMethods.push(methodName);
|
||||
} else if ( (notMethodBits & bit) !== 0 ) {
|
||||
notMethodBits &= ~bit;
|
||||
rc.excludedRequestMethods.push(methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static keyFromArgs(args) {
|
||||
return `${args[1]} ${args[2]}`;
|
||||
}
|
||||
|
||||
static logData(idata, details) {
|
||||
const methods = [];
|
||||
let methodBits = filterData[idata+1];
|
||||
let notMethodBits = filterData[idata+2];
|
||||
for ( let i = 0; methodBits !== 0 || notMethodBits !== 0; i++ ) {
|
||||
const bit = 1 << i;
|
||||
const methodName = FilteringContext.getMethodName(bit);
|
||||
if ( (methodBits & bit) !== 0 ) {
|
||||
methodBits &= ~bit;
|
||||
methods.push(methodName);
|
||||
} else if ( (notMethodBits & bit) !== 0 ) {
|
||||
notMethodBits &= ~bit;
|
||||
methods.push(`~${methodName}`);
|
||||
}
|
||||
}
|
||||
details.options.push(`method=${methods.join('|')}`);
|
||||
}
|
||||
|
||||
static dumpInfo(idata) {
|
||||
return `0b${filterData[idata+1].toString(2)} 0b${filterData[idata+2].toString(2)}`;
|
||||
}
|
||||
};
|
||||
|
||||
registerFilterClass(FilterMethod);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// stylesheet: 1 => bit 0
|
||||
// image: 2 => bit 1
|
||||
// object: 3 => bit 2
|
||||
|
@ -3025,6 +3102,8 @@ class FilterCompiler {
|
|||
this.tokenBeg = 0;
|
||||
this.typeBits = 0;
|
||||
this.notTypeBits = 0;
|
||||
this.methodBits = 0;
|
||||
this.notMethodBits = 0;
|
||||
this.wildcardPos = -1;
|
||||
this.caretPos = -1;
|
||||
return this;
|
||||
|
@ -3055,6 +3134,21 @@ class FilterCompiler {
|
|||
}
|
||||
}
|
||||
|
||||
processMethodOption(value) {
|
||||
for ( const method of value.split('|') ) {
|
||||
if ( method.charCodeAt(0) === 0x7E /* '~' */ ) {
|
||||
const bit = FilteringContext.getMethod(method.slice(1)) || 0;
|
||||
if ( bit === 0 ) { continue; }
|
||||
this.notMethodBits |= bit;
|
||||
} else {
|
||||
const bit = FilteringContext.getMethod(method) || 0;
|
||||
if ( bit === 0 ) { continue; }
|
||||
this.methodBits |= bit;
|
||||
}
|
||||
}
|
||||
this.methodBits &= ~this.notMethodBits;
|
||||
}
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/589
|
||||
// Be ready to handle multiple negated types
|
||||
|
||||
|
@ -3225,6 +3319,9 @@ class FilterCompiler {
|
|||
}
|
||||
this.optionUnitBits |= this.REDIRECT_BIT;
|
||||
break;
|
||||
case parser.OPTTokenMethod:
|
||||
this.processMethodOption(val);
|
||||
break;
|
||||
case parser.OPTTokenInvalid:
|
||||
return false;
|
||||
default:
|
||||
|
@ -3573,6 +3670,11 @@ class FilterCompiler {
|
|||
units.push(FilterAnchorRight.compile());
|
||||
}
|
||||
|
||||
// Method(s)
|
||||
if ( this.methodBits !== 0 || this.notMethodBits !== 0 ) {
|
||||
units.push(FilterMethod.compile(this));
|
||||
}
|
||||
|
||||
// Not types
|
||||
if ( this.notTypeBits !== 0 ) {
|
||||
units.push(FilterNotType.compile(this));
|
||||
|
@ -4566,6 +4668,7 @@ FilterContainer.prototype.matchAndFetchModifiers = function(
|
|||
$docHostname = fctxt.getDocHostname();
|
||||
$docDomain = fctxt.getDocDomain();
|
||||
$requestHostname = fctxt.getHostname();
|
||||
$requestMethodBit = fctxt.method || 0;
|
||||
$requestTypeValue = (typeBits & TypeBitsMask) >>> TypeBitsOffset;
|
||||
|
||||
const partyBits = fctxt.is3rdPartyToDoc() ? ThirdParty : FirstParty;
|
||||
|
@ -4866,6 +4969,7 @@ FilterContainer.prototype.matchRequestReverse = function(type, url) {
|
|||
// Prime tokenizer: we get a normalized URL in return.
|
||||
$requestURL = urlTokenizer.setURL(url);
|
||||
$requestURLRaw = url;
|
||||
$requestMethodBit = 0;
|
||||
$requestTypeValue = (typeBits & TypeBitsMask) >>> TypeBitsOffset;
|
||||
$isBlockImportant = false;
|
||||
this.$filterUnit = 0;
|
||||
|
@ -4933,6 +5037,7 @@ FilterContainer.prototype.matchRequest = function(fctxt, modifiers = 0) {
|
|||
$docHostname = fctxt.getDocHostname();
|
||||
$docDomain = fctxt.getDocDomain();
|
||||
$requestHostname = fctxt.getHostname();
|
||||
$requestMethodBit = fctxt.method || 0;
|
||||
$requestTypeValue = (typeBits & TypeBitsMask) >>> TypeBitsOffset;
|
||||
$isBlockImportant = false;
|
||||
|
||||
|
@ -4967,6 +5072,7 @@ FilterContainer.prototype.matchHeaders = function(fctxt, headers) {
|
|||
$docHostname = fctxt.getDocHostname();
|
||||
$docDomain = fctxt.getDocDomain();
|
||||
$requestHostname = fctxt.getHostname();
|
||||
$requestMethodBit = fctxt.method || 0;
|
||||
$requestTypeValue = (typeBits & TypeBitsMask) >>> TypeBitsOffset;
|
||||
$httpHeaders.init(headers);
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
</span>
|
||||
</div>
|
||||
<div><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\t(?:0,)?1\t" data-i18n="loggerRowFiltererBuiltin1p"></span><span data-filtex="\t(?:3(?:,\d)?|0,3)\t" data-i18n="loggerRowFiltererBuiltin3p"></span></div>
|
||||
<div><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\tget\t">get</span><span data-filtex="\thead\t">head</span><span data-filtex="\tpost\t">post</span></div>
|
||||
<div id="filterExprCnameOf" style="display:none"><span data-filtex="!" data-i18n="loggerRowFiltererBuiltinNot"></span><span data-filtex="\taliasURL=.">CNAME</span></div>
|
||||
</div>
|
||||
</span>
|
||||
|
@ -85,7 +86,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div id="vwLineSizer">
|
||||
<div class="logEntry oneLine"><div><span>00:00:00</span><span> </span><span>**</span><span> </span><span>3,3</span><span>inline-script</span><span> </span></div></div>
|
||||
<div class="logEntry oneLine"><div><span>00:00:00</span><span> </span><span>**</span><span> </span><span>3,3</span><span>options</span><span>inline-script</span><span> </span></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -101,7 +102,7 @@
|
|||
</div>
|
||||
|
||||
<div id="templates" style="display: none;">
|
||||
<div id="logEntryTemplate"><div><span></span>​<span></span>​<span></span>​<span></span>​<span></span>​<span></span>​<span></span></div></div>
|
||||
<div id="logEntryTemplate"><div><span></span>​<span></span>​<span></span>​<span></span>​<span></span>​<span></span>​<span></span>​<span></span></div></div>
|
||||
|
||||
<div id="netFilteringDialog" data-pane="details">
|
||||
<div class="hide preview"><span>click to preview</span></div>
|
||||
|
|
Loading…
Reference in New Issue