mirror of https://github.com/gorhill/uMatrix.git
Browse Source
Notably: - Import logger improvements from uBO - Import CNAME uncloaking from uBO - Import more improvements from uBO - Make use of modern JS features This should un-stall further development of uMatrix.pull/1014/head

91 changed files with 24736 additions and 16318 deletions
@ -1 +1 @@ |
|||
1.4.0 |
|||
1.4.1.0 |
|||
|
File diff suppressed because it is too large
@ -0,0 +1,308 @@ |
|||
/******************************************************************************* |
|||
|
|||
uBlock Origin - a browser extension to block requests. |
|||
Copyright (C) 2019-present Raymond Hill |
|||
|
|||
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 |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|||
|
|||
Home: https://github.com/gorhill/uBlock
|
|||
*/ |
|||
|
|||
// For non-background page
|
|||
|
|||
'use strict'; |
|||
|
|||
/******************************************************************************/ |
|||
|
|||
// Direct messaging connection ability
|
|||
|
|||
(( ) => { |
|||
// >>>>>>>> start of private namespace
|
|||
|
|||
if ( |
|||
typeof vAPI !== 'object' || |
|||
vAPI.messaging instanceof Object === false || |
|||
vAPI.MessagingConnection instanceof Function |
|||
) { |
|||
return; |
|||
} |
|||
|
|||
const listeners = new Set(); |
|||
const connections = new Map(); |
|||
|
|||
vAPI.MessagingConnection = class { |
|||
constructor(handler, details) { |
|||
this.messaging = vAPI.messaging; |
|||
this.handler = handler; |
|||
this.id = details.id; |
|||
this.to = details.to; |
|||
this.toToken = details.toToken; |
|||
this.from = details.from; |
|||
this.fromToken = details.fromToken; |
|||
this.checkTimer = undefined; |
|||
// On Firefox it appears ports are not automatically disconnected
|
|||
// when navigating to another page.
|
|||
const ctor = vAPI.MessagingConnection; |
|||
if ( ctor.pagehide !== undefined ) { return; } |
|||
ctor.pagehide = ( ) => { |
|||
for ( const connection of connections.values() ) { |
|||
connection.disconnect(); |
|||
connection.handler( |
|||
connection.toDetails('connectionBroken') |
|||
); |
|||
} |
|||
}; |
|||
window.addEventListener('pagehide', ctor.pagehide); |
|||
} |
|||
toDetails(what, payload) { |
|||
return { |
|||
what: what, |
|||
id: this.id, |
|||
from: this.from, |
|||
fromToken: this.fromToken, |
|||
to: this.to, |
|||
toToken: this.toToken, |
|||
payload: payload |
|||
}; |
|||
} |
|||
disconnect() { |
|||
if ( this.checkTimer !== undefined ) { |
|||
clearTimeout(this.checkTimer); |
|||
this.checkTimer = undefined; |
|||
} |
|||
connections.delete(this.id); |
|||
const port = this.messaging.getPort(); |
|||
if ( port === null ) { return; } |
|||
port.postMessage({ |
|||
channel: 'vapi', |
|||
msg: this.toDetails('connectionBroken'), |
|||
}); |
|||
} |
|||
checkAsync() { |
|||
if ( this.checkTimer !== undefined ) { |
|||
clearTimeout(this.checkTimer); |
|||
} |
|||
this.checkTimer = vAPI.setTimeout( |
|||
( ) => { this.check(); }, |
|||
499 |
|||
); |
|||
} |
|||
check() { |
|||
this.checkTimer = undefined; |
|||
if ( connections.has(this.id) === false ) { return; } |
|||
const port = this.messaging.getPort(); |
|||
if ( port === null ) { return; } |
|||
port.postMessage({ |
|||
channel: 'vapi', |
|||
msg: this.toDetails('connectionCheck'), |
|||
}); |
|||
this.checkAsync(); |
|||
} |
|||
receive(details) { |
|||
switch ( details.what ) { |
|||
case 'connectionAccepted': |
|||
this.toToken = details.toToken; |
|||
this.handler(details); |
|||
this.checkAsync(); |
|||
break; |
|||
case 'connectionBroken': |
|||
connections.delete(this.id); |
|||
this.handler(details); |
|||
break; |
|||
case 'connectionMessage': |
|||
this.handler(details); |
|||
this.checkAsync(); |
|||
break; |
|||
case 'connectionCheck': |
|||
const port = this.messaging.getPort(); |
|||
if ( port === null ) { return; } |
|||
if ( connections.has(this.id) ) { |
|||
this.checkAsync(); |
|||
} else { |
|||
details.what = 'connectionBroken'; |
|||
port.postMessage({ channel: 'vapi', msg: details }); |
|||
} |
|||
break; |
|||
case 'connectionRefused': |
|||
connections.delete(this.id); |
|||
this.handler(details); |
|||
break; |
|||
} |
|||
} |
|||
send(payload) { |
|||
const port = this.messaging.getPort(); |
|||
if ( port === null ) { return; } |
|||
port.postMessage({ |
|||
channel: 'vapi', |
|||
msg: this.toDetails('connectionMessage', payload), |
|||
}); |
|||
} |
|||
|
|||
static addListener(listener) { |
|||
listeners.add(listener); |
|||
} |
|||
static async connectTo(from, to, handler) { |
|||
const port = vAPI.messaging.getPort(); |
|||
if ( port === null ) { return; } |
|||
const connection = new vAPI.MessagingConnection(handler, { |
|||
id: `${from}-${to}-${vAPI.sessionId}`, |
|||
to: to, |
|||
from: from, |
|||
fromToken: port.name |
|||
}); |
|||
connections.set(connection.id, connection); |
|||
port.postMessage({ |
|||
channel: 'vapi', |
|||
msg: { |
|||
what: 'connectionRequested', |
|||
id: connection.id, |
|||
from: from, |
|||
fromToken: port.name, |
|||
to: to, |
|||
} |
|||
}); |
|||
return connection.id; |
|||
} |
|||
static disconnectFrom(connectionId) { |
|||
const connection = connections.get(connectionId); |
|||
if ( connection === undefined ) { return; } |
|||
connection.disconnect(); |
|||
} |
|||
static sendTo(connectionId, payload) { |
|||
const connection = connections.get(connectionId); |
|||
if ( connection === undefined ) { return; } |
|||
connection.send(payload); |
|||
} |
|||
static canDestroyPort() { |
|||
return listeners.length === 0 && connections.size === 0; |
|||
} |
|||
static mustDestroyPort() { |
|||
if ( connections.size === 0 ) { return; } |
|||
for ( const connection of connections.values() ) { |
|||
connection.receive({ what: 'connectionBroken' }); |
|||
} |
|||
connections.clear(); |
|||
} |
|||
static canProcessMessage(details) { |
|||
if ( details.channel !== 'vapi' ) { return; } |
|||
switch ( details.msg.what ) { |
|||
case 'connectionAccepted': |
|||
case 'connectionBroken': |
|||
case 'connectionCheck': |
|||
case 'connectionMessage': |
|||
case 'connectionRefused': { |
|||
const connection = connections.get(details.msg.id); |
|||
if ( connection === undefined ) { break; } |
|||
connection.receive(details.msg); |
|||
return true; |
|||
} |
|||
case 'connectionRequested': |
|||
if ( listeners.length === 0 ) { return; } |
|||
const port = vAPI.messaging.getPort(); |
|||
if ( port === null ) { break; } |
|||
let listener, result; |
|||
for ( listener of listeners ) { |
|||
result = listener(details.msg); |
|||
if ( result !== undefined ) { break; } |
|||
} |
|||
if ( result === undefined ) { break; } |
|||
if ( result === true ) { |
|||
details.msg.what = 'connectionAccepted'; |
|||
details.msg.toToken = port.name; |
|||
const connection = new vAPI.MessagingConnection( |
|||
listener, |
|||
details.msg |
|||
); |
|||
connections.set(connection.id, connection); |
|||
} else { |
|||
details.msg.what = 'connectionRefused'; |
|||
} |
|||
port.postMessage(details); |
|||
return true; |
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
vAPI.messaging.extensions.push(vAPI.MessagingConnection); |
|||
|
|||
// <<<<<<<< end of private namespace
|
|||
})(); |
|||
|
|||
/******************************************************************************/ |
|||
|
|||
// Broadcast listening ability
|
|||
|
|||
(( ) => { |
|||
// >>>>>>>> start of private namespace
|
|||
|
|||
if ( |
|||
typeof vAPI !== 'object' || |
|||
vAPI.messaging instanceof Object === false || |
|||
vAPI.broadcastListener instanceof Object |
|||
) { |
|||
return; |
|||
} |
|||
|
|||
const listeners = new Set(); |
|||
|
|||
vAPI.broadcastListener = { |
|||
add: function(listener) { |
|||
listeners.add(listener); |
|||
vAPI.messaging.getPort(); |
|||
}, |
|||
remove: function(listener) { |
|||
listeners.delete(listener); |
|||
}, |
|||
canDestroyPort() { |
|||
return listeners.size === 0; |
|||
}, |
|||
mustDestroyPort() { |
|||
listeners.clear(); |
|||
}, |
|||
canProcessMessage(details) { |
|||
if ( details.broadcast === false ) { return; } |
|||
for ( const listener of listeners ) { |
|||
listener(details.msg); |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
vAPI.messaging.extensions.push(vAPI.broadcastListener); |
|||
|
|||
// <<<<<<<< end of private namespace
|
|||
})(); |
|||
|
|||
/******************************************************************************/ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/******************************************************************************* |
|||
|
|||
DO NOT: |
|||
- Remove the following code |
|||
- Add code beyond the following code |
|||
Reason: |
|||
- https://github.com/gorhill/uBlock/pull/3721
|
|||
- uBO never uses the return value from injected content scripts |
|||
|
|||
**/ |
|||
|
|||
void 0; |
@ -0,0 +1,86 @@ |
|||
/******************************************************************************* |
|||
|
|||
uMatrix - a browser extension to block requests. |
|||
Copyright (C) 2017-present Raymond Hill |
|||
|
|||
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 |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|||
|
|||
Home: https://github.com/gorhill/uBlock
|
|||
*/ |
|||
|
|||
'use strict'; |
|||
|
|||
/* global HTMLDocument, XMLDocument */ |
|||
|
|||
// For background page, auxiliary pages, and content scripts.
|
|||
|
|||
/******************************************************************************/ |
|||
|
|||
if ( self.browser instanceof Object ) { |
|||
self.chrome = self.browser; |
|||
} else { |
|||
self.browser = self.chrome; |
|||
} |
|||
|
|||
/******************************************************************************/ |
|||
|
|||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1408996#c9
|
|||
var vAPI = self.vAPI; // jshint ignore:line
|
|||
|
|||
// https://github.com/chrisaljoudi/uBlock/issues/464
|
|||
// https://github.com/chrisaljoudi/uBlock/issues/1528
|
|||
// A XMLDocument can be a valid HTML document.
|
|||
|
|||
// https://github.com/gorhill/uBlock/issues/1124
|
|||
// Looks like `contentType` is on track to be standardized:
|
|||
// https://dom.spec.whatwg.org/#concept-document-content-type
|
|||
|
|||
// https://forums.lanik.us/viewtopic.php?f=64&t=31522
|
|||
// Skip text/plain documents.
|
|||
|
|||
if ( |
|||
( |
|||
document instanceof HTMLDocument || |
|||
document instanceof XMLDocument && |
|||
document.createElement('div') instanceof HTMLDivElement |
|||
) && |
|||
( |
|||
/^image\/|^text\/plain/.test(document.contentType || '') === false |
|||
) && |
|||
( |
|||
self.vAPI instanceof Object === false || vAPI.uMatrix !== true |
|||
) |
|||
) { |
|||
vAPI = self.vAPI = { uMatrix: true }; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/******************************************************************************* |
|||
|
|||
DO NOT: |
|||
- Remove the following code |
|||
- Add code beyond the following code |
|||
Reason: |
|||
- https://github.com/gorhill/uBlock/pull/3721
|
|||
- uMatrix never uses the return value from injected content scripts |
|||
|
|||
**/ |
|||
|
|||
void 0; |
@ -0,0 +1,176 @@ |
|||
/******************************************************************************* |
|||
|
|||
uBlock Origin - a browser extension to block requests. |
|||
Copyright (C) 2019-present Raymond Hill |
|||
|
|||
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 |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|||
|
|||
Home: https://github.com/gorhill/uBlock
|
|||
*/ |
|||
|
|||
'use strict'; |
|||
|
|||
// `webext` is a promisified api of `chrome`. Entries are added as
|
|||
// the promisification of uBO progress.
|
|||
|
|||
const webext = (( ) => { // jshint ignore:line
|
|||
// >>>>> start of private scope
|
|||
|
|||
const noopFunc = ( ) => { }; |
|||
|
|||
const promisifyNoFail = function(thisArg, fnName, outFn = r => r) { |
|||
const fn = thisArg[fnName]; |
|||
return function() { |
|||
return new Promise(resolve => { |
|||
fn.call(thisArg, ...arguments, function() { |
|||
if ( chrome.runtime.lastError instanceof Object ) { |
|||
void chrome.runtime.lastError.message; |
|||
} |
|||
resolve(outFn(...arguments)); |
|||
}); |
|||
}); |
|||
}; |
|||
}; |
|||
|
|||
const promisify = function(thisArg, fnName) { |
|||
const fn = thisArg[fnName]; |
|||
return function() { |
|||
return new Promise((resolve, reject) => { |
|||
fn.call(thisArg, ...arguments, function() { |
|||
const lastError = chrome.runtime.lastError; |
|||
if ( lastError instanceof Object ) { |
|||
return reject(lastError.message); |
|||
} |
|||
resolve(...arguments); |
|||
}); |
|||
}); |
|||