mirror of
https://github.com/QuiteAFancyEmerald/Holy-Unblocker.git
synced 2025-05-15 21:00:00 -04:00
UV Added! (Repl support not a given yet)
This commit is contained in:
parent
d70d202131
commit
ec78402863
14 changed files with 772 additions and 199 deletions
|
@ -32,7 +32,7 @@ const pages = {
|
||||||
'rh': 'pages/proxnav/rammerhead.html',
|
'rh': 'pages/proxnav/rammerhead.html',
|
||||||
'w': 'pages/proxnav/womginx.html',
|
'w': 'pages/proxnav/womginx.html',
|
||||||
/* Proxy Presets */
|
/* Proxy Presets */
|
||||||
'sx': 'pages/proxnav/preset/searx.html',
|
'sx': 'pages/proxnav/preset/spotify.html',
|
||||||
'y': 'pages/proxnav/preset/youtube.html',
|
'y': 'pages/proxnav/preset/youtube.html',
|
||||||
'd': 'pages/proxnav/preset/discord.html',
|
'd': 'pages/proxnav/preset/discord.html',
|
||||||
'r': 'pages/proxnav/preset/reddit.html',
|
'r': 'pages/proxnav/preset/reddit.html',
|
||||||
|
|
|
@ -7,7 +7,6 @@ import pkg from './routes.mjs';
|
||||||
import { paintSource, tryReadFile } from './randomization.mjs';
|
import { paintSource, tryReadFile } from './randomization.mjs';
|
||||||
|
|
||||||
const bare = new Server('/bare/', '');
|
const bare = new Server('/bare/', '');
|
||||||
|
|
||||||
const config = JSON.parse(await readFile(new URL('./config.json',
|
const config = JSON.parse(await readFile(new URL('./config.json',
|
||||||
import.meta.url)));
|
import.meta.url)));
|
||||||
const { pages, text404 } = pkg;
|
const { pages, text404 } = pkg;
|
||||||
|
@ -18,12 +17,10 @@ const router = express.Router();
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
|
|
||||||
router.get('/', async(req, res) => res.send(paintSource(tryReadFile(path.normalize(__dirname + '/views/' + (['/', '/?'].includes(req.url) ? pages.index : pages[Object.keys(req.query)[0]]))))));
|
router.get('/', async(req, res) => res.send(paintSource(tryReadFile(path.normalize(__dirname + '/views/' + (['/', '/?'].includes(req.url) ? pages.index : pages[Object.keys(req.query)[0]]))))));
|
||||||
|
|
||||||
app.use('/', (req, res, next) => {
|
|
||||||
if (!bare.route_request(req, res)) return next()
|
|
||||||
});
|
|
||||||
|
|
||||||
app.use(router);
|
app.use(router);
|
||||||
|
app.use('/', (req, res, next) => {
|
||||||
|
if (!bare.route_request(req, res)) return next()
|
||||||
|
});
|
||||||
app.use(express.static(path.normalize(__dirname + '/views')));
|
app.use(express.static(path.normalize(__dirname + '/views')));
|
||||||
app.disable('x-powered-by');
|
app.disable('x-powered-by');
|
||||||
app.use((req, res) => {
|
app.use((req, res) => {
|
||||||
|
@ -31,4 +28,4 @@ app.use((req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(port);
|
server.listen(port);
|
||||||
console.log('Holy Unblocker is listening on port ' + port + '.');
|
console.log('Holy Unblocker is listening on port ' + port + '.');
|
|
@ -1 +1 @@
|
||||||
document.getElementById("header").innerHTML = decodeURIComponent(atob("JTNDYSUyMGhyZWYlM0QlMjIlMkYlMjIlMjBjbGFzcyUzRCUyMmJyYW5kJTIyJTNFSCUyNiUyMzE3MyUzQm8lMjYlMjMxNzMlM0JseSUyMFUlMjYlMjMxNzMlM0JuJTI2JTIzMTczJTNCYiUyNiUyMzE3MyUzQmxvJTI2JTIzMTczJTNCYyUyNiUyMzE3MyUzQmslMjYlMjMxNzMlM0JlciUzQyUyRmElM0UlM0NpbnB1dCUyMGlkJTNEJTIybW5hdmVjYiUyMiUyMHR5cGUlM0QlMjJjaGVja2JveCUyMiUzRSUzQ2xhYmVsJTIwZm9yJTNEJTIybW5hdmVjYiUyMiUyMGNsYXNzJTNEJTIybW5hdmUlMjIlM0UlM0NzcGFuJTIwY2xhc3MlM0QlMjJtbmF2ZWJ1dHRvbiUyMiUzRSUzQyUyRnNwYW4lM0UlM0MlMkZsYWJlbCUzRSUzQ3VsJTIwY2xhc3MlM0QlMjJuYXZiYXIlMjIlM0UlMjAlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGeiUyMiUzRVclMjYlMjMxNzMlM0JlYiUyMFByJTI2JTIzMTczJTNCb3glMjYlMjMxNzMlM0JpZSUyNiUyMzE3MyUzQnMlM0MlMkZhJTNFJTNDJTJGbGklM0UlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGc3glMjIlM0VTZWFyeCUzQyUyRmElM0UlM0MlMkZsaSUzRSUzQ2xpJTNFJTNDYSUyMGhyZWYlM0QlMjIlMkYlM0ZnJTIyJTNFRyUyNiUyMzE3MyUzQmElMjYlMjMxNzMlM0JtZSUyNiUyMzE3MyUzQnMlM0MlMkZhJTNFJTNDJTJGbGklM0UlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGeSUyMiUzRVlvJTI2JTIzMTczJTNCdVQlMjYlMjMxNzMlM0J1JTI2JTIzMTczJTNCYmUlM0MlMkZhJTNFJTNDJTJGbGklM0UlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGZCUyMiUzRUQlMjYlMjMxNzMlM0Jpc2MlMjYlMjMxNzMlM0JvciUyNiUyMzE3MyUzQmQlM0MlMkZhJTNFJTNDJTJGbGklM0UlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGciUyMiUzRVJlJTI2JTIzMTczJTNCZGQlMjYlMjMxNzMlM0JpdCUzQyUyRmElM0UlM0MlMkZsaSUzRSUzQ2xpJTIwY2xhc3MlM0QlMjJkcm9wZG93bi1wYXJlbnQlMjIlM0UlM0NhJTIwaHJlZiUzRCUyMiUyMyUyMiUzRU0lMjYlMjMxNzMlM0JvciUyNiUyMzE3MyUzQmUlMjAlM0NpJTIwY2xhc3MlM0QlMjJmYXMlMjBmYS1lbGxpcHNpcy12JTIyJTNFJTNDJTJGaSUzRSUzQyUyRmElM0UlMjAlM0NkaXYlMjBjbGFzcyUzRCUyMmRyb3Bkb3duLWNoaWxkJTIyJTIwdGFiaW5kZXglM0QlMjIwJTIyJTNFJTIwJTNDdWwlMjBjbGFzcyUzRCUyMnN1Ym5hdmJhciUyMiUzRSUyMCUzQ2klMjBjbGFzcyUzRCUyMmZhcyUyMGZhLWJhcnMlMjIlM0UlM0MlMkZpJTNFJTIwJTNDbGklM0UlM0NhJTIwaHJlZiUzRCUyMiUyRiUzRnglMjIlM0VCb29rJTI2JTIzMTczJTNCbWFyayUyNiUyMzE3MyUzQmxldHMlM0MlMkZhJTNFJTNDJTJGbGklM0UlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGaW4lMjIlM0VEb2NzJTNDJTJGYSUzRSUzQyUyRmxpJTNFJTNDbGklM0UlM0NhJTIwaHJlZiUzRCUyMiUyRiUzRmZhcSUyMiUzRUZBJTI2JTIzMTczJTNCUSUzQyUyRmElM0UlM0MlMkZsaSUzRSUzQ2xpJTNFJTNDYSUyMGhyZWYlM0QlMjIlMkYlM0ZjJTIyJTNFQ3JlZGl0JTI2JTIzMTczJTNCcyUzQyUyRmElM0UlM0MlMkZsaSUzRSUzQ2xpJTNFJTNDYSUyMGhyZWYlM0QlMjIlMkYlM0Z0JTIyJTNFVE8lMjYlMjMxNzMlM0JTJTNDJTJGYSUzRSUzQyUyRmxpJTNFJTNDJTJGdWwlM0UlMjAlM0MlMkZkaXYlM0UlM0MlMkZsaSUzRSUzQ2xpJTIwY2xhc3MlM0QlMjJkcm9wZG93bi1wYXJlbnQlMjIlM0UlM0NhJTIwaHJlZiUzRCUyMiUyMyUyMiUzRVNldHRpbmdzJTIwJTNDaSUyMGNsYXNzJTNEJTIyZmFzJTIwZmEtY29nJTIyJTNFJTNDJTJGaSUzRSUzQyUyRmElM0UlMjAlM0NkaXYlMjBjbGFzcyUzRCUyMmRyb3Bkb3duLWNoaWxkJTIyJTIwdGFiaW5kZXglM0QlMjIwJTIyJTNFJTIwJTNDZGl2JTIwaWQlM0QlMjJjc2VsJTIyJTNFJTNDJTJGZGl2JTNFJTNDJTJGZGl2JTNFJTNDJTJGbGklM0UlM0MlMkZ1bCUzRQ=="));
|
document.getElementById("header").innerHTML = decodeURIComponent(atob("JTNDYSUyMGhyZWYlM0QlMjIlMkYlMjIlMjBjbGFzcyUzRCUyMmJyYW5kJTIyJTNFSCUyNiUyMzE3MyUzQm8lMjYlMjMxNzMlM0JseSUyMFUlMjYlMjMxNzMlM0JuJTI2JTIzMTczJTNCYiUyNiUyMzE3MyUzQmxvJTI2JTIzMTczJTNCYyUyNiUyMzE3MyUzQmslMjYlMjMxNzMlM0JlciUzQyUyRmElM0UlMEElM0NpbnB1dCUyMGlkJTNEJTIybW5hdmVjYiUyMiUyMHR5cGUlM0QlMjJjaGVja2JveCUyMiUzRSUwQSUzQ2xhYmVsJTIwZm9yJTNEJTIybW5hdmVjYiUyMiUyMGNsYXNzJTNEJTIybW5hdmUlMjIlM0UlM0NzcGFuJTIwY2xhc3MlM0QlMjJtbmF2ZWJ1dHRvbiUyMiUzRSUzQyUyRnNwYW4lM0UlM0MlMkZsYWJlbCUzRSUwQSUzQ3VsJTIwY2xhc3MlM0QlMjJuYXZiYXIlMjIlM0UlMEElMjAlMjAlMjAlMjAlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGeiUyMiUzRVclMjYlMjMxNzMlM0JlYiUyMFByJTI2JTIzMTczJTNCb3glMjYlMjMxNzMlM0JpZSUyNiUyMzE3MyUzQnMlM0MlMkZhJTNFJTNDJTJGbGklM0UlMEElMjAlMjAlMjAlMjAlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGZyUyMiUzRUclMjYlMjMxNzMlM0JhJTI2JTIzMTczJTNCbWUlMjYlMjMxNzMlM0JzJTNDJTJGYSUzRSUzQyUyRmxpJTNFJTBBJTIwJTIwJTIwJTIwJTNDbGklM0UlM0NhJTIwaHJlZiUzRCUyMiUyRiUzRnN4JTIyJTNFUyUyNiUyMzE3MyUzQnBvdGklMjYlMjMxNzMlM0JmeSUzQyUyRmElM0UlM0MlMkZsaSUzRSUwQSUyMCUyMCUyMCUyMCUzQ2xpJTNFJTNDYSUyMGhyZWYlM0QlMjIlMkYlM0Z5JTIyJTNFWW8lMjYlMjMxNzMlM0J1VCUyNiUyMzE3MyUzQnUlMjYlMjMxNzMlM0JiZSUzQyUyRmElM0UlM0MlMkZsaSUzRSUwQSUyMCUyMCUyMCUyMCUzQ2xpJTNFJTNDYSUyMGhyZWYlM0QlMjIlMkYlM0ZkJTIyJTNFRCUyNiUyMzE3MyUzQmlzYyUyNiUyMzE3MyUzQm9yJTI2JTIzMTczJTNCZCUzQyUyRmElM0UlM0MlMkZsaSUzRSUwQSUyMCUyMCUyMCUyMCUzQ2xpJTNFJTNDYSUyMGhyZWYlM0QlMjIlMkYlM0ZyJTIyJTNFUmUlMjYlMjMxNzMlM0JkZCUyNiUyMzE3MyUzQml0JTNDJTJGYSUzRSUzQyUyRmxpJTNFJTBBJTIwJTIwJTIwJTIwJTNDIS0tJTIwdGFiaW5kZXglM0QlMjIwJTIyJTIwaXMlMjByZXF1aXJlZCUyMG9uJTIwdGhlJTIwZHJvcGRvd25zJTIwLS0lM0UlMEElMjAlMjAlMjAlMjAlM0NsaSUyMGNsYXNzJTNEJTIyZHJvcGRvd24tcGFyZW50JTIyJTNFJTNDYSUyMGhyZWYlM0QlMjIlMjMlMjIlM0VNJTI2JTIzMTczJTNCb3IlMjYlMjMxNzMlM0JlJTIwJTNDaSUyMGNsYXNzJTNEJTIyZmFzJTIwZmEtZWxsaXBzaXMtdiUyMiUzRSUzQyUyRmklM0UlM0MlMkZhJTNFJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNDZGl2JTIwY2xhc3MlM0QlMjJkcm9wZG93bi1jaGlsZCUyMiUyMHRhYmluZGV4JTNEJTIyMCUyMiUzRSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQ3VsJTIwY2xhc3MlM0QlMjJzdWJuYXZiYXIlMjIlM0UlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0NpJTIwY2xhc3MlM0QlMjJmYXMlMjBmYS1iYXJzJTIyJTNFJTNDJTJGaSUzRSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQ2xpJTNFJTNDYSUyMGhyZWYlM0QlMjIlMkYlM0Z4JTIyJTNFQm9vayUyNiUyMzE3MyUzQm1hcmslMjYlMjMxNzMlM0JsZXRzJTNDJTJGYSUzRSUzQyUyRmxpJTNFJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNDbGklM0UlM0NhJTIwaHJlZiUzRCUyMiUyRiUzRmluJTIyJTNFRG9jcyUzQyUyRmElM0UlM0MlMkZsaSUzRSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQ2xpJTNFJTNDYSUyMGhyZWYlM0QlMjIlMkYlM0ZmYXElMjIlM0VGQSUyNiUyMzE3MyUzQlElM0MlMkZhJTNFJTNDJTJGbGklM0UlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGYyUyMiUzRUNyZWRpdCUyNiUyMzE3MyUzQnMlM0MlMkZhJTNFJTNDJTJGbGklM0UlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0NsaSUzRSUzQ2ElMjBocmVmJTNEJTIyJTJGJTNGdCUyMiUzRVRPJTI2JTIzMTczJTNCUyUzQyUyRmElM0UlM0MlMkZsaSUzRSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQyUyRnVsJTNFJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNDJTJGZGl2JTNFJTBBJTIwJTIwJTIwJTIwJTNDJTJGbGklM0UlMEElMjAlMjAlMjAlMjAlM0NsaSUyMGNsYXNzJTNEJTIyZHJvcGRvd24tcGFyZW50JTIyJTNFJTNDYSUyMGhyZWYlM0QlMjIlMjMlMjIlM0VTZXR0aW5ncyUyMCUzQ2klMjBjbGFzcyUzRCUyMmZhcyUyMGZhLWNvZyUyMiUzRSUzQyUyRmklM0UlM0MlMkZhJTNFJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNDZGl2JTIwY2xhc3MlM0QlMjJkcm9wZG93bi1jaGlsZCUyMiUyMHRhYmluZGV4JTNEJTIyMCUyMiUzRSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQ2RpdiUyMGlkJTNEJTIyY3NlbCUyMiUzRSUzQyUyRmRpdiUzRSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQyUyRmRpdiUzRSUwQSUyMCUyMCUyMCUyMCUzQyUyRmxpJTNFJTBBJTNDJTJGdWwlM0U="));
|
|
@ -39,6 +39,13 @@
|
||||||
</script>
|
</script>
|
||||||
<script src="uv.bundle.js"></script>
|
<script src="uv.bundle.js"></script>
|
||||||
<script src="uv.config.js"></script>
|
<script src="uv.config.js"></script>
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.navigator.serviceWorker.register('/sw.js', {
|
||||||
|
scope: __uv$config.prefix,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script src="assets/js/csel.js"></script>
|
<script src="assets/js/csel.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,13 @@
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
||||||
<script src="uv.bundle.js"></script>
|
<script src="uv.bundle.js"></script>
|
||||||
<script src="uv.config.js"></script>
|
<script src="uv.config.js"></script>
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.navigator.serviceWorker.register('/sw.js', {
|
||||||
|
scope: __uv$config.prefix,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script src="assets/js/common.js"></script>
|
<script src="assets/js/common.js"></script>
|
||||||
<script src="assets/js/links.js"></script>
|
<script src="assets/js/links.js"></script>
|
||||||
<script src="assets/js/header.js"></script>
|
<script src="assets/js/header.js"></script>
|
||||||
|
|
|
@ -46,6 +46,13 @@
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
||||||
<script src="uv.bundle.js"></script>
|
<script src="uv.bundle.js"></script>
|
||||||
<script src="uv.config.js"></script>
|
<script src="uv.config.js"></script>
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.navigator.serviceWorker.register('/sw.js', {
|
||||||
|
scope: __uv$config.prefix,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script src="assets/js/common.js"></script>
|
<script src="assets/js/common.js"></script>
|
||||||
<script src="assets/js/header.js"></script>
|
<script src="assets/js/header.js"></script>
|
||||||
<script src="assets/js/csel.js"></script>
|
<script src="assets/js/csel.js"></script>
|
||||||
|
|
|
@ -24,10 +24,11 @@
|
||||||
<div class="ad" id="ad-right"></div>
|
<div class="ad" id="ad-right"></div>
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
||||||
<div class="box box-medium text-center textm">
|
<div class="box box-medium text-center textm">
|
||||||
<h1 class="bigtitle">Searx</h1>
|
<h1 class="bigtitle">Spotify</h1>
|
||||||
<p class="responsive-fix">
|
<p class="responsive-fix">
|
||||||
Sea­rx is a free inte­rnet me­tasearch en­gine which ag­gregates r­esults from mo­re than 7­0 sea­rch ser­vices. User­s are neit­her tra­cked nor pr­ofil­ed.
|
Sp­oti­fy is a digi­tal mus­ic, podc­ast, and v­ideo servi­ce th­at giv­es yo­u acc­ess to mill­ions of so­ngs and oth­er cont­ent f­rom creat­ors all o­ver the
|
||||||
<br>Add­itiona­lly, se­arx c­an be u­sed ov­er To­r for onli­ne anonym­ity.
|
wor­ld.
|
||||||
|
<br>Using Ult­rav­iolet, Spo­tify wo­rks wh­ile b­eing su­per fa­st. Enj­oy unblo­cked mu­sic strea­ming!
|
||||||
</p>
|
</p>
|
||||||
<h3>Having Issues?</h3>
|
<h3>Having Issues?</h3>
|
||||||
<p class="font3 accented">
|
<p class="font3 accented">
|
||||||
|
@ -35,12 +36,22 @@
|
||||||
<br>Sometimes the pro­xie­s are under high load so things may be s­low, sorry. In that case simply wait for the pa­ge to load.
|
<br>Sometimes the pro­xie­s are under high load so things may be s­low, sorry. In that case simply wait for the pa­ge to load.
|
||||||
</p>
|
</p>
|
||||||
<div class="responsive-fix">
|
<div class="responsive-fix">
|
||||||
<p>Down for now.</p>
|
<a class="fancybutton glowbutton" href="#" onclick="goProx.ultraviolet('https://open.spotify.com');">Classic</a>
|
||||||
|
<a class="fancybutton glowbutton" href="#" onclick="goProx.ultraviolet('https://open.spotify.com', true);">Stealth</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="footer" class="fullwidth"></div>
|
<div id="footer" class="fullwidth"></div>
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
||||||
|
<script src="uv.bundle.js"></script>
|
||||||
|
<script src="uv.config.js"></script>
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.navigator.serviceWorker.register('/sw.js', {
|
||||||
|
scope: __uv$config.prefix,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script src="assets/js/common.js"></script>
|
<script src="assets/js/common.js"></script>
|
||||||
<script src="assets/js/header.js"></script>
|
<script src="assets/js/header.js"></script>
|
||||||
<script src="assets/js/csel.js"></script>
|
<script src="assets/js/csel.js"></script>
|
|
@ -45,6 +45,13 @@
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
||||||
<script src="uv.bundle.js"></script>
|
<script src="uv.bundle.js"></script>
|
||||||
<script src="uv.config.js"></script>
|
<script src="uv.config.js"></script>
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.navigator.serviceWorker.register('/sw.js', {
|
||||||
|
scope: __uv$config.prefix,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script src="assets/js/common.js"></script>
|
<script src="assets/js/common.js"></script>
|
||||||
<script src="assets/js/header.js"></script>
|
<script src="assets/js/header.js"></script>
|
||||||
<script src="assets/js/csel.js"></script>
|
<script src="assets/js/csel.js"></script>
|
||||||
|
|
|
@ -62,6 +62,13 @@
|
||||||
</script>
|
</script>
|
||||||
<script src="uv.bundle.js"></script>
|
<script src="uv.bundle.js"></script>
|
||||||
<script src="uv.config.js"></script>
|
<script src="uv.config.js"></script>
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.navigator.serviceWorker.register('/sw.js', {
|
||||||
|
scope: __uv$config.prefix,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script src="assets/js/header.js"></script>
|
<script src="assets/js/header.js"></script>
|
||||||
<script src="assets/js/csel.js"></script>
|
<script src="assets/js/csel.js"></script>
|
||||||
<script src="assets/js/footer.js"></script>
|
<script src="assets/js/footer.js"></script>
|
||||||
|
|
9
views/sw.js
Normal file
9
views/sw.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
importScripts('./uv.sw.js');
|
||||||
|
|
||||||
|
const sw = new UVServiceWorker();
|
||||||
|
|
||||||
|
self.addEventListener('fetch', event =>
|
||||||
|
event.respondWith(
|
||||||
|
sw.fetch(event)
|
||||||
|
)
|
||||||
|
);
|
|
@ -37985,6 +37985,10 @@ class WebSocketApi extends _events_js__WEBPACK_IMPORTED_MODULE_0__["default"] {
|
||||||
this.protocol = ctx.nativeMethods.getOwnPropertyDescriptor(this.wsProto, 'protocol');
|
this.protocol = ctx.nativeMethods.getOwnPropertyDescriptor(this.wsProto, 'protocol');
|
||||||
this.send = this.wsProto.send;
|
this.send = this.wsProto.send;
|
||||||
this.close = this.wsProto.close;
|
this.close = this.wsProto.close;
|
||||||
|
this.CONNECTING = 0;
|
||||||
|
this.OPEN = 1;
|
||||||
|
this.CLOSING = 2;
|
||||||
|
this.CLOSED = 3;
|
||||||
};
|
};
|
||||||
overrideWebSocket() {
|
overrideWebSocket() {
|
||||||
this.ctx.override(this.window, 'WebSocket', (target, that, args) => {
|
this.ctx.override(this.window, 'WebSocket', (target, that, args) => {
|
||||||
|
@ -37998,6 +38002,11 @@ class WebSocketApi extends _events_js__WEBPACK_IMPORTED_MODULE_0__["default"] {
|
||||||
if (event.intercepted) return event.returnValue;
|
if (event.intercepted) return event.returnValue;
|
||||||
return new event.target(event.data.url, event.data.protocols);
|
return new event.target(event.data.url, event.data.protocols);
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
this.window.WebSocket.CONNECTING = this.CONNECTING;
|
||||||
|
this.window.WebSocket.OPEN = this.OPEN;
|
||||||
|
this.window.WebSocket.CLOSING = this.CLOSING;
|
||||||
|
this.window.WebSocket.CLOSED = this.CLOSED;
|
||||||
};
|
};
|
||||||
overrideUrl() {
|
overrideUrl() {
|
||||||
this.ctx.overrideDescriptor(this.wsProto, 'url', {
|
this.ctx.overrideDescriptor(this.wsProto, 'url', {
|
||||||
|
@ -39050,9 +39059,9 @@ class Ultraviolet {
|
||||||
this.meta = options.meta || {};
|
this.meta = options.meta || {};
|
||||||
this.meta.base ||= undefined;
|
this.meta.base ||= undefined;
|
||||||
this.meta.origin ||= '';
|
this.meta.origin ||= '';
|
||||||
this.bundleScript = options.bundleScript || '/uv.bundle.js';
|
this.bundleScript = options.bundle || '/uv.bundle.js';
|
||||||
this.handlerScript = options.handlerScript || '/uv.handler.js';
|
this.handlerScript = options.handler || '/uv.handler.js';
|
||||||
this.configScript = options.handlerScript || '/uv.config.js';
|
this.configScript = options.config || '/uv.config.js';
|
||||||
this.meta.url ||= this.meta.base || '';
|
this.meta.url ||= this.meta.base || '';
|
||||||
this.codec = Ultraviolet.codec;
|
this.codec = Ultraviolet.codec;
|
||||||
this.html = new _html_js__WEBPACK_IMPORTED_MODULE_0__["default"](this);
|
this.html = new _html_js__WEBPACK_IMPORTED_MODULE_0__["default"](this);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
self.__uv$config = {
|
self.__uv$config = {
|
||||||
prefix: '/sw/',
|
prefix: '/service/',
|
||||||
bare: '/bare/',
|
bare: 'https://cdn.' + location.hostname + '/bare/',
|
||||||
encodeUrl: Ultraviolet.codec.xor.encode,
|
encodeUrl: Ultraviolet.codec.xor.encode,
|
||||||
decodeUrl: Ultraviolet.codec.xor.decode,
|
decodeUrl: Ultraviolet.codec.xor.decode,
|
||||||
handler: '/uv.handler.js',
|
handler: '/uv.handler.js',
|
||||||
bundle: '/uv.bundle.js',
|
bundle: '/uv.bundle.js',
|
||||||
config: '/uv.config.js',
|
config: '/uv.config.js',
|
||||||
sw: '/uv.sw.js',
|
sw: '/uv.sw.js',
|
||||||
};
|
};
|
|
@ -17,6 +17,10 @@ async function __uvHook(window, config = {}, bare = '/bare/') {
|
||||||
window,
|
window,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (typeof config.construct === 'function') {
|
||||||
|
config.construct(__uv, worker ? 'worker' : 'window');
|
||||||
|
};
|
||||||
|
|
||||||
const { client } = __uv;
|
const { client } = __uv;
|
||||||
const {
|
const {
|
||||||
HTMLMediaElement,
|
HTMLMediaElement,
|
||||||
|
|
868
views/uv.sw.js
868
views/uv.sw.js
|
@ -1,196 +1,135 @@
|
||||||
importScripts('./uv.bundle.js');
|
importScripts('./uv.bundle.js');
|
||||||
importScripts('./uv.config.js')
|
importScripts('./uv.config.js');
|
||||||
|
|
||||||
const csp = [
|
|
||||||
'cross-origin-embedder-policy',
|
|
||||||
'cross-origin-opener-policy',
|
|
||||||
'cross-origin-resource-policy',
|
|
||||||
'content-security-policy',
|
|
||||||
'content-security-policy-report-only',
|
|
||||||
'expect-ct',
|
|
||||||
'feature-policy',
|
|
||||||
'origin-isolation',
|
|
||||||
'strict-transport-security',
|
|
||||||
'upgrade-insecure-requests',
|
|
||||||
'x-content-type-options',
|
|
||||||
'x-download-options',
|
|
||||||
'x-frame-options',
|
|
||||||
'x-permitted-cross-domain-policies',
|
|
||||||
'x-powered-by',
|
|
||||||
'x-xss-protection',
|
|
||||||
];
|
|
||||||
|
|
||||||
const headers = {
|
|
||||||
csp: [
|
|
||||||
'cross-origin-embedder-policy',
|
|
||||||
'cross-origin-opener-policy',
|
|
||||||
'cross-origin-resource-policy',
|
|
||||||
'content-security-policy',
|
|
||||||
'content-security-policy-report-only',
|
|
||||||
'expect-ct',
|
|
||||||
'feature-policy',
|
|
||||||
'origin-isolation',
|
|
||||||
'strict-transport-security',
|
|
||||||
'upgrade-insecure-requests',
|
|
||||||
'x-content-type-options',
|
|
||||||
'x-download-options',
|
|
||||||
'x-frame-options',
|
|
||||||
'x-permitted-cross-domain-policies',
|
|
||||||
'x-powered-by',
|
|
||||||
'x-xss-protection',
|
|
||||||
],
|
|
||||||
forward: [
|
|
||||||
'accept-encoding',
|
|
||||||
'connection',
|
|
||||||
'content-length',
|
|
||||||
'content-type',
|
|
||||||
'user-agent',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const scripts = {
|
|
||||||
package: '/uv.bundle.js',
|
|
||||||
handler: '/uv.handler.js',
|
|
||||||
};
|
|
||||||
|
|
||||||
const method = {
|
|
||||||
empty: ['GET', 'HEAD']
|
|
||||||
};
|
|
||||||
|
|
||||||
const statusCode = {
|
|
||||||
empty: [
|
|
||||||
204,
|
|
||||||
304,
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const handler = UVServiceWorker(__uv$config.bare, __uv$config);
|
|
||||||
|
|
||||||
addEventListener('fetch', async event =>
|
|
||||||
event.respondWith(handler(event))
|
|
||||||
);
|
|
||||||
|
|
||||||
addEventListener('install', () => {
|
|
||||||
self.skipWaiting();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function UVServiceWorker(_bare = '/bare/', options) {
|
|
||||||
try {
|
|
||||||
return async function handler(event) {
|
|
||||||
const { request } = event;
|
|
||||||
const bare = new URL(_bare, location.href);
|
|
||||||
|
|
||||||
|
class UVServiceWorker extends EventEmitter {
|
||||||
|
constructor(config = __uv$config) {
|
||||||
|
super();
|
||||||
|
if (!config.bare) config.bare = '/bare/';
|
||||||
|
this.addresses = typeof config.bare === 'string' ? [ new URL(config.bare, location) ] : config.bare.map(str => new URL(str, location));
|
||||||
|
this.headers = {
|
||||||
|
csp: [
|
||||||
|
'cross-origin-embedder-policy',
|
||||||
|
'cross-origin-opener-policy',
|
||||||
|
'cross-origin-resource-policy',
|
||||||
|
'content-security-policy',
|
||||||
|
'content-security-policy-report-only',
|
||||||
|
'expect-ct',
|
||||||
|
'feature-policy',
|
||||||
|
'origin-isolation',
|
||||||
|
'strict-transport-security',
|
||||||
|
'upgrade-insecure-requests',
|
||||||
|
'x-content-type-options',
|
||||||
|
'x-download-options',
|
||||||
|
'x-frame-options',
|
||||||
|
'x-permitted-cross-domain-policies',
|
||||||
|
'x-powered-by',
|
||||||
|
'x-xss-protection',
|
||||||
|
],
|
||||||
|
forward: [
|
||||||
|
'accept-encoding',
|
||||||
|
'connection',
|
||||||
|
'content-length',
|
||||||
|
'content-type',
|
||||||
|
'user-agent',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
this.method = {
|
||||||
|
empty: [
|
||||||
|
'GET',
|
||||||
|
'HEAD'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
this.statusCode = {
|
||||||
|
empty: [
|
||||||
|
204,
|
||||||
|
304,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
this.config = config;
|
||||||
|
};
|
||||||
|
async fetch({ request }) {
|
||||||
|
if (!request.url.startsWith(location.origin + (this.config.prefix || '/service/'))) {
|
||||||
|
return fetch(request);
|
||||||
|
};
|
||||||
try {
|
try {
|
||||||
if (!request.url.startsWith(location.origin + (options.prefix || '/service/'))) {
|
|
||||||
return fetch(request);
|
const ultraviolet = new Ultraviolet(this.config);
|
||||||
|
|
||||||
|
if (typeof this.config.construct === 'function') {
|
||||||
|
this.config.construct(ultraviolet, 'service');
|
||||||
};
|
};
|
||||||
|
|
||||||
const requestCtx = {
|
const db = await ultraviolet.cookie.db();
|
||||||
url: bare.href + 'v1/',
|
|
||||||
referrer: false,
|
|
||||||
headers: {},
|
|
||||||
forward: headers.forward,
|
|
||||||
method: request.method,
|
|
||||||
body: !method.empty.includes(request.method.toUpperCase()) ? await request.blob() : null,
|
|
||||||
redirect: request.redirect,
|
|
||||||
credentials: 'omit',
|
|
||||||
mode: request.mode === 'cors' ? request.mode : 'same-origin',
|
|
||||||
blob: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
const uv = new Ultraviolet(options);
|
ultraviolet.meta.origin = location.origin;
|
||||||
const db = await uv.cookie.db();
|
ultraviolet.meta.base = ultraviolet.meta.url = new URL(ultraviolet.sourceUrl(request.url));
|
||||||
|
|
||||||
uv.meta.origin = location.origin;
|
|
||||||
uv.meta.base = uv.meta.url = new URL(uv.sourceUrl(request.url));
|
|
||||||
|
|
||||||
if (uv.meta.url.protocol === 'blob:') {
|
const requestCtx = new RequestContext(
|
||||||
|
request,
|
||||||
|
this,
|
||||||
|
ultraviolet,
|
||||||
|
!this.method.empty.includes(request.method.toUpperCase()) ? await request.blob() : null
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ultraviolet.meta.url.protocol === 'blob:') {
|
||||||
requestCtx.blob = true;
|
requestCtx.blob = true;
|
||||||
uv.meta.base = uv.meta.url = new URL(uv.meta.url.pathname);
|
requestCtx.base = requestCtx.url = new URL(requestCtx.url.pathname);
|
||||||
requestCtx.url = 'blob:' + location.origin + uv.meta.url.pathname;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
requestCtx.headers = Object.fromEntries([...request.headers.entries()]);
|
|
||||||
|
|
||||||
requestCtx.host = uv.meta.url.host;
|
|
||||||
|
|
||||||
if (request.referrer && request.referrer.startsWith(location.origin)) {
|
if (request.referrer && request.referrer.startsWith(location.origin)) {
|
||||||
const referer = new URL(uv.sourceUrl(request.referrer));
|
const referer = new URL(ultraviolet.sourceUrl(request.referrer));
|
||||||
|
|
||||||
if (uv.meta.url.origin !== referer.origin && request.mode === 'cors') {
|
if (ultraviolet.meta.url.origin !== referer.origin && request.mode === 'cors') {
|
||||||
requestCtx.headers.origin = referer.origin;
|
requestCtx.headers.origin = referer.origin;
|
||||||
};
|
};
|
||||||
|
|
||||||
requestCtx.headers.referer = referer.href;
|
requestCtx.headers.referer = referer.href;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cookies = await uv.cookie.getCookies(db) || [];
|
const cookies = await ultraviolet.cookie.getCookies(db) || [];
|
||||||
const cookieStr = uv.cookie.serialize(cookies, uv.meta, false);
|
const cookieStr = ultraviolet.cookie.serialize(cookies, ultraviolet.meta, false);
|
||||||
|
|
||||||
const browser = Ultraviolet.Bowser.getParser(self.navigator.userAgent).getBrowserName();
|
const browser = Ultraviolet.Bowser.getParser(self.navigator.userAgent).getBrowserName();
|
||||||
const forward = [...headers.forward];
|
|
||||||
|
|
||||||
if (browser === 'Firefox' && !(request.destination === 'iframe' || request.destination === 'document')) {
|
if (browser === 'Firefox' && !(request.destination === 'iframe' || request.destination === 'document')) {
|
||||||
forward.shift();
|
requestCtx.forward.shift();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cookieStr) requestCtx.headers.cookie = cookieStr;
|
if (cookieStr) requestCtx.headers.cookie = cookieStr;
|
||||||
|
|
||||||
const bareHeaders = {
|
|
||||||
'x-bare-protocol': uv.meta.url.protocol,
|
|
||||||
'x-bare-host': uv.meta.url.hostname,
|
|
||||||
'x-bare-path': uv.meta.url.pathname + uv.meta.url.search,
|
|
||||||
'x-bare-port': uv.meta.url.port || (uv.meta.url.protocol === 'https:' ? '443' : '80'),
|
|
||||||
'x-bare-headers': JSON.stringify(requestCtx.headers),
|
|
||||||
'x-bare-forward-headers': JSON.stringify(forward),
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchOptions = {
|
const reqEvent = new HookEvent(requestCtx, null, null);
|
||||||
method: requestCtx.method,
|
this.emit('request', reqEvent);
|
||||||
headers: !requestCtx.blob ? bareHeaders : requestCtx.headers,
|
|
||||||
redirect: requestCtx.redirect,
|
|
||||||
credentials: requestCtx.credentials,
|
|
||||||
mode: location.origin !== bare.origin ? 'cors' : requestCtx.mode,
|
|
||||||
};
|
|
||||||
if (requestCtx.body) fetchOptions.body = requestCtx.body;
|
|
||||||
|
|
||||||
|
if (reqEvent.intercepted) return reqEvent.returnValue;
|
||||||
|
|
||||||
|
const response = await fetch(requestCtx.send);
|
||||||
|
|
||||||
const response = await fetch(requestCtx.url, fetchOptions);
|
|
||||||
|
|
||||||
if (response.status === 500) {
|
if (response.status === 500) {
|
||||||
return Promise.reject('Err');
|
return Promise.reject('');
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendData = !requestCtx.blob ? getBarerResponse(response) : {
|
|
||||||
status: response.status,
|
|
||||||
statusText: response.statusText,
|
|
||||||
headers: Object.fromEntries([...response.headers.entries()]),
|
|
||||||
body: response.body,
|
|
||||||
};
|
|
||||||
|
|
||||||
const responseCtx = {
|
const responseCtx = new ResponseContext(requestCtx, response, this);
|
||||||
headers: sendData.headers,
|
const resEvent = new HookEvent(responseCtx, null, null);
|
||||||
status: sendData.status,
|
|
||||||
statusText: sendData.statusText,
|
this.emit('beforemod', resEvent);
|
||||||
body: !statusCode.empty.includes(sendData.status) ? sendData.body : null,
|
if (resEvent.intercepted) return resEvent.returnValue;
|
||||||
};
|
|
||||||
|
for (const name of this.headers.csp) {
|
||||||
for (const name of headers.csp) {
|
|
||||||
if (responseCtx.headers[name]) delete responseCtx.headers[name];
|
if (responseCtx.headers[name]) delete responseCtx.headers[name];
|
||||||
};
|
};
|
||||||
|
|
||||||
if (responseCtx.headers.location) {
|
if (responseCtx.headers.location) {
|
||||||
responseCtx.headers.location = uv.rewriteUrl(responseCtx.headers.location);
|
responseCtx.headers.location = ultraviolet.rewriteUrl(responseCtx.headers.location);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (responseCtx.headers['set-cookie']) {
|
if (responseCtx.headers['set-cookie']) {
|
||||||
Promise.resolve(uv.cookie.setCookies(responseCtx.headers['set-cookie'], db, uv.meta)).then(() => {
|
Promise.resolve(ultraviolet.cookie.setCookies(responseCtx.headers['set-cookie'], db, ultraviolet.meta)).then(() => {
|
||||||
self.clients.matchAll().then(function (clients){
|
self.clients.matchAll().then(function (clients){
|
||||||
clients.forEach(function(client){
|
clients.forEach(function(client){
|
||||||
client.postMessage({
|
client.postMessage({
|
||||||
msg: 'updateCookies',
|
msg: 'updateCookies',
|
||||||
url: uv.meta.url.href,
|
url: ultraviolet.meta.url.href,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -203,27 +142,27 @@ function UVServiceWorker(_bare = '/bare/', options) {
|
||||||
case 'script':
|
case 'script':
|
||||||
case 'worker':
|
case 'worker':
|
||||||
responseCtx.body = `if (!self.__uv && self.importScripts) importScripts('${__uv$config.bundle}', '${__uv$config.config}', '${__uv$config.handler}');\n`;
|
responseCtx.body = `if (!self.__uv && self.importScripts) importScripts('${__uv$config.bundle}', '${__uv$config.config}', '${__uv$config.handler}');\n`;
|
||||||
responseCtx.body += uv.js.rewrite(
|
responseCtx.body += ultraviolet.js.rewrite(
|
||||||
await response.text()
|
await response.text()
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'style':
|
case 'style':
|
||||||
responseCtx.body = uv.rewriteCSS(
|
responseCtx.body = ultraviolet.rewriteCSS(
|
||||||
await response.text()
|
await response.text()
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'iframe':
|
case 'iframe':
|
||||||
case 'document':
|
case 'document':
|
||||||
if (isHtml(uv.meta.url, (sendData.headers['content-type'] || ''))) {
|
if (isHtml(ultraviolet.meta.url, (responseCtx.headers['content-type'] || ''))) {
|
||||||
responseCtx.body = uv.rewriteHtml(
|
responseCtx.body = ultraviolet.rewriteHtml(
|
||||||
await response.text(),
|
await response.text(),
|
||||||
{
|
{
|
||||||
document: true ,
|
document: true ,
|
||||||
injectHead: uv.createHtmlInject(
|
injectHead: ultraviolet.createHtmlInject(
|
||||||
options.handler,
|
this.config.handler,
|
||||||
options.bundle,
|
this.config.bundle,
|
||||||
options.config,
|
this.config.config,
|
||||||
uv.cookie.serialize(cookies, uv.meta, true),
|
ultraviolet.cookie.serialize(cookies, ultraviolet.meta, true),
|
||||||
request.referrer
|
request.referrer
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -233,46 +172,615 @@ function UVServiceWorker(_bare = '/bare/', options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (requestCtx.headers.accept === 'text/event-stream') {
|
if (requestCtx.headers.accept === 'text/event-stream') {
|
||||||
requestCtx.headers['content-type'] = 'text/event-stream';
|
responseCtx.headers['content-type'] = 'text/event-stream';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.emit('response', resEvent);
|
||||||
|
if (resEvent.intercepted) return resEvent.returnValue;
|
||||||
|
|
||||||
return new Response(responseCtx.body, {
|
return new Response(responseCtx.body, {
|
||||||
headers: responseCtx.headers,
|
headers: responseCtx.headers,
|
||||||
status: responseCtx.status,
|
status: responseCtx.status,
|
||||||
statusText: responseCtx.statusText,
|
statusText: responseCtx.statusText,
|
||||||
});
|
});
|
||||||
} catch(e) {
|
|
||||||
return new Response(e.toString(), {
|
} catch(err) {
|
||||||
|
return new Response(err.toString(), {
|
||||||
status: 500,
|
status: 500,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} catch(e) {
|
getBarerResponse(response) {
|
||||||
return (event) => {
|
const headers = {};
|
||||||
event.respondWith(new Response(e.toString(), {
|
const raw = JSON.parse(response.headers.get('x-bare-headers'));
|
||||||
status: 500,
|
|
||||||
}))
|
for (const key in raw) {
|
||||||
|
headers[key.toLowerCase()] = raw[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
headers,
|
||||||
|
status: +response.headers.get('x-bare-status'),
|
||||||
|
statusText: response.headers.get('x-bare-status-text'),
|
||||||
|
body: !this.statusCode.empty.includes(+response.headers.get('x-bare-status')) ? response.body : null,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
get address() {
|
||||||
|
return this.addresses[Math.floor(Math.random() * this.addresses.length)];
|
||||||
|
};
|
||||||
|
static Ultraviolet = Ultraviolet;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getBarerResponse(response) {
|
self.UVServiceWorker = UVServiceWorker;
|
||||||
|
|
||||||
const headers = {};
|
|
||||||
const raw = JSON.parse(response.headers.get('x-bare-headers'));
|
|
||||||
|
|
||||||
for (const key in raw) {
|
class ResponseContext {
|
||||||
headers[key.toLowerCase()] = raw[key];
|
constructor(request, response, worker) {
|
||||||
|
const { headers, status, statusText, body } = !request.blob ? worker.getBarerResponse(response) : {
|
||||||
|
status: response.status,
|
||||||
|
statusText: response.statusText,
|
||||||
|
headers: Object.fromEntries([...response.headers.entries()]),
|
||||||
|
body: response.body,
|
||||||
|
};
|
||||||
|
this.request = request;
|
||||||
|
this.raw = response;
|
||||||
|
this.ultraviolet = request.ultraviolet;
|
||||||
|
this.headers = headers;
|
||||||
|
this.status = status;
|
||||||
|
this.statusText = statusText;
|
||||||
|
this.body = body;
|
||||||
};
|
};
|
||||||
|
get url() {
|
||||||
return {
|
return this.request.url;
|
||||||
headers,
|
}
|
||||||
status: +response.headers.get('x-bare-status'),
|
get base() {
|
||||||
statusText: response.headers.get('x-bare-status-text'),
|
return this.request.base;
|
||||||
body: response.body,
|
};
|
||||||
|
set base(val) {
|
||||||
|
this.request.base = val;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RequestContext {
|
||||||
|
constructor(request, worker, ultraviolet, body = null) {
|
||||||
|
this.ultraviolet = ultraviolet;
|
||||||
|
this.request = request;
|
||||||
|
this.headers = Object.fromEntries([...request.headers.entries()]);
|
||||||
|
this.method = request.method;
|
||||||
|
this.forward = [...worker.headers.forward];
|
||||||
|
this.address = worker.address;
|
||||||
|
this.body = body || null;
|
||||||
|
this.redirect = request.redirect;
|
||||||
|
this.credentials = 'omit';
|
||||||
|
this.mode = request.mode === 'cors' ? request.mode : 'same-origin';
|
||||||
|
this.blob = false;
|
||||||
|
};
|
||||||
|
get send() {
|
||||||
|
return new Request((!this.blob ? this.address.href + 'v1/' : 'blob:' + location.origin + this.url.pathname), {
|
||||||
|
method: this.method,
|
||||||
|
headers: {
|
||||||
|
'x-bare-protocol': this.url.protocol,
|
||||||
|
'x-bare-host': this.url.hostname,
|
||||||
|
'x-bare-path': this.url.pathname + this.url.search,
|
||||||
|
'x-bare-port': this.url.port || (this.url.protocol === 'https:' ? '443' : '80'),
|
||||||
|
'x-bare-headers': JSON.stringify(this.headers),
|
||||||
|
'x-bare-forward-headers': JSON.stringify(this.forward),
|
||||||
|
},
|
||||||
|
redirect: this.redirect,
|
||||||
|
credentials: this.credentials,
|
||||||
|
mode: location.origin !== this.address.origin ? 'cors' : this.mode,
|
||||||
|
body: this.body
|
||||||
|
});
|
||||||
|
};
|
||||||
|
get url() {
|
||||||
|
return this.ultraviolet.meta.url;
|
||||||
|
};
|
||||||
|
set url(val) {
|
||||||
|
this.ultraviolet.meta.url = val;
|
||||||
|
};
|
||||||
|
get base() {
|
||||||
|
return this.ultraviolet.meta.base;
|
||||||
|
};
|
||||||
|
set base(val) {
|
||||||
|
this.ultraviolet.meta.base = val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function isHtml(url, contentType = '') {
|
function isHtml(url, contentType = '') {
|
||||||
return (Ultraviolet.mime.contentType((contentType || url.pathname)) || 'text/html').split(';')[0] === 'text/html';
|
return (Ultraviolet.mime.contentType((contentType || url.pathname)) || 'text/html').split(';')[0] === 'text/html';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class HookEvent {
|
||||||
|
#intercepted;
|
||||||
|
#returnValue;
|
||||||
|
constructor(data = {}, target = null, that = null) {
|
||||||
|
this.#intercepted = false;
|
||||||
|
this.#returnValue = null;
|
||||||
|
this.data = data;
|
||||||
|
this.target = target;
|
||||||
|
this.that = that;
|
||||||
|
};
|
||||||
|
get intercepted() {
|
||||||
|
return this.#intercepted;
|
||||||
|
};
|
||||||
|
get returnValue() {
|
||||||
|
return this.#returnValue;
|
||||||
|
};
|
||||||
|
respondWith(input) {
|
||||||
|
this.#returnValue = input;
|
||||||
|
this.#intercepted = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var R = typeof Reflect === 'object' ? Reflect : null
|
||||||
|
var ReflectApply = R && typeof R.apply === 'function'
|
||||||
|
? R.apply
|
||||||
|
: function ReflectApply(target, receiver, args) {
|
||||||
|
return Function.prototype.apply.call(target, receiver, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ReflectOwnKeys
|
||||||
|
if (R && typeof R.ownKeys === 'function') {
|
||||||
|
ReflectOwnKeys = R.ownKeys
|
||||||
|
} else if (Object.getOwnPropertySymbols) {
|
||||||
|
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
||||||
|
return Object.getOwnPropertyNames(target)
|
||||||
|
.concat(Object.getOwnPropertySymbols(target));
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
||||||
|
return Object.getOwnPropertyNames(target);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProcessEmitWarning(warning) {
|
||||||
|
if (console && console.warn) console.warn(warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
|
||||||
|
return value !== value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EventEmitter() {
|
||||||
|
EventEmitter.init.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backwards-compat with node 0.10.x
|
||||||
|
EventEmitter.EventEmitter = EventEmitter;
|
||||||
|
|
||||||
|
EventEmitter.prototype._events = undefined;
|
||||||
|
EventEmitter.prototype._eventsCount = 0;
|
||||||
|
EventEmitter.prototype._maxListeners = undefined;
|
||||||
|
|
||||||
|
// By default EventEmitters will print a warning if more than 10 listeners are
|
||||||
|
// added to it. This is a useful default which helps finding memory leaks.
|
||||||
|
var defaultMaxListeners = 10;
|
||||||
|
|
||||||
|
function checkListener(listener) {
|
||||||
|
if (typeof listener !== 'function') {
|
||||||
|
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
|
||||||
|
enumerable: true,
|
||||||
|
get: function() {
|
||||||
|
return defaultMaxListeners;
|
||||||
|
},
|
||||||
|
set: function(arg) {
|
||||||
|
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
|
||||||
|
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
|
||||||
|
}
|
||||||
|
defaultMaxListeners = arg;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
EventEmitter.init = function() {
|
||||||
|
|
||||||
|
if (this._events === undefined ||
|
||||||
|
this._events === Object.getPrototypeOf(this)._events) {
|
||||||
|
this._events = Object.create(null);
|
||||||
|
this._eventsCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._maxListeners = this._maxListeners || undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Obviously not all Emitters should be limited to 10. This function allows
|
||||||
|
// that to be increased. Set to zero for unlimited.
|
||||||
|
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
|
||||||
|
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
|
||||||
|
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
|
||||||
|
}
|
||||||
|
this._maxListeners = n;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
function _getMaxListeners(that) {
|
||||||
|
if (that._maxListeners === undefined)
|
||||||
|
return EventEmitter.defaultMaxListeners;
|
||||||
|
return that._maxListeners;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
|
||||||
|
return _getMaxListeners(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
EventEmitter.prototype.emit = function emit(type) {
|
||||||
|
var args = [];
|
||||||
|
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
|
||||||
|
var doError = (type === 'error');
|
||||||
|
|
||||||
|
var events = this._events;
|
||||||
|
if (events !== undefined)
|
||||||
|
doError = (doError && events.error === undefined);
|
||||||
|
else if (!doError)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If there is no 'error' event listener then throw.
|
||||||
|
if (doError) {
|
||||||
|
var er;
|
||||||
|
if (args.length > 0)
|
||||||
|
er = args[0];
|
||||||
|
if (er instanceof Error) {
|
||||||
|
// Note: The comments on the `throw` lines are intentional, they show
|
||||||
|
// up in Node's output if this results in an unhandled exception.
|
||||||
|
throw er; // Unhandled 'error' event
|
||||||
|
}
|
||||||
|
// At least give some kind of context to the user
|
||||||
|
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
|
||||||
|
err.context = er;
|
||||||
|
throw err; // Unhandled 'error' event
|
||||||
|
}
|
||||||
|
|
||||||
|
var handler = events[type];
|
||||||
|
|
||||||
|
if (handler === undefined)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (typeof handler === 'function') {
|
||||||
|
ReflectApply(handler, this, args);
|
||||||
|
} else {
|
||||||
|
var len = handler.length;
|
||||||
|
var listeners = arrayClone(handler, len);
|
||||||
|
for (var i = 0; i < len; ++i)
|
||||||
|
ReflectApply(listeners[i], this, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
function _addListener(target, type, listener, prepend) {
|
||||||
|
var m;
|
||||||
|
var events;
|
||||||
|
var existing;
|
||||||
|
|
||||||
|
checkListener(listener);
|
||||||
|
|
||||||
|
events = target._events;
|
||||||
|
if (events === undefined) {
|
||||||
|
events = target._events = Object.create(null);
|
||||||
|
target._eventsCount = 0;
|
||||||
|
} else {
|
||||||
|
// To avoid recursion in the case that type === "newListener"! Before
|
||||||
|
// adding it to the listeners, first emit "newListener".
|
||||||
|
if (events.newListener !== undefined) {
|
||||||
|
target.emit('newListener', type,
|
||||||
|
listener.listener ? listener.listener : listener);
|
||||||
|
|
||||||
|
// Re-assign `events` because a newListener handler could have caused the
|
||||||
|
// this._events to be assigned to a new object
|
||||||
|
events = target._events;
|
||||||
|
}
|
||||||
|
existing = events[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existing === undefined) {
|
||||||
|
// Optimize the case of one listener. Don't need the extra array object.
|
||||||
|
existing = events[type] = listener;
|
||||||
|
++target._eventsCount;
|
||||||
|
} else {
|
||||||
|
if (typeof existing === 'function') {
|
||||||
|
// Adding the second element, need to change to array.
|
||||||
|
existing = events[type] =
|
||||||
|
prepend ? [listener, existing] : [existing, listener];
|
||||||
|
// If we've already got an array, just append.
|
||||||
|
} else if (prepend) {
|
||||||
|
existing.unshift(listener);
|
||||||
|
} else {
|
||||||
|
existing.push(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for listener leak
|
||||||
|
m = _getMaxListeners(target);
|
||||||
|
if (m > 0 && existing.length > m && !existing.warned) {
|
||||||
|
existing.warned = true;
|
||||||
|
// No error code for this since it is a Warning
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
var w = new Error('Possible EventEmitter memory leak detected. ' +
|
||||||
|
existing.length + ' ' + String(type) + ' listeners ' +
|
||||||
|
'added. Use emitter.setMaxListeners() to ' +
|
||||||
|
'increase limit');
|
||||||
|
w.name = 'MaxListenersExceededWarning';
|
||||||
|
w.emitter = target;
|
||||||
|
w.type = type;
|
||||||
|
w.count = existing.length;
|
||||||
|
ProcessEmitWarning(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventEmitter.prototype.addListener = function addListener(type, listener) {
|
||||||
|
return _addListener(this, type, listener, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
||||||
|
|
||||||
|
EventEmitter.prototype.prependListener =
|
||||||
|
function prependListener(type, listener) {
|
||||||
|
return _addListener(this, type, listener, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
function onceWrapper() {
|
||||||
|
if (!this.fired) {
|
||||||
|
this.target.removeListener(this.type, this.wrapFn);
|
||||||
|
this.fired = true;
|
||||||
|
if (arguments.length === 0)
|
||||||
|
return this.listener.call(this.target);
|
||||||
|
return this.listener.apply(this.target, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _onceWrap(target, type, listener) {
|
||||||
|
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
|
||||||
|
var wrapped = onceWrapper.bind(state);
|
||||||
|
wrapped.listener = listener;
|
||||||
|
state.wrapFn = wrapped;
|
||||||
|
return wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventEmitter.prototype.once = function once(type, listener) {
|
||||||
|
checkListener(listener);
|
||||||
|
this.on(type, _onceWrap(this, type, listener));
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
EventEmitter.prototype.prependOnceListener =
|
||||||
|
function prependOnceListener(type, listener) {
|
||||||
|
checkListener(listener);
|
||||||
|
this.prependListener(type, _onceWrap(this, type, listener));
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Emits a 'removeListener' event if and only if the listener was removed.
|
||||||
|
EventEmitter.prototype.removeListener =
|
||||||
|
function removeListener(type, listener) {
|
||||||
|
var list, events, position, i, originalListener;
|
||||||
|
|
||||||
|
checkListener(listener);
|
||||||
|
|
||||||
|
events = this._events;
|
||||||
|
if (events === undefined)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
list = events[type];
|
||||||
|
if (list === undefined)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
if (list === listener || list.listener === listener) {
|
||||||
|
if (--this._eventsCount === 0)
|
||||||
|
this._events = Object.create(null);
|
||||||
|
else {
|
||||||
|
delete events[type];
|
||||||
|
if (events.removeListener)
|
||||||
|
this.emit('removeListener', type, list.listener || listener);
|
||||||
|
}
|
||||||
|
} else if (typeof list !== 'function') {
|
||||||
|
position = -1;
|
||||||
|
|
||||||
|
for (i = list.length - 1; i >= 0; i--) {
|
||||||
|
if (list[i] === listener || list[i].listener === listener) {
|
||||||
|
originalListener = list[i].listener;
|
||||||
|
position = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position < 0)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
if (position === 0)
|
||||||
|
list.shift();
|
||||||
|
else {
|
||||||
|
spliceOne(list, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.length === 1)
|
||||||
|
events[type] = list[0];
|
||||||
|
|
||||||
|
if (events.removeListener !== undefined)
|
||||||
|
this.emit('removeListener', type, originalListener || listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
||||||
|
|
||||||
|
EventEmitter.prototype.removeAllListeners =
|
||||||
|
function removeAllListeners(type) {
|
||||||
|
var listeners, events, i;
|
||||||
|
|
||||||
|
events = this._events;
|
||||||
|
if (events === undefined)
|
||||||
|
return this;
|
||||||
|
|
||||||
|
// not listening for removeListener, no need to emit
|
||||||
|
if (events.removeListener === undefined) {
|
||||||
|
if (arguments.length === 0) {
|
||||||
|
this._events = Object.create(null);
|
||||||
|
this._eventsCount = 0;
|
||||||
|
} else if (events[type] !== undefined) {
|
||||||
|
if (--this._eventsCount === 0)
|
||||||
|
this._events = Object.create(null);
|
||||||
|
else
|
||||||
|
delete events[type];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit removeListener for all listeners on all events
|
||||||
|
if (arguments.length === 0) {
|
||||||
|
var keys = Object.keys(events);
|
||||||
|
var key;
|
||||||
|
for (i = 0; i < keys.length; ++i) {
|
||||||
|
key = keys[i];
|
||||||
|
if (key === 'removeListener') continue;
|
||||||
|
this.removeAllListeners(key);
|
||||||
|
}
|
||||||
|
this.removeAllListeners('removeListener');
|
||||||
|
this._events = Object.create(null);
|
||||||
|
this._eventsCount = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners = events[type];
|
||||||
|
|
||||||
|
if (typeof listeners === 'function') {
|
||||||
|
this.removeListener(type, listeners);
|
||||||
|
} else if (listeners !== undefined) {
|
||||||
|
// LIFO order
|
||||||
|
for (i = listeners.length - 1; i >= 0; i--) {
|
||||||
|
this.removeListener(type, listeners[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
function _listeners(target, type, unwrap) {
|
||||||
|
var events = target._events;
|
||||||
|
|
||||||
|
if (events === undefined)
|
||||||
|
return [];
|
||||||
|
|
||||||
|
var evlistener = events[type];
|
||||||
|
if (evlistener === undefined)
|
||||||
|
return [];
|
||||||
|
|
||||||
|
if (typeof evlistener === 'function')
|
||||||
|
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
|
||||||
|
|
||||||
|
return unwrap ?
|
||||||
|
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventEmitter.prototype.listeners = function listeners(type) {
|
||||||
|
return _listeners(this, type, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
EventEmitter.prototype.rawListeners = function rawListeners(type) {
|
||||||
|
return _listeners(this, type, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
EventEmitter.listenerCount = function(emitter, type) {
|
||||||
|
if (typeof emitter.listenerCount === 'function') {
|
||||||
|
return emitter.listenerCount(type);
|
||||||
|
} else {
|
||||||
|
return listenerCount.call(emitter, type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
EventEmitter.prototype.listenerCount = listenerCount;
|
||||||
|
function listenerCount(type) {
|
||||||
|
var events = this._events;
|
||||||
|
|
||||||
|
if (events !== undefined) {
|
||||||
|
var evlistener = events[type];
|
||||||
|
|
||||||
|
if (typeof evlistener === 'function') {
|
||||||
|
return 1;
|
||||||
|
} else if (evlistener !== undefined) {
|
||||||
|
return evlistener.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventEmitter.prototype.eventNames = function eventNames() {
|
||||||
|
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
|
||||||
|
};
|
||||||
|
|
||||||
|
function arrayClone(arr, n) {
|
||||||
|
var copy = new Array(n);
|
||||||
|
for (var i = 0; i < n; ++i)
|
||||||
|
copy[i] = arr[i];
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
function spliceOne(list, index) {
|
||||||
|
for (; index + 1 < list.length; index++)
|
||||||
|
list[index] = list[index + 1];
|
||||||
|
list.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function unwrapListeners(arr) {
|
||||||
|
var ret = new Array(arr.length);
|
||||||
|
for (var i = 0; i < ret.length; ++i) {
|
||||||
|
ret[i] = arr[i].listener || arr[i];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function once(emitter, name) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
function errorListener(err) {
|
||||||
|
emitter.removeListener(name, resolver);
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolver() {
|
||||||
|
if (typeof emitter.removeListener === 'function') {
|
||||||
|
emitter.removeListener('error', errorListener);
|
||||||
|
}
|
||||||
|
resolve([].slice.call(arguments));
|
||||||
|
};
|
||||||
|
|
||||||
|
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
|
||||||
|
if (name !== 'error') {
|
||||||
|
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
|
||||||
|
if (typeof emitter.on === 'function') {
|
||||||
|
eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
|
||||||
|
if (typeof emitter.on === 'function') {
|
||||||
|
if (flags.once) {
|
||||||
|
emitter.once(name, listener);
|
||||||
|
} else {
|
||||||
|
emitter.on(name, listener);
|
||||||
|
}
|
||||||
|
} else if (typeof emitter.addEventListener === 'function') {
|
||||||
|
// EventTarget does not have `error` event semantics like Node
|
||||||
|
// EventEmitters, we do not listen for `error` events here.
|
||||||
|
emitter.addEventListener(name, function wrapListener(arg) {
|
||||||
|
// IE does not have builtin `{ once: true }` support so we
|
||||||
|
// have to do it manually.
|
||||||
|
if (flags.once) {
|
||||||
|
emitter.removeEventListener(name, wrapListener);
|
||||||
|
}
|
||||||
|
listener(arg);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue