mirror of
https://github.com/bytedream/stream-bypass.git
synced 2025-06-27 18:40:31 +02:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
67e03eafaa | |||
db0ccd9b56 | |||
fd3eda9c61 | |||
e522916585 | |||
b9514284da | |||
06beaa6ebe | |||
6a56c37dd2 | |||
018b381732 |
@ -1,9 +0,0 @@
|
|||||||
.DS_Store
|
|
||||||
node_modules
|
|
||||||
/dist
|
|
||||||
/release
|
|
||||||
.env
|
|
||||||
.env.*
|
|
||||||
!.env.example
|
|
||||||
|
|
||||||
package-lock.json
|
|
@ -1,34 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:svelte/recommended',
|
|
||||||
'prettier'
|
|
||||||
],
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
plugins: ['@typescript-eslint'],
|
|
||||||
parserOptions: {
|
|
||||||
sourceType: 'module',
|
|
||||||
ecmaVersion: 2020,
|
|
||||||
extraFileExtensions: ['.svelte']
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
es2017: true,
|
|
||||||
node: true
|
|
||||||
},
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.svelte'],
|
|
||||||
parser: 'svelte-eslint-parser',
|
|
||||||
parserOptions: {
|
|
||||||
parser: '@typescript-eslint/parser'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'no-undef': 'off'
|
|
||||||
}
|
|
||||||
};
|
|
82
README.md
82
README.md
@ -12,9 +12,6 @@ A multi-browser addon / extension for multiple streaming providers which redirec
|
|||||||
<a href="https://chromewebstore.google.com/detail/ddfpfjomnakfckhmilacnbokdaknamdb">
|
<a href="https://chromewebstore.google.com/detail/ddfpfjomnakfckhmilacnbokdaknamdb">
|
||||||
<img src="https://img.shields.io/chrome-web-store/users/ddfpfjomnakfckhmilacnbokdaknamdb?style=flat-square&label=Chrome%20Users" alt="Chrome Store">
|
<img src="https://img.shields.io/chrome-web-store/users/ddfpfjomnakfckhmilacnbokdaknamdb?style=flat-square&label=Chrome%20Users" alt="Chrome Store">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://addons.mozilla.org/de/firefox/addon/stream-bypass/">
|
|
||||||
<img src="https://img.shields.io/amo/stars/stream-bypass?label=Firefox%20Store%20Stars&style=flat-square" alt="Firefox Addon Stars">
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/bytedream/stream-bypass/releases/latest">
|
<a href="https://github.com/bytedream/stream-bypass/releases/latest">
|
||||||
<img src="https://img.shields.io/github/downloads/ByteDream/stream-bypass/total?label=GitHub%20Downloads&style=flat-square" alt="GitHub Downloads">
|
<img src="https://img.shields.io/github/downloads/ByteDream/stream-bypass/total?label=GitHub%20Downloads&style=flat-square" alt="GitHub Downloads">
|
||||||
</a>
|
</a>
|
||||||
@ -25,7 +22,9 @@ A multi-browser addon / extension for multiple streaming providers which redirec
|
|||||||
•
|
•
|
||||||
<a href="#-installation">Installation 📥</a>
|
<a href="#-installation">Installation 📥</a>
|
||||||
•
|
•
|
||||||
<a href="#-supported-sites">Supported Sites 📜</a>
|
<a href="#-features">Features ✨</a>
|
||||||
|
•
|
||||||
|
<a href="#-supported-websites">Supported Websites 📜</a>
|
||||||
•
|
•
|
||||||
<a href="#%EF%B8%8F-building">Building 🛠️</a>
|
<a href="#%EF%B8%8F-building">Building 🛠️</a>
|
||||||
•
|
•
|
||||||
@ -51,7 +50,7 @@ Additionally, this enables you to download the video by right-clicking it and ju
|
|||||||
|
|
||||||
The best way to install the extension are the official browser extension stores:
|
The best way to install the extension are the official browser extension stores:
|
||||||
|
|
||||||
- [Firefox Addon Store](https://addons.mozilla.org/de/firefox/addon/stream-bypass/)
|
- [Firefox Addon Store](https://addons.mozilla.org/de/firefox/addon/stream-bypass/) (Firefox for Android is supported too!)
|
||||||
- [Chrome Web Store](https://chromewebstore.google.com/detail/ddfpfjomnakfckhmilacnbokdaknamdb)
|
- [Chrome Web Store](https://chromewebstore.google.com/detail/ddfpfjomnakfckhmilacnbokdaknamdb)
|
||||||
|
|
||||||
### Manual installation
|
### Manual installation
|
||||||
@ -67,46 +66,47 @@ The best way to install the extension are the official browser extension stores:
|
|||||||
- Turn on the developer mode by checking the switch in the top right corner
|
- Turn on the developer mode by checking the switch in the top right corner
|
||||||
- Click `Load unpacked` and choose the unzipped directory
|
- Click `Load unpacked` and choose the unzipped directory
|
||||||
|
|
||||||
## 📜 Supported sites
|
## ✨ Features
|
||||||
|
|
||||||
| Site | Supported | Note |
|
| Feature | Firefox | Chrome | Firefox for Android |
|
||||||
| --------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------ |
|
| --------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | ------------------- |
|
||||||
| [dropload.io](https://dropload.io) | ✔ | |
|
| Replace site-speicifc video player with browser native video player | ✔ | ✔ | ✔ |
|
||||||
| [doodstream.com](doodstream.com) / [dood.pm](https://dood.pm) | ✔️ | |
|
| Support websites that are accessed via a redirect | ✔ | ❌ | ✔ |
|
||||||
| [filemoon.sx](https://filemoon.sx) | ✔ | |
|
| Open video in mpv (with [ff2mpv](https://github.com/ByteDream/stream-bypass/tree/master#ff2mpv-use-mpv-to-directly-play-streams)) | ✔ | ✔ | ❌ |
|
||||||
| [goodstream.uno](https://goodstream.uno) | ✔ | |
|
|
||||||
| [mcloud.to](https://mcloud.to/) | ❌ | Reverse engineering the site costs too much time ([#5](https://github.com/ByteDream/stream-bypass/issues/5)) |
|
- ✔️: Supported.
|
||||||
| [mixdrop.co](https://mixdrop.co) | ✔ ️ | |
|
- ❌: Not supported.
|
||||||
| [mp4upload.com](https://mp4upload.com) | ✔ | |
|
|
||||||
| [newgrounds.com](https://newgrounds.com) | ✔ | |
|
## 📜 Supported websites
|
||||||
| [streama2s.com](https://streama2z.com) | ✔ |
|
|
||||||
| [streamtape.com](https://streamtape.com) | ✔ | |
|
| Site | Firefox & Firefox for Android | Chrome & Chromium based |
|
||||||
| [streamzz.to](https://streamzz.to) / [streamz.ws](https://streamz.ws) | ✔ | |
|
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
||||||
| [supervideo.tv](https://supervideo.tv) | ✔ | |
|
| [dropload.io](https://dropload.io) | ✔ | ✔ |
|
||||||
| [upstream.to](https://upstream.to) | ✔ | |
|
| [doodstream.com](doodstream.com) / [dood.pm](https://dood.pm) | ✔️ | ⚠ (redirect probably required) |
|
||||||
| [videovard.sx](https://videovard.sx) | ❌ | Reverse engineering the site costs too much time |
|
| [filemoon.to](https://filemoon.to) | ✔ | ✔ |
|
||||||
| [vidmoly.me](https://vidmoly.me) | ✔ | |
|
| [goodstream.uno](https://goodstream.uno) | ✔ | ✔ |
|
||||||
| [vidoza.net](https://vidoza.net) | ✔ | |
|
| [mixdrop.co](https://mixdrop.co) | ✔ ️ | ✔ |
|
||||||
| [vidstream.pro](https://vidstream.pro) | ❌ | Reverse engineering the site costs too much time ([#5](https://github.com/ByteDream/stream-bypass/issues/5)) |
|
| [mp4upload.com](https://mp4upload.com) | ✔ | ✔ |
|
||||||
| [voe.sx](https://voe.sx) | ✔ | |
|
| [newgrounds.com](https://newgrounds.com) | ✔ | ✔ |
|
||||||
| [vupload.com](https://vupload.com) | ✔ | |
|
| [streama2z.com](https://streama2z.com) | ✔ | ❌ (redirect always required) |
|
||||||
| [kwik.cx](https://kwik.cx) | ✔ | |
|
| [streamtape.com](https://streamtape.com) | ⚠ (correct video url can't always be extract, retrying/reloading the page might fix it) | ⚠ (correct video url can't always be extract, retrying/reloading the page might fix it) |
|
||||||
|
| [streamzz.to](https://streamzz.to) / [streamz.ws](https://streamz.ws) | ✔ | ✔ |
|
||||||
|
| [supervideo.tv](https://supervideo.tv) | ✔ | ✔ |
|
||||||
|
| [upstream.to](https://upstream.to) | ✔ | ✔ |
|
||||||
|
| [vidmoly.to](https://vidmoly.me) | ✔ | ✔ |
|
||||||
|
| [vidoza.net](https://vidoza.net) | ⚠ (doesn't always work the first time, retrying/reloading the page one or two times fixes it) | ⚠ (doesn't always work the first time, retrying/reloading the page one or two times fixes it) |
|
||||||
|
| [voe.sx](https://voe.sx) | ✔ | ❌ (redirect always required) |
|
||||||
|
| [vupload.com](https://vupload.com) | ✔ | ✔ |
|
||||||
|
| [kwik.cx](https://kwik.cx) | ✔ | ✔ |
|
||||||
|
|
||||||
- ✔️: Everything ok.
|
- ✔️: Everything ok.
|
||||||
- ⚠: Included in the addon but will probably not work. See `Note` in this case, an explanation why will stand there in the most cases.
|
- ⚠: Works with limitations.
|
||||||
- ❌: Not included / supported by the addon. This can have various reasons. See `Note` for an explanation.
|
- ❌: Not supported.
|
||||||
|
|
||||||
|
_This table might not be 100% accurate, it isn't actively monitored if the addon works for every website!_
|
||||||
|
|
||||||
Some sites put much effort in obfuscating their code / how they receive the video stream so that it simply cost too much time for me to reverse engineer it and find out how to bypass the native video player of the site.
|
Some sites put much effort in obfuscating their code / how they receive the video stream so that it simply cost too much time for me to reverse engineer it and find out how to bypass the native video player of the site.
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Hall of dead sites</summary>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://evoload.io">evoload.io</a> - Down</li>
|
|
||||||
<li><a href="https://vidlox.me">vidlox.me</a> - Reachable but empty</li>
|
|
||||||
<li><a href="https://vivo.sx">vivo.sx</a> - Down</li>
|
|
||||||
</ul>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## 🛠️ Building
|
## 🛠️ Building
|
||||||
|
|
||||||
If you want to build the addon from source and not using the [installation](#installation) way, follow the instructions.
|
If you want to build the addon from source and not using the [installation](#installation) way, follow the instructions.
|
||||||
@ -161,11 +161,11 @@ Steps to get it set up:
|
|||||||
- Chrome/Chromium:
|
- Chrome/Chromium:
|
||||||
- Go To: Settings -> Extensions
|
- Go To: Settings -> Extensions
|
||||||
- Click on `Details` of the Stream Bypass extension and copy the ID
|
- Click on `Details` of the Stream Bypass extension and copy the ID
|
||||||
- Add `chrome-extension://your-id-here/` to `allowed_origins` ->
|
- Add `chrome-extension://ddfpfjomnakfckhmilacnbokdaknamdb/` to `allowed_origins` ->
|
||||||
```
|
```
|
||||||
"allowed_origins": [
|
"allowed_origins": [
|
||||||
"chrome-extension://ephjcajbkgplkjmelpglennepbpmdpjg/",
|
"chrome-extension://ephjcajbkgplkjmelpglennepbpmdpjg/",
|
||||||
"chrome-extension://your-id-her/"
|
"chrome-extension://ddfpfjomnakfckhmilacnbokdaknamdb/"
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
40
eslint.config.mjs
Normal file
40
eslint.config.mjs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import prettier from 'eslint-config-prettier';
|
||||||
|
import js from '@eslint/js';
|
||||||
|
import svelte from 'eslint-plugin-svelte';
|
||||||
|
import ts from 'typescript-eslint';
|
||||||
|
|
||||||
|
export default ts.config(
|
||||||
|
js.configs.recommended,
|
||||||
|
...ts.configs.recommended,
|
||||||
|
...svelte.configs['flat/recommended'],
|
||||||
|
prettier,
|
||||||
|
...svelte.configs['flat/prettier'],
|
||||||
|
{
|
||||||
|
files: ['**/*.svelte'],
|
||||||
|
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
parser: ts.parser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'no-undef': 'off'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
'.DS_Store',
|
||||||
|
'node_modules',
|
||||||
|
'dist',
|
||||||
|
'release',
|
||||||
|
'.idea',
|
||||||
|
'.env',
|
||||||
|
'.env.*',
|
||||||
|
'!.env.example',
|
||||||
|
'package-lock.json'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
);
|
5179
package-lock.json
generated
5179
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
37
package.json
37
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "stream-bypass",
|
"name": "stream-bypass",
|
||||||
"version": "3.1.0",
|
"version": "3.1.1",
|
||||||
"displayName": "Stream Bypass",
|
"displayName": "Stream Bypass",
|
||||||
"author": "bytedream",
|
"author": "bytedream",
|
||||||
"description": "Multi-browser addon for multiple streaming providers which redirects directly to the source video",
|
"description": "Multi-browser addon for multiple streaming providers which redirects directly to the source video",
|
||||||
@ -25,27 +25,26 @@
|
|||||||
"url": "https://github.com/bytedream/stream-bypass/issues"
|
"url": "https://github.com/bytedream/stream-bypass/issues"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@samrum/vite-plugin-web-extension": "^5.1.0",
|
"@samrum/vite-plugin-web-extension": "^5.1.1",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.5.3",
|
"@sveltejs/vite-plugin-svelte": "^5.0.2",
|
||||||
"@tsconfig/svelte": "^5.0.4",
|
"@tsconfig/svelte": "^5.0.4",
|
||||||
"@types/chrome": "^0.0.269",
|
"@types/chrome": "^0.0.287",
|
||||||
"@types/firefox-webext-browser": "^120.0.4",
|
"@types/firefox-webext-browser": "^120.0.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.17.0",
|
"eslint": "^9.17.0",
|
||||||
"@typescript-eslint/parser": "^7.17.0",
|
|
||||||
"eslint": "^8.57.0",
|
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-svelte": "^2.43.0",
|
"eslint-plugin-svelte": "^2.46.1",
|
||||||
"hls.js": "^1.5.13",
|
"hls.js": "^1.5.17",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.4.2",
|
||||||
"prettier-plugin-svelte": "^3.2.6",
|
"prettier-plugin-svelte": "^3.3.2",
|
||||||
"sass": "^1.77.8",
|
"sass": "^1.83.0",
|
||||||
"svelte": "^4.2.18",
|
"svelte": "^5.14.0",
|
||||||
"svelte-check": "^3.8.4",
|
"svelte-check": "^4.1.1",
|
||||||
"svelte-preprocess": "^6.0.2",
|
"svelte-preprocess": "^6.0.3",
|
||||||
"tslib": "^2.6.3",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.5.4",
|
"typescript": "^5.7.2",
|
||||||
"vite": "^4.5.3",
|
"typescript-eslint": "^8.18.0",
|
||||||
"web-ext": "^8.2.0"
|
"vite": "^6.0.3",
|
||||||
|
"web-ext": "^8.3.0"
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import './shared';
|
import './shared';
|
||||||
|
|
||||||
import type { Match } from '~/lib/match';
|
import type { Match } from '~/lib/match';
|
||||||
import { Redirect, storageDelete, storageGet } from '~/lib/settings';
|
import { Redirect, UrlReferer } from '~/lib/settings';
|
||||||
import { getMatch } from '~/lib/match';
|
import { getMatch } from '~/lib/match';
|
||||||
|
|
||||||
chrome.webRequest.onBeforeSendHeaders.addListener(
|
chrome.webRequest.onBeforeSendHeaders.addListener(
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
async (details) => {
|
async (details) => {
|
||||||
const referer: { domain: string } | undefined = await storageGet('referer');
|
const referer = await UrlReferer.get(new URL(details.url).hostname);
|
||||||
if (referer === undefined) return;
|
if (!referer) return;
|
||||||
|
|
||||||
|
await UrlReferer.delete(new URL(details.url).hostname);
|
||||||
|
|
||||||
details.requestHeaders!.push({
|
details.requestHeaders!.push({
|
||||||
name: 'Referer',
|
name: 'Referer',
|
||||||
value: `https://${referer.domain}/`
|
value: `https://${referer}/`
|
||||||
});
|
});
|
||||||
|
|
||||||
await storageDelete('referer');
|
|
||||||
|
|
||||||
return { requestHeaders: details.requestHeaders };
|
return { requestHeaders: details.requestHeaders };
|
||||||
},
|
},
|
||||||
{ urls: ['<all_urls>'], types: ['xmlhttprequest'] },
|
{ urls: ['<all_urls>'], types: ['xmlhttprequest'] },
|
||||||
|
@ -20,10 +20,16 @@ async function main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const re = document.body.innerHTML.match(match.regex);
|
let re = null;
|
||||||
|
for (const regex of match.regex) {
|
||||||
|
if ((re = document.body.innerHTML.match(regex)) !== null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (re === null) {
|
if (re === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redirect) {
|
if (redirect) {
|
||||||
await Redirect.delete();
|
await Redirect.delete();
|
||||||
}
|
}
|
||||||
@ -31,7 +37,7 @@ async function main() {
|
|||||||
let url: string | null;
|
let url: string | null;
|
||||||
try {
|
try {
|
||||||
url = await match.match(re);
|
url = await match.match(re);
|
||||||
} catch (e) {
|
} catch {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +64,8 @@ async function main() {
|
|||||||
// clear completed document
|
// clear completed document
|
||||||
document.documentElement.innerHTML = '';
|
document.documentElement.innerHTML = '';
|
||||||
|
|
||||||
|
document.body.style.backgroundColor = '#131313';
|
||||||
|
|
||||||
// video player
|
// video player
|
||||||
const player = document.createElement('video');
|
const player = document.createElement('video');
|
||||||
player.style.width = '100%';
|
player.style.width = '100%';
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
import { play } from '~/entries/player/player';
|
import { play } from '~/entries/player/player';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
let errorMessage: string | null = null;
|
let errorMessage: string | null = $state(null);
|
||||||
|
|
||||||
let videoElem: HTMLVideoElement;
|
let videoElem: HTMLVideoElement;
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
@ -10,13 +11,13 @@
|
|||||||
await play(videoElem);
|
await play(videoElem);
|
||||||
videoElem.controls = true;
|
videoElem.controls = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorMessage = e;
|
errorMessage = e as string;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-media-has-caption -->
|
<!-- svelte-ignore a11y_media_has_caption -->
|
||||||
<video id="video" bind:this={videoElem} />
|
<video id="video" bind:this={videoElem}></video>
|
||||||
{#if errorMessage}
|
{#if errorMessage}
|
||||||
<div id="message-container">
|
<div id="message-container">
|
||||||
<p>
|
<p>
|
||||||
|
@ -7,8 +7,9 @@
|
|||||||
<body>
|
<body>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import Player from '~/entries/player/Player.svelte';
|
import Player from '~/entries/player/Player.svelte';
|
||||||
|
import { mount } from 'svelte';
|
||||||
|
|
||||||
new Player({
|
mount(Player, {
|
||||||
target: document.body
|
target: document.body
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
import { matches } from '~/lib/match';
|
import { matches } from '~/lib/match';
|
||||||
import Hls from 'hls.js';
|
import Hls from 'hls.js';
|
||||||
import { storageSet } from '~/lib/settings';
|
import { UrlReferer } from '~/lib/settings';
|
||||||
|
|
||||||
|
async function playNative(url: string, domain: string, videoElem: HTMLVideoElement) {
|
||||||
|
await UrlReferer.set(new URL(url).hostname, domain);
|
||||||
|
|
||||||
async function playNative(url: string, videoElem: HTMLVideoElement) {
|
|
||||||
videoElem.src = url;
|
videoElem.src = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function playHls(url: string, videoElem: HTMLVideoElement) {
|
async function playHls(url: string, domain: string, videoElem: HTMLVideoElement) {
|
||||||
if (videoElem.canPlayType('application/vnd.apple.mpegurl')) {
|
if (videoElem.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
videoElem.src = url;
|
videoElem.src = url;
|
||||||
} else if (Hls.isSupported()) {
|
} else if (Hls.isSupported()) {
|
||||||
const hls = new Hls({
|
const hls = new Hls({
|
||||||
enableWorker: false
|
enableWorker: false,
|
||||||
|
xhrSetup: async (xhr: XMLHttpRequest, url: string) => {
|
||||||
|
await UrlReferer.set(new URL(url).hostname, domain);
|
||||||
|
xhr.open('GET', url);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
hls.loadSource(url);
|
hls.loadSource(url);
|
||||||
hls.attachMedia(videoElem);
|
hls.attachMedia(videoElem);
|
||||||
@ -32,11 +38,9 @@ export async function play(videoElem: HTMLVideoElement) {
|
|||||||
}
|
}
|
||||||
document.title = `Stream Bypass (${domain})`;
|
document.title = `Stream Bypass (${domain})`;
|
||||||
|
|
||||||
await storageSet('referer', { domain: domain });
|
|
||||||
|
|
||||||
if (new URL(url).pathname.endsWith('.m3u8')) {
|
if (new URL(url).pathname.endsWith('.m3u8')) {
|
||||||
await playHls(url, videoElem);
|
await playHls(url, domain, videoElem);
|
||||||
} else {
|
} else {
|
||||||
await playNative(url, videoElem);
|
await playNative(url, domain, videoElem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
<Toggle
|
<Toggle
|
||||||
bind:checked={hostersEnabled}
|
bind:checked={hostersEnabled}
|
||||||
id="hosters-enabled"
|
id="hosters-enabled"
|
||||||
on:change={() => Hosters.setAll(hostersEnabled)}
|
onChange={() => Hosters.setAll(hostersEnabled)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
@ -52,7 +52,7 @@
|
|||||||
bind:checked={hoster.active}
|
bind:checked={hoster.active}
|
||||||
disabled={!hostersEnabled}
|
disabled={!hostersEnabled}
|
||||||
id="hoster-{i}"
|
id="hoster-{i}"
|
||||||
on:change={async () => {
|
onChange={async () => {
|
||||||
if (hoster.active) {
|
if (hoster.active) {
|
||||||
await Hosters.enable(hoster);
|
await Hosters.enable(hoster);
|
||||||
} else {
|
} else {
|
||||||
@ -73,7 +73,7 @@
|
|||||||
<Toggle
|
<Toggle
|
||||||
bind:checked={ff2mpvEnabled}
|
bind:checked={ff2mpvEnabled}
|
||||||
id="ff2mpv"
|
id="ff2mpv"
|
||||||
on:change={async () => {
|
onChange={async () => {
|
||||||
ff2mpvEnabled = !ff2mpvEnabled;
|
ff2mpvEnabled = !ff2mpvEnabled;
|
||||||
if (await browser.permissions.request({ permissions: ['nativeMessaging'] })) {
|
if (await browser.permissions.request({ permissions: ['nativeMessaging'] })) {
|
||||||
await Other.setFf2mpv(ff2mpvEnabled);
|
await Other.setFf2mpv(ff2mpvEnabled);
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
<body style="overflow-y: scroll">
|
<body style="overflow-y: scroll">
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import Popup from '~/entries/popup/Popup.svelte';
|
import Popup from '~/entries/popup/Popup.svelte';
|
||||||
|
import { mount } from 'svelte';
|
||||||
|
|
||||||
new Popup({
|
mount(Popup, {
|
||||||
target: document.body
|
target: document.body
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
import App from './Popup.svelte';
|
|
||||||
|
|
||||||
new App({
|
|
||||||
target: document.getElementById('app') as Element
|
|
||||||
});
|
|
@ -1,18 +1,21 @@
|
|||||||
<!-- https://flowbite.com/docs/forms/toggle/ -->
|
<!-- https://flowbite.com/docs/forms/toggle/ -->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
export let checked = false;
|
type Props = {
|
||||||
export let disabled = false;
|
checked?: boolean;
|
||||||
export let id: string | null = null;
|
disabled?: boolean;
|
||||||
|
id?: string | null;
|
||||||
const dispatch = createEventDispatcher();
|
onChange?: () => void;
|
||||||
|
children?: Snippet;
|
||||||
|
};
|
||||||
|
let { checked = $bindable(), disabled, id = null, onChange, children }: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="toggle">
|
<label class="toggle">
|
||||||
<slot />
|
{@render children?.()}
|
||||||
<input type="checkbox" {id} bind:checked {disabled} on:change={(e) => dispatch('change', e)} />
|
<input type="checkbox" {id} bind:checked {disabled} onchange={onChange} />
|
||||||
<span />
|
<span></span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<style lang="scss" global>
|
<style lang="scss" global>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { unpack } from './utils';
|
import { unpack } from './utils';
|
||||||
import { Hosters, Redirect } from './settings';
|
import { Hosters, Redirect, TmpHost } from './settings';
|
||||||
|
|
||||||
export interface Match {
|
export interface Match {
|
||||||
name: string;
|
name: string;
|
||||||
id: string;
|
id: string;
|
||||||
domains: string[];
|
domains: string[];
|
||||||
replace?: boolean;
|
replace?: boolean;
|
||||||
regex: RegExp;
|
regex: RegExp[];
|
||||||
notice?: string;
|
notice?: string;
|
||||||
|
|
||||||
match(match: RegExpMatchArray): Promise<string | null>;
|
match(match: RegExpMatchArray): Promise<string | null>;
|
||||||
@ -35,7 +35,7 @@ export const Doodstream: Match = {
|
|||||||
'd000d.com'
|
'd000d.com'
|
||||||
],
|
],
|
||||||
replace: true,
|
replace: true,
|
||||||
regex: /(\/pass_md5\/.*?)'.*(\?token=.*?expiry=)/s,
|
regex: [/(\/pass_md5\/.*?)'.*(\?token=.*?expiry=)/s],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
const response = await fetch(`https://${window.location.host}${match[1]}`, {
|
const response = await fetch(`https://${window.location.host}${match[1]}`, {
|
||||||
@ -54,7 +54,7 @@ export const DropLoad: Match = {
|
|||||||
name: 'Dropload',
|
name: 'Dropload',
|
||||||
id: 'dropload',
|
id: 'dropload',
|
||||||
domains: ['dropload.ui'],
|
domains: ['dropload.ui'],
|
||||||
regex: /eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms,
|
regex: [/eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
const unpacked = await unpack(match[0]);
|
const unpacked = await unpack(match[0]);
|
||||||
@ -65,12 +65,20 @@ export const DropLoad: Match = {
|
|||||||
export const Filemoon: Match = {
|
export const Filemoon: Match = {
|
||||||
name: 'Filemoon',
|
name: 'Filemoon',
|
||||||
id: 'filemoon',
|
id: 'filemoon',
|
||||||
domains: ['filemoon.sx', 'filemoon.in'],
|
domains: ['filemoon.sx', 'filemoon.to', 'filemoon.in'],
|
||||||
regex: /eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms,
|
regex: [/(?<=<iframe\s*src=")\S*(?=")/s, /eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms],
|
||||||
|
replace: true,
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
|
if (window.location.host.startsWith('filemoon')) {
|
||||||
|
await TmpHost.set(new URL(match[0]).host, Filemoon);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await TmpHost.delete();
|
||||||
|
|
||||||
const unpacked = await unpack(match[0]);
|
const unpacked = await unpack(match[0]);
|
||||||
return unpacked.match(/(?<=file:").*(?=")/)![0];
|
return unpacked.match(/(?<=file:")\S*(?=")/)![0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,7 +86,7 @@ export const GoodStream: Match = {
|
|||||||
name: 'Goodstream',
|
name: 'Goodstream',
|
||||||
id: 'goodstream',
|
id: 'goodstream',
|
||||||
domains: ['goodstream.uno'],
|
domains: ['goodstream.uno'],
|
||||||
regex: /(?<=file:\s+").*(?=")/g,
|
regex: [/(?<=file:\s+").*(?=")/g],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
return match[0];
|
return match[0];
|
||||||
@ -89,7 +97,7 @@ export const Kwik: Match = {
|
|||||||
name: 'Kwik',
|
name: 'Kwik',
|
||||||
id: 'kwik',
|
id: 'kwik',
|
||||||
domains: ['kwik.cx'],
|
domains: ['kwik.cx'],
|
||||||
regex: /eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms,
|
regex: [/eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
const unpacked = await unpack(match[0]);
|
const unpacked = await unpack(match[0]);
|
||||||
@ -101,7 +109,7 @@ export const Mixdrop: Match = {
|
|||||||
name: 'Mixdrop',
|
name: 'Mixdrop',
|
||||||
id: 'mixdrop',
|
id: 'mixdrop',
|
||||||
domains: ['mixdrop.co', 'mixdrop.to', 'mixdrop.ch', 'mixdrop.bz', 'mixdrop.gl'],
|
domains: ['mixdrop.co', 'mixdrop.to', 'mixdrop.ch', 'mixdrop.bz', 'mixdrop.gl'],
|
||||||
regex: /eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms,
|
regex: [/eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
const unpacked = await unpack(match[0]);
|
const unpacked = await unpack(match[0]);
|
||||||
@ -115,7 +123,7 @@ export const Mp4Upload: Match = {
|
|||||||
id: 'mp4upload',
|
id: 'mp4upload',
|
||||||
domains: ['mp4upload.com'],
|
domains: ['mp4upload.com'],
|
||||||
replace: true,
|
replace: true,
|
||||||
regex: /eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms,
|
regex: [/eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
const unpacked = await unpack(match[0]);
|
const unpacked = await unpack(match[0]);
|
||||||
@ -127,7 +135,7 @@ export const Newgrounds: Match = {
|
|||||||
name: 'Newgrounds',
|
name: 'Newgrounds',
|
||||||
id: 'newgrounds',
|
id: 'newgrounds',
|
||||||
domains: ['newgrounds.com'],
|
domains: ['newgrounds.com'],
|
||||||
regex: /.*/gm,
|
regex: [/.*/gm],
|
||||||
|
|
||||||
match: async () => {
|
match: async () => {
|
||||||
const id = window.location.pathname.split('/').slice(-1)[0];
|
const id = window.location.pathname.split('/').slice(-1)[0];
|
||||||
@ -145,7 +153,7 @@ export const StreamA2z: Match = {
|
|||||||
name: 'Stream2Az',
|
name: 'Stream2Az',
|
||||||
id: 'stream2az',
|
id: 'stream2az',
|
||||||
domains: ['streama2z.com', 'streama2z.xyz'],
|
domains: ['streama2z.com', 'streama2z.xyz'],
|
||||||
regex: /https?:\/\/\S*m3u8.+(?=['"])/gm,
|
regex: [/https?:\/\/\S*m3u8.+(?=['"])/gm],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
if (StreamA2z.domains.indexOf(window.location.hostname) !== -1) {
|
if (StreamA2z.domains.indexOf(window.location.hostname) !== -1) {
|
||||||
@ -160,7 +168,7 @@ export const Streamtape: Match = {
|
|||||||
name: 'Streamtape',
|
name: 'Streamtape',
|
||||||
id: 'streamtape',
|
id: 'streamtape',
|
||||||
domains: ['streamtape.com', 'streamtape.net', 'shavetape.cash'],
|
domains: ['streamtape.com', 'streamtape.net', 'shavetape.cash'],
|
||||||
regex: /id=.*(?=')/gm,
|
regex: [/id=.*(?=')/gm],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
@ -179,7 +187,7 @@ export const Streamzz: Match = {
|
|||||||
name: 'Streamzz',
|
name: 'Streamzz',
|
||||||
id: 'streamzz',
|
id: 'streamzz',
|
||||||
domains: ['streamzz.to', 'streamz.ws'],
|
domains: ['streamzz.to', 'streamz.ws'],
|
||||||
regex: /(?<=\|)\w{2,}/gm,
|
regex: [/(?<=\|)\w{2,}/gm],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
return `https://get.${location.hostname.split('.')[0]}.tw/getlink-${
|
return `https://get.${location.hostname.split('.')[0]}.tw/getlink-${
|
||||||
@ -192,7 +200,7 @@ export const SuperVideo: Match = {
|
|||||||
name: 'Supervideo',
|
name: 'Supervideo',
|
||||||
id: 'supervideo',
|
id: 'supervideo',
|
||||||
domains: ['supervideo.tv'],
|
domains: ['supervideo.tv'],
|
||||||
regex: /eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms,
|
regex: [/eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
const unpacked = await unpack(match[0]);
|
const unpacked = await unpack(match[0]);
|
||||||
@ -204,7 +212,7 @@ export const Upstream: Match = {
|
|||||||
name: 'Upstream',
|
name: 'Upstream',
|
||||||
id: 'upstream',
|
id: 'upstream',
|
||||||
domains: ['upstream.to'],
|
domains: ['upstream.to'],
|
||||||
regex: /eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms,
|
regex: [/eval\(function\(p,a,c,k,e,d\).*?(?=<\/script>)/gms],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
const unpacked = await unpack(match[0]);
|
const unpacked = await unpack(match[0]);
|
||||||
@ -216,10 +224,10 @@ export const Vidmoly: Match = {
|
|||||||
name: 'Vidmoly',
|
name: 'Vidmoly',
|
||||||
id: 'vidmoly',
|
id: 'vidmoly',
|
||||||
domains: ['vidmoly.me', 'vidmoly.to'],
|
domains: ['vidmoly.me', 'vidmoly.to'],
|
||||||
regex: /(?<=file:").+\.m3u8/gm,
|
regex: [/(?<=file:").+\.m3u8/gm],
|
||||||
|
replace: true,
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
alert('a');
|
|
||||||
return match[0];
|
return match[0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -227,8 +235,8 @@ export const Vidmoly: Match = {
|
|||||||
export const Vidoza: Match = {
|
export const Vidoza: Match = {
|
||||||
name: 'Vidoza',
|
name: 'Vidoza',
|
||||||
id: 'vidoza',
|
id: 'vidoza',
|
||||||
domains: ['vidoza.net'],
|
domains: ['vidoza.net', 'videzz.net'],
|
||||||
regex: /(?<=src:\s?").+?(?=")/gm,
|
regex: [/(?<=src:\s?").+?(?=")/gm],
|
||||||
replace: true,
|
replace: true,
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
@ -240,10 +248,10 @@ export const Voe: Match = {
|
|||||||
name: 'Voe',
|
name: 'Voe',
|
||||||
id: 'voe',
|
id: 'voe',
|
||||||
domains: ['voe.sx'],
|
domains: ['voe.sx'],
|
||||||
regex: /https?:\/\/\S*m3u8.+(?=['"])/gm,
|
regex: [/(?<='hls':\s*')\S*(?=')/gm],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
return match[0];
|
return atob(match[0]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -251,7 +259,7 @@ export const Vupload: Match = {
|
|||||||
name: 'Vupload',
|
name: 'Vupload',
|
||||||
id: 'vupload',
|
id: 'vupload',
|
||||||
domains: ['vupload.com'],
|
domains: ['vupload.com'],
|
||||||
regex: /(?<=src:\s?").+?(?=")/gm,
|
regex: [/(?<=src:\s?").+?(?=")/gm],
|
||||||
|
|
||||||
match: async (match: RegExpMatchArray) => {
|
match: async (match: RegExpMatchArray) => {
|
||||||
return match[0];
|
return match[0];
|
||||||
@ -292,5 +300,10 @@ export async function getMatch(domain: string): Promise<Match | null> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tmpHost = await TmpHost.get();
|
||||||
|
if (tmpHost && tmpHost[0] === domain) {
|
||||||
|
return tmpHost[1];
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,34 @@ export const Redirect = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const TmpHost = {
|
||||||
|
get: async (): Promise<[string, Match] | null> => {
|
||||||
|
const tmphost = await storageGet<[string, number]>('tmphost');
|
||||||
|
if (tmphost === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return [tmphost[0], matches[tmphost[1]]];
|
||||||
|
},
|
||||||
|
set: async (domain: string, match: Match) => {
|
||||||
|
await storageSet('tmphost', [domain, match.id]);
|
||||||
|
},
|
||||||
|
delete: async () => {
|
||||||
|
await storageDelete('tmphost');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UrlReferer = {
|
||||||
|
get: async (url: string): Promise<string | null> => {
|
||||||
|
return (await storageGet(`urlReferer.${url}`)) || null;
|
||||||
|
},
|
||||||
|
set: async (url: string, referer: string) => {
|
||||||
|
await storageSet(`urlReferer.${url}`, referer);
|
||||||
|
},
|
||||||
|
delete: async (url: string) => {
|
||||||
|
await storageDelete(`urlReferer.${url}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const Other = {
|
export const Other = {
|
||||||
getFf2mpv: async () => {
|
getFf2mpv: async () => {
|
||||||
return await storageGet('other.ff2mpv', false);
|
return await storageGet('other.ff2mpv', false);
|
||||||
@ -51,7 +79,7 @@ export const Other = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function storageGet<T>(key: string, defaultValue?: T): Promise<T | undefined> {
|
async function storageGet<T>(key: string, defaultValue?: T): Promise<T | undefined> {
|
||||||
let resolve: (value: T | undefined) => void;
|
let resolve: (value: T | undefined) => void;
|
||||||
const promise = new Promise<T | undefined>((r) => (resolve = r));
|
const promise = new Promise<T | undefined>((r) => (resolve = r));
|
||||||
|
|
||||||
@ -63,7 +91,7 @@ export async function storageGet<T>(key: string, defaultValue?: T): Promise<T |
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function storageSet<T>(key: string, value: T) {
|
async function storageSet<T>(key: string, value: T) {
|
||||||
let resolve: () => void;
|
let resolve: () => void;
|
||||||
const promise = new Promise<void>((r) => (resolve = r));
|
const promise = new Promise<void>((r) => (resolve = r));
|
||||||
|
|
||||||
@ -75,7 +103,7 @@ export async function storageSet<T>(key: string, value: T) {
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function storageDelete(key: string) {
|
async function storageDelete(key: string) {
|
||||||
let resolve: () => void;
|
let resolve: () => void;
|
||||||
const promise = new Promise<void>((r) => (resolve = r));
|
const promise = new Promise<void>((r) => (resolve = r));
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ export async function unpack(packed: string): Promise<string> {
|
|||||||
${packed}
|
${packed}
|
||||||
};
|
};
|
||||||
return packed;
|
return packed;
|
||||||
}'
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const res = (await runInPageContext(toExecute)) as string;
|
const res = (await runInPageContext(toExecute)) as string;
|
||||||
@ -32,8 +32,9 @@ export async function unpack(packed: string): Promise<string> {
|
|||||||
async function runInPageContext<T>(toExecute: string): Promise<T | null> {
|
async function runInPageContext<T>(toExecute: string): Promise<T | null> {
|
||||||
// test that we are running with the allow-scripts permission
|
// test that we are running with the allow-scripts permission
|
||||||
try {
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||||
window.sessionStorage;
|
window.sessionStorage;
|
||||||
} catch (ignore) {
|
} catch {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,18 +49,17 @@ async function runInPageContext<T>(toExecute: string): Promise<T | null> {
|
|||||||
scriptElm.textContent = `
|
scriptElm.textContent = `
|
||||||
(
|
(
|
||||||
async function () {
|
async function () {
|
||||||
|
const response = {
|
||||||
|
id: '${resultMessageId}'
|
||||||
|
};
|
||||||
|
|
||||||
const response = {
|
try {
|
||||||
id: ${resultMessageId}
|
response.result = JSON.stringify(await (${toExecute})() ); // run script
|
||||||
};
|
} catch(err) {
|
||||||
|
response.error = JSON.stringify(err);
|
||||||
try {
|
}
|
||||||
response.result = JSON.stringify(await (${toExecute})() ); // run script
|
|
||||||
} catch(err) {
|
|
||||||
response.error = JSON.stringify(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.postMessage(response, '*');
|
window.postMessage(response, '*');
|
||||||
}
|
}
|
||||||
)();
|
)();
|
||||||
`;
|
`;
|
||||||
|
Reference in New Issue
Block a user