Browse Source

Partial IPC system rewrite

pull/46/head
coomdev 2 years ago
parent
commit
f038fd42bd
  1. 2
      README.md
  2. 30
      chrome/dist/background.js
  3. 193
      chrome/dist/main.js
  4. 2
      chrome/manifest.json
  5. 224
      dist/main.js
  6. 30
      firefox/dist/background.js
  7. 197
      firefox/dist/main.js
  8. 2
      firefox/manifest.json
  9. 2
      firefox_update.json
  10. 2
      main.meta.js
  11. 226
      main.user.js
  12. BIN
      pngextraembedder-0.300.xpi
  13. 24
      src/background.ts
  14. 65
      src/f5stego.ts
  15. 165
      src/main.ts
  16. 32
      src/platform.ts
  17. 13
      src/processor.worker.ts

2
README.md

@ -25,7 +25,7 @@ Please report any issue you have with those (only for mainstream browsers)
Also, use this if you plan to use b4k's archive. Also, use this if you plan to use b4k's archive.
- [Install 4chanX (recommended)](https://www.4chan-x.net/builds/4chan-X.user.js) - [Install 4chanX (recommended)](https://www.4chan-x.net/builds/4chan-X.user.js)
- Install the correct WebExtension for your Browser ([Firefox](https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.299.xpi) or Chrome-based (Down for "maintainance")) - Install the correct WebExtension for your Browser ([Firefox](https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.300.xpi) or Chrome-based (Down for "maintainance"))
For FF users, the extension is signed so you can just drag and drop it on your about:addons tab. For FF users, the extension is signed so you can just drag and drop it on your about:addons tab.

30
chrome/dist/background.js

@ -1879,10 +1879,7 @@
var port1; var port1;
console.log("chrome_api", true); console.log("chrome_api", true);
if (false) { if (false) {
const nmc = new MessageChannel(); iframe = document.createElement("iframe");
port1 = nmc.port1;
port2 = nmc.port2;
const iframe = document.createElement("iframe");
iframe.style.display = "none"; iframe.style.display = "none";
iframe.name = location.origin; iframe.name = location.origin;
const iframeloaded = new Promise((_) => { const iframeloaded = new Promise((_) => {
@ -1891,13 +1888,12 @@
iframe.src = `${chrome.runtime.getURL("")}options.html`; iframe.src = `${chrome.runtime.getURL("")}options.html`;
document.documentElement.appendChild(iframe); document.documentElement.appendChild(iframe);
iframeloaded.then(() => { iframeloaded.then(() => {
iframe.contentWindow?.postMessage("", "*", [port2]); port1 = genPort();
});
port1.onmessage = (ev) => { port1.onmessage = (ev) => {
lqueue[ev.data.id](ev.data); lqueue[ev.data.id](ev.data);
}; };
});
} }
console.log("chrome_api");
if (false) { if (false) {
port1 = { port1 = {
onmessage(ev) { onmessage(ev) {
@ -1913,11 +1909,14 @@
}; };
} }
var gid = 0; var gid = 0;
var sendCmd = (cmd, tr) => { var sendCmd = (cmd, tr, overwrite = false, todelete = false) => {
const prom = new Promise((_) => { const prom = new Promise((_) => {
const id = gid++; const id = gid++;
if (overwrite)
cmd.id = id;
lqueue[id] = (e) => { lqueue[id] = (e) => {
_(e); _(e);
if (todelete)
delete lqueue[id]; delete lqueue[id];
}; };
port1.postMessage({ id, ...cmd }, tr || []); port1.postMessage({ id, ...cmd }, tr || []);
@ -2019,8 +2018,7 @@
} }
} }
} }
var pendingFetches = /* @__PURE__ */ new Map(); var bgCorsFetch = async (c, pendingFetches, id, input, init) => {
var bgCorsFetch = async (c, id, input, init) => {
if (input.startsWith("//")) if (input.startsWith("//"))
input = "https:" + input; input = "https:" + input;
if (init?.body && true) { if (init?.body && true) {
@ -2106,12 +2104,15 @@
var waitConnect = (cb) => { var waitConnect = (cb) => {
window.addEventListener("message", (msg) => { window.addEventListener("message", (msg) => {
cb(msg.ports[0]); cb(msg.ports[0]);
}); }, { once: true });
}; };
var onMessage = (c, cb) => c.onmessage = (e) => { var onMessage = (c, cb) => c.onmessage = (e) => {
cb(e.data); cb(e.data);
}; };
waitConnect((c) => { (async () => {
while (true) {
const c = await new Promise(waitConnect);
const pendingFetches = /* @__PURE__ */ new Map();
onMessage(c, async (obj2) => { onMessage(c, async (obj2) => {
const { id, name, args, sid, fid, url } = obj2; const { id, name, args, sid, fid, url } = obj2;
if (name == "keepAlive") { if (name == "keepAlive") {
@ -2122,7 +2123,7 @@
return; return;
} }
if (name == "corsFetch") { if (name == "corsFetch") {
bgCorsFetch(c, id, ...args); bgCorsFetch(c, pendingFetches, id, ...args);
return; return;
} }
if (name == "revoke") { if (name == "revoke") {
@ -2149,7 +2150,8 @@
res res
}); });
}); });
}); }
})();
})(); })();
/*! /*!
* The buffer module from node.js, for the browser. * The buffer module from node.js, for the browser.

193
chrome/dist/main.js

File diff suppressed because one or more lines are too long

2
chrome/manifest.json

@ -2,7 +2,7 @@
"manifest_version": 3, "manifest_version": 3,
"name": "PngExtraEmbedder", "name": "PngExtraEmbedder",
"description": "Discover embedded files on 4chan and archives!", "description": "Discover embedded files on 4chan and archives!",
"version": "0.298", "version": "0.300",
"icons": { "icons": {
"64": "1449696017588.png" "64": "1449696017588.png"
}, },

224
dist/main.js

File diff suppressed because one or more lines are too long

30
firefox/dist/background.js

@ -1879,10 +1879,7 @@
var port1; var port1;
console.log("ff_api", true); console.log("ff_api", true);
if (false) { if (false) {
const nmc = new MessageChannel(); iframe = document.createElement("iframe");
port1 = nmc.port1;
port2 = nmc.port2;
const iframe = document.createElement("iframe");
iframe.style.display = "none"; iframe.style.display = "none";
iframe.name = location.origin; iframe.name = location.origin;
const iframeloaded = new Promise((_) => { const iframeloaded = new Promise((_) => {
@ -1891,13 +1888,12 @@
iframe.src = `${chrome.runtime.getURL("")}options.html`; iframe.src = `${chrome.runtime.getURL("")}options.html`;
document.documentElement.appendChild(iframe); document.documentElement.appendChild(iframe);
iframeloaded.then(() => { iframeloaded.then(() => {
iframe.contentWindow?.postMessage("", "*", [port2]); port1 = genPort();
});
port1.onmessage = (ev) => { port1.onmessage = (ev) => {
lqueue[ev.data.id](ev.data); lqueue[ev.data.id](ev.data);
}; };
});
} }
console.log("ff_api");
if (false) { if (false) {
port1 = { port1 = {
onmessage(ev) { onmessage(ev) {
@ -1913,11 +1909,14 @@
}; };
} }
var gid = 0; var gid = 0;
var sendCmd = (cmd, tr) => { var sendCmd = (cmd, tr, overwrite = false, todelete = false) => {
const prom = new Promise((_) => { const prom = new Promise((_) => {
const id = gid++; const id = gid++;
if (overwrite)
cmd.id = id;
lqueue[id] = (e) => { lqueue[id] = (e) => {
_(e); _(e);
if (todelete)
delete lqueue[id]; delete lqueue[id];
}; };
port1.postMessage({ id, ...cmd }, tr || []); port1.postMessage({ id, ...cmd }, tr || []);
@ -1984,8 +1983,7 @@
}; };
} }
}, filts, ["blocking", "responseHeaders", ...false ? ["extraHeaders"] : []]); }, filts, ["blocking", "responseHeaders", ...false ? ["extraHeaders"] : []]);
var pendingFetches = /* @__PURE__ */ new Map(); var bgCorsFetch = async (c, pendingFetches, id, input, init) => {
var bgCorsFetch = async (c, id, input, init) => {
if (input.startsWith("//")) if (input.startsWith("//"))
input = "https:" + input; input = "https:" + input;
if (init?.body && false) { if (init?.body && false) {
@ -2071,12 +2069,15 @@
var waitConnect = (cb) => { var waitConnect = (cb) => {
window.addEventListener("message", (msg) => { window.addEventListener("message", (msg) => {
cb(msg.ports[0]); cb(msg.ports[0]);
}); }, { once: true });
}; };
var onMessage = (c, cb) => c.onmessage = (e) => { var onMessage = (c, cb) => c.onmessage = (e) => {
cb(e.data); cb(e.data);
}; };
waitConnect((c) => { (async () => {
while (true) {
const c = await new Promise(waitConnect);
const pendingFetches = /* @__PURE__ */ new Map();
onMessage(c, async (obj2) => { onMessage(c, async (obj2) => {
const { id, name, args, sid, fid, url } = obj2; const { id, name, args, sid, fid, url } = obj2;
if (name == "keepAlive") { if (name == "keepAlive") {
@ -2087,7 +2088,7 @@
return; return;
} }
if (name == "corsFetch") { if (name == "corsFetch") {
bgCorsFetch(c, id, ...args); bgCorsFetch(c, pendingFetches, id, ...args);
return; return;
} }
if (name == "revoke") { if (name == "revoke") {
@ -2114,7 +2115,8 @@
res res
}); });
}); });
}); }
})();
})(); })();
/*! /*!
* The buffer module from node.js, for the browser. * The buffer module from node.js, for the browser.

197
firefox/dist/main.js

File diff suppressed because one or more lines are too long

2
firefox/manifest.json

@ -7,7 +7,7 @@
}, },
"name": "PngExtraEmbedder", "name": "PngExtraEmbedder",
"description": "Discover embedded files on 4chan and archives!", "description": "Discover embedded files on 4chan and archives!",
"version": "0.299", "version": "0.300",
"icons": { "icons": {
"64": "1449696017588.png" "64": "1449696017588.png"
}, },

2
firefox_update.json

@ -1 +1 @@
{"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.299","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.299.xpi"}]}}} {"addons":{"{34ac4994-07f2-44d2-8599-682516a6c6a6}":{"updates":[{"version":"0.300","update_link":"https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.300.xpi"}]}}}

2
main.meta.js

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name PNGExtraEmbed // @name PNGExtraEmbed
// @namespace https://coom.tech/ // @namespace https://coom.tech/
// @version 0.296 // @version 0.300
// @description uhh // @description uhh
// @author You // @author You
// @match https://boards.4channel.org/* // @match https://boards.4channel.org/*

226
main.user.js

File diff suppressed because one or more lines are too long

BIN
pngextraembedder-0.300.xpi

Binary file not shown.

24
src/background.ts

@ -88,9 +88,11 @@ async function bravedeserialize(src: any): Promise<any> {
} }
} }
const pendingFetches = new Map<MessagePort, { [id in number]: { fetchFully: boolean } }>(); const bgCorsFetch = async (c: MessagePort,
pendingFetches: Map<MessagePort, { [id in number]: { fetchFully: boolean } }>,
const bgCorsFetch = async (c: MessagePort, id: number, input: string, init?: RequestInit) => { id: number,
input: string,
init?: RequestInit) => {
if (input.startsWith('//')) // firefox?? if (input.startsWith('//')) // firefox??
input = 'https:' + input; input = 'https:' + input;
if (init?.body && execution_mode == "chrome_api") { if (init?.body && execution_mode == "chrome_api") {
@ -185,7 +187,7 @@ const waitConnect = (cb: any) => {
//if (msg.origin === meself) { //if (msg.origin === meself) {
cb(msg.ports[0]); cb(msg.ports[0]);
//} //}
}); }, { once: true });
}; };
const onMessage = (c: MessagePort, cb: any) => const onMessage = (c: MessagePort, cb: any) =>
@ -193,9 +195,14 @@ const onMessage = (c: MessagePort, cb: any) =>
cb(e.data); cb(e.data);
}; };
waitConnect((c: any) => { (async () => {
// eslint-disable-next-line no-constant-condition
while (true) {
const c = await new Promise<MessagePort>(waitConnect);
const pendingFetches = new Map<MessagePort, { [id in number]: { fetchFully: boolean } }>();
onMessage(c, async (obj: any) => { onMessage(c, async (obj: any) => {
const { id, name, args, sid, fid, url } = obj as { url?: string, fid?: number, sid?: number, id: number, name: string, args: Parameters<typeof Platform[keyof Methods<typeof Platform>]> }; const { id, name, args, sid, fid, url } = obj as any;
if (name == "keepAlive") { if (name == "keepAlive") {
console.log('im alive, tho?'); console.log('im alive, tho?');
return; return;
@ -206,7 +213,7 @@ waitConnect((c: any) => {
} }
if (name == "corsFetch") { if (name == "corsFetch") {
// this handles the reply // this handles the reply
(bgCorsFetch as any)(c, id, ...args); (bgCorsFetch as any)(c, pendingFetches, id, ...args);
return; return;
} }
@ -232,4 +239,5 @@ waitConnect((c: any) => {
id, res id, res
}); });
}); });
}); }
})();

65
src/f5stego.ts

@ -254,11 +254,8 @@ type FrameType = {
}; };
export class f5stego { export class f5stego {
#randPool!: ArrayBuffer;
constructor(key: ArrayLike<number>, private maxPixels: number = 4096 * 4096) { constructor(key: ArrayLike<number>, private maxPixels: number = 4096 * 4096) {
this.#shuffleInit(key); }
};
embed(image: Uint8Array, data: ArrayLike<number>, k?: number) { embed(image: Uint8Array, data: ArrayLike<number>, k?: number) {
this.parse(image); this.parse(image);
@ -280,66 +277,6 @@ export class f5stego {
#tail: Uint8Array | null = null; #tail: Uint8Array | null = null;
#shuffleInit(key: ArrayLike<number>) {
this.#randPool = new ArrayBuffer(this.maxPixels * 4.125);
if (!key.length) throw 'key needed';
var i = 0,
j = 0,
t = 0,
k = 0,
S = new Uint8Array(256),
rnd = new Uint8Array(this.#randPool);
// init state from key
for (i = 0; i < 256; ++i) S[i] = i;
for (i = 0; i < 256; ++i) {
j = (j + S[i] + key[i % key.length]) & 255;
t = S[i];
S[i] = S[j];
S[j] = t;
}
i = 0;
j = 0;
// shuffle data
for (k = 0; k < this.maxPixels * 4.125; ++k) {
i = (i + 1) & 255;
j = (j + S[i]) & 255;
t = S[i];
S[i] = S[j];
S[j] = t;
rnd[k] = S[(t + S[i]) & 255];
}
}
#stegShuffle(pm: number | Uint32Array | Int16Array) {
let t, l, k, random_index, rand32Array = new Uint32Array(this.#randPool);
if (typeof pm == 'number') {
l = pm;
pm = new Uint32Array(l);
for (k = 1; k < l; k++) {
random_index = rand32Array[k] % (k + 1);
if (random_index != k) pm[k] = pm[random_index];
pm[random_index] = k;
}
} else {
l = pm.length;
for (k = 1; k < l; k++) {
random_index = rand32Array[k] % (k + 1);
// if (random_index != k) {
t = pm[k];
pm[k] = pm[random_index];
pm[random_index] = t;
// }
}
}
return { pm: pm, gamma: new Uint8Array(this.#randPool, l * 4) };
}
#_analyze(coeff: Int16Array) { #_analyze(coeff: Int16Array) {
var _one = 0, var _one = 0,
_zero = 0, _zero = 0,

165
src/main.ts

@ -23,7 +23,7 @@ import NotificationsHandler from './Components/NotificationsHandler.svelte';
import { fireNotification, getEmbedsFromCache, getSelectedFile } from "./utils"; import { fireNotification, getEmbedsFromCache, getSelectedFile } from "./utils";
import { getQueryProcessor, QueryProcessor } from "./websites"; import { getQueryProcessor, QueryProcessor } from "./websites";
import { ifetch, Platform, sendCmd, lqueue, supportedAltDomain, supportedMainDomain } from "./platform"; import { ifetch, Platform, sendCmd, lqueue, supportedAltDomain, supportedMainDomain, genPort } from "./platform";
import TextEmbeddingsSvelte from "./Components/TextEmbeddings.svelte"; import TextEmbeddingsSvelte from "./Components/TextEmbeddings.svelte";
import { HydrusClient } from "./hydrus"; import { HydrusClient } from "./hydrus";
import { registerPlugin } from 'linkifyjs'; import { registerPlugin } from 'linkifyjs';
@ -47,6 +47,7 @@ const processors: ImageProcessor[] =
let cappState: Parameters<typeof appState['set']>[0]; let cappState: Parameters<typeof appState['set']>[0];
settings.subscribe(async b => { settings.subscribe(async b => {
if (!b) return; if (!b) return;
csettings = b;
if (b.hyd) { if (b.hyd) {
// transition from disable to enabled // transition from disable to enabled
if (b.ak) { if (b.ak) {
@ -64,7 +65,6 @@ settings.subscribe(async b => {
} }
} }
} }
csettings = b;
//processors = [...(!csettings.te ? [thirdeye] : []), //processors = [...(!csettings.te ? [thirdeye] : []),
// pngv3, pomf, jpg, webm, gif // pngv3, pomf, jpg, webm, gif
//]; //];
@ -212,69 +212,18 @@ const shouldUseCache = () => {
let cp: CommandProcessor; let cp: CommandProcessor;
class CommandProcessor { class BackgroundEmulator {
processor = ProcessWorker(); async bgCorsFetch(c: MessagePort,
pendingFetches: Map<MessagePort, { [id in number]: { fetchFully: boolean } }>,
genid = 0; id: number,
input: string,
pendinggens: Record<number, AsyncGenerator> = {}; init?: RequestInit) {
cmdid = 0;
pendingprom: Record<number, (v?: any) => void> = {};
constructor() {
this.processor.onmessage = async (msg) => {
let gen: AsyncGenerator;
let res: IteratorResult<any, any>;
switch (msg.data.type) {
case 'ipc':
{
const id = msg.data.msg.id;
if (execution_mode != "userscript") {
if (msg.data.msg.name == 'corsFetch') {
sendCmd(msg.data.msg, msg.data.tr);
lqueue[id] = (res: any) => {
this.processor.postMessage({
type: 'ipc',
id,
res
});
};
} else {
// for complitude, but technically the webworker doesn't run anything besides corsFetch
const repl: any = await sendCmd(msg.data.msg, msg.data.tr);
repl.id = id;
this.processor.postMessage({
type: 'ipc',
id,
res: repl
});
}
} else {
if (msg.data.msg.name == 'fullyRead') {
// ignore
this.processor.postMessage({
type: 'ipc',
res: {
id,
ok: 1
}
});
}
if (msg.data.msg.name == 'corsFetch') {
const { args } = msg.data.msg;
try { try {
const res = await ifetch(args[0], args[1]); const res = await ifetch(input, init);
// don't report progress because monkeys don't have a way to expose partial responses anyway // don't report progress because monkeys don't have a way to expose partial responses anyway
const headersStr = (res as any).responseHeaders; const headersStr = (res as any).responseHeaders;
const headerObj = headerStringToObject(headersStr); const headerObj = headerStringToObject(headersStr);
c.postMessage({
this.processor.postMessage({
type: 'ipc',
id,
res: {
id, id,
ok: res.ok || true, ok: res.ok || true,
setRes: true, setRes: true,
@ -286,36 +235,24 @@ class CommandProcessor {
status: res.status, status: res.status,
bodyUsed: res.bodyUsed, bodyUsed: res.bodyUsed,
statusText: res.statusText, statusText: res.statusText,
}
}); });
if (!args[1].method || ['GET', 'POST'].includes(args[1].method)) { if (['GET', 'POST'].includes(init?.method || 'GET')) {
const data = await res.arrayBuffer(); const data = await res.arrayBuffer();
this.processor.postMessage({ c.postMessage({
type: 'ipc',
id,
res: {
id, id,
pushData: { pushData: {
data data
} }
}
}, [data]); }, [data]);
} }
// let's hope these are delivered in order :%) // let's hope these are delivered in order :%)
this.processor.postMessage({ c.postMessage({
type: 'ipc',
id,
res: {
id, id,
pushData: { pushData: {
} }
}
}, []); }, []);
} catch (e) { } catch (e) {
this.processor.postMessage({ c.postMessage({
type: 'ipc',
id,
res: {
id, id,
ok: false, ok: false,
setRes: true, setRes: true,
@ -325,14 +262,71 @@ class CommandProcessor {
status: 400, status: 400,
bodyUsed: false, bodyUsed: false,
statusText: 'shit broke', statusText: 'shit broke',
});
}
}
constructor(private port: MessagePort) {
const pendingFetches = new Map<MessagePort, { [id in number]: { fetchFully: boolean } }>();
port.onmessage = async (obj: MessageEvent) => {
const { id, name, args, sid, fid, url } = obj.data as any;
if (name == "keepAlive") {
console.log('im alive, tho?');
return;
}
if (name == "abortCorsFetch") {
//chrome.runtime.sendMessage({ name, sid });
return;
}
if (name == "corsFetch") {
// this handles the reply
(this.bgCorsFetch as any)(port, pendingFetches, id, ...args);
return;
} }
if (name == "revoke") {
URL.revokeObjectURL(url!);
port.postMessage({
id, ok: 1
}); });
return;
} }
if (name == "fullyRead") {
const obj = pendingFetches.get(port)!;
if (obj && fid! in obj)
obj[fid!].fetchFully = true;
port.postMessage({
id, ok: 1
});
return;
} }
// ignore other commands const res = await (Platform as any)[name](...args);
port.postMessage({
id, res
});
};
} }
} break; }
class CommandProcessor {
processor = ProcessWorker();
genid = 0;
pendinggens: Record<number, AsyncGenerator> = {};
cmdid = 0;
pendingprom: Record<number, (v?: any) => void> = {};
constructor() {
this.processor.onmessage = async (msg) => {
let gen: AsyncGenerator;
let res: IteratorResult<any, any>;
switch (msg.data.type) {
case 'reply': case 'reply':
if (msg.data.id in this.pendingprom) { if (msg.data.id in this.pendingprom) {
this.pendingprom[msg.data.id](msg.data.res); this.pendingprom[msg.data.id](msg.data.res);
@ -352,7 +346,20 @@ class CommandProcessor {
}); });
break; break;
} }
}; };
if (execution_mode != "userscript") {
const ipcport = genPort();
this.processor.postMessage({ type: 'ipc', port: ipcport }, [ipcport]);
} else {
const nmc = new MessageChannel();
const port1 = nmc.port1;
const port2 = nmc.port2;
new BackgroundEmulator(port2);
const ipcport = port1;
this.processor.postMessage({ type: 'ipc', port: ipcport }, [ipcport]);
}
} }
serializeArg(m: any) { serializeArg(m: any) {

32
src/platform.ts

@ -11,20 +11,25 @@ const localSet = (key: string, value: any) =>
localStorage.setItem('__pee__' + key, JSON.stringify(value)); localStorage.setItem('__pee__' + key, JSON.stringify(value));
export let port1: MessagePort; export let port1: MessagePort;
let port2: MessagePort;
console.log(execution_mode, isBackground); console.log(execution_mode, isBackground);
/* /*
A web worker has no access to the dom, so things like remote fetches are proxied through the main frame A web worker has no access to the dom, so things like remote fetches are proxied through the main frame
*/ */
let iframe: HTMLIFrameElement;
if (execution_mode != 'userscript' && !isBackground && execution_mode != 'worker') { export const genPort = () => {
const nmc = new MessageChannel(); const nmc = new MessageChannel();
port1 = nmc.port1; const port1 = nmc.port1;
port2 = nmc.port2; const port2 = nmc.port2;
iframe.contentWindow?.postMessage('', '*', [port2]);
return port1;
};
if (execution_mode != 'userscript' && !isBackground && execution_mode != 'worker') {
// It has to be a content script // It has to be a content script
const iframe = document.createElement('iframe'); iframe = document.createElement('iframe');
iframe.style.display = 'none'; iframe.style.display = 'none';
iframe.name = location.origin; iframe.name = location.origin;
const iframeloaded = new Promise(_ => { const iframeloaded = new Promise(_ => {
@ -34,15 +39,21 @@ if (execution_mode != 'userscript' && !isBackground && execution_mode != 'worker
//const meself = new URL(chrome.runtime.getURL('')).origin; //const meself = new URL(chrome.runtime.getURL('')).origin;
document.documentElement.appendChild(iframe); document.documentElement.appendChild(iframe);
iframeloaded.then(() => { iframeloaded.then(() => {
iframe.contentWindow?.postMessage('', '*', [port2]); port1 = genPort();
});
port1.onmessage = (ev) => { port1.onmessage = (ev) => {
lqueue[ev.data.id](ev.data); lqueue[ev.data.id](ev.data);
}; };
});
} }
console.log(execution_mode); export const setupPort = (port: MessagePort) => {
port1 = port;
port1.onmessage = (ev) => {
lqueue[ev.data.id](ev.data);
};
};
// will be later overwritten if it's not launched from the userscript
if (execution_mode == "worker") { if (execution_mode == "worker") {
port1 = { port1 = {
onmessage(ev) { onmessage(ev) {
@ -70,11 +81,14 @@ const visit = (e: any, cb: (e: any) => true | undefined) => {
cb(e); cb(e);
}; };
export const sendCmd = <V>(cmd: any, tr?: Transferable[]) => { export const sendCmd = <V>(cmd: any, tr?: Transferable[], overwrite = false, todelete = false) => {
const prom = new Promise<V>(_ => { const prom = new Promise<V>(_ => {
const id = gid++; const id = gid++;
if (overwrite)
cmd.id = id;
lqueue[id] = (e: any) => { lqueue[id] = (e: any) => {
_(e); _(e);
if (todelete)
delete lqueue[id]; delete lqueue[id];
}; };
port1.postMessage({ id, ...cmd }, tr || []); port1.postMessage({ id, ...cmd }, tr || []);

13
src/processor.worker.ts

@ -59,6 +59,8 @@ const proxyAsyncGen = (id: number) => {
}; };
const deserializeMessage = (m: any) => { const deserializeMessage = (m: any) => {
if (m instanceof MessagePort)
return m;
if (typeof m == "object" && m.type == 'AsyncGenerator') { if (typeof m == "object" && m.type == 'AsyncGenerator') {
return proxyAsyncGen(m.id); return proxyAsyncGen(m.id);
} }
@ -144,7 +146,7 @@ const processImage = async (srcs: AsyncGenerator<string, void, void>, fn: string
return; return;
} }
return [await proc.extract(cumul), false] as [WorkerEmbeddedFile[], boolean]; return [await proc.extract(cumul), false] as [WorkerEmbeddedFile[], boolean];
} catch(err) { } catch (err) {
console.log(err); console.log(err);
// ignore error and retry with another link // ignore error and retry with another link
} }
@ -153,13 +155,11 @@ const processImage = async (srcs: AsyncGenerator<string, void, void>, fn: string
return ret.filter(e => e).map(e => e!); return ret.filter(e => e).map(e => e!);
}; };
(async () => { onmessage = async (msg: MessageEvent<any>) => {
onmessage = async (msg: MessageEvent<any>) => {
const des = deserializeMessage(msg.data); const des = deserializeMessage(msg.data);
switch (des.type) { switch (des.type) {
case 'ipc': { case 'ipc': {
if (platform.port1.onmessage) platform.setupPort(des.port);
platform.port1.onmessage(new MessageEvent("message", { data: des.res }));
break; break;
} }
case 'cmd': { case 'cmd': {
@ -195,5 +195,4 @@ const processImage = async (srcs: AsyncGenerator<string, void, void>, fn: string
break; break;
} }
} }
}; };
})();

Loading…
Cancel
Save