Browse Source

Transfer files between iframe more efficiently on chrome and works on brave

pull/46/head
coomdev 2 years ago
parent
commit
cb12a65a8f
  1. 20
      chrome/dist/background.js
  2. 120
      chrome/dist/main.js
  3. 2
      chrome/manifest.json
  4. 51
      src/background.ts
  5. 73
      src/platform.ts

20
chrome/dist/background.js

@ -1969,7 +1969,8 @@
};
}
}, filts, ["blocking", "responseHeaders", ...true ? ["extraHeaders"] : []]);
async function deserialize(src) {
var snooze = (n) => new Promise((_) => setTimeout(_, n));
async function bravedeserialize(src) {
if (typeof src != "object")
return src;
switch (src.cls) {
@ -1977,26 +1978,30 @@
const ret = new FormData();
for (const [key, items] of src.value) {
for (const item of items) {
ret.append(key, await deserialize(item));
ret.append(key, await bravedeserialize(item));
}
}
return ret;
}
case "File": {
return new File([await (await fetch(src.value)).blob()], src.name, {
if ("brave" in navigator)
await snooze(1e3);
return new File([src.value], src.name, {
lastModified: src.lastModified,
type: src.type
});
}
case "Blob": {
return new Blob([await (await fetch(src.value)).blob()], {
if ("brave" in navigator)
await snooze(1e3);
return new Blob([src.value], {
type: src.type
});
}
case "Object": {
const ret = {};
for (const prop in src.value) {
ret[prop] = await deserialize(src.value[prop]);
ret[prop] = await bravedeserialize(src.value[prop]);
}
return ret;
}
@ -2006,8 +2011,9 @@
var bgCorsFetch = async (c, id, input, init) => {
if (input.startsWith("//"))
input = "https:" + input;
if (init?.body && true)
init.body = await deserialize(init.body);
if (init?.body && true) {
init.body = await bravedeserialize(init.body);
}
try {
const k = await fetch(input, init);
let headersStr = "";

120
chrome/dist/main.js

@ -51,7 +51,7 @@
var define_BUILD_VERSION_default;
var init_define_BUILD_VERSION = __esm({
"<define:BUILD_VERSION>"() {
define_BUILD_VERSION_default = [0, 256];
define_BUILD_VERSION_default = [0, 259];
}
});
@ -14206,79 +14206,60 @@
}
}
}
async function serialize(src) {
if (src instanceof FormData) {
const value = [];
for (const kv of src)
value.push([kv[0], await Promise.all(src.getAll(kv[0]).map(serialize))]);
return {
cls: "FormData",
value
};
}
if (src instanceof File) {
const { name, type, lastModified } = src;
const value = URL.createObjectURL(src);
return {
cls: "File",
name,
type,
lastModified,
value
};
}
if (src instanceof Blob) {
const { type } = src;
const value = URL.createObjectURL(src);
return {
cls: "Blob",
type,
value
};
}
if (src === null || src === void 0 || typeof src != "object")
return src;
const ret = {
cls: "Object",
value: {}
};
for (const prop in src) {
ret.value[prop] = await serialize(src[prop]);
}
return ret;
}
function cleanupSerialized(src) {
if (typeof src != "object")
return src;
switch (src.cls) {
case "FormData": {
for (const [key, items] of src.value) {
for (const item of items) {
cleanupSerialized(item);
}
}
break;
async function braveserialize(root) {
const transfer = [];
const ser = async (src) => {
if (src instanceof FormData) {
const value = [];
for (const kv of src)
value.push([kv[0], await Promise.all(src.getAll(kv[0]).map(ser))]);
return {
cls: "FormData",
value
};
}
case "File": {
URL.revokeObjectURL(src.value);
break;
if (src instanceof File) {
const { name, type, lastModified } = src;
const value = await src.arrayBuffer();
transfer.push(value);
return {
cls: "File",
name,
type,
lastModified,
value
};
}
case "Blob": {
URL.revokeObjectURL(src.value);
break;
if (src instanceof Blob) {
const { type } = src;
const value = await src.arrayBuffer();
transfer.push(value);
return {
cls: "Blob",
type,
value
};
}
case "Object": {
for (const prop in src.value) {
cleanupSerialized(src.value[prop]);
}
if (src === null || src === void 0 || typeof src != "object")
return src;
const ret = {
cls: "Object",
value: {}
};
for (const prop in src) {
ret.value[prop] = await ser(src[prop]);
}
}
return ret;
};
return [await ser(root), transfer];
}
var corsFetch = async (input, init5, lsn) => {
const id = gid++;
let transfer = [];
if (init5?.body) {
if (true)
init5.body = await serialize(init5.body);
if (true) {
[init5.body, transfer] = await braveserialize(init5.body);
}
}
const prom = new Promise((_, rej) => {
let gcontroller;
@ -14297,12 +14278,7 @@
let s;
s = 0;
const cmdbuff = [];
let cleaned = false;
lqueue[id] = async (e) => {
if (!cleaned && true && init5?.body) {
cleanupSerialized(init5.body);
cleaned = true;
}
if (e.progress) {
if (lsn)
lsn.dispatchEvent(new CustomEvent("progress", { detail: e.progress }));
@ -14394,7 +14370,7 @@
id,
name: "corsFetch",
args: [input, init5]
});
}, transfer);
});
return prom;
};

2
chrome/manifest.json

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

51
src/background.ts

@ -54,6 +54,8 @@ if (manifest == 2)
}
}, filts, ['blocking', 'responseHeaders', ...(execution_mode == "chrome_api" ? ['extraHeaders' as 'blocking'] : [])]);
const snooze = (n: number) => new Promise<void>((_) => setTimeout(_, n));
async function deserialize(src: any): Promise<any> {
if (typeof src != "object")
return src;
@ -68,12 +70,16 @@ async function deserialize(src: any): Promise<any> {
return ret;
}
case 'File': {
if ('brave' in navigator)
await snooze(1000);
return new File([await (await fetch(src.value)).blob()], src.name, {
lastModified: src.lastModified,
type: src.type
});
}
case 'Blob': {
if ('brave' in navigator)
await snooze(1000);
return new Blob([await (await fetch(src.value)).blob()], {
type: src.type
});
@ -88,13 +94,52 @@ async function deserialize(src: any): Promise<any> {
}
}
async function bravedeserialize(src: any): Promise<any> {
if (typeof src != "object")
return src;
switch (src.cls) {
case 'FormData': {
const ret = new FormData();
for (const [key, items] of src.value) {
for (const item of items) {
ret.append(key, await bravedeserialize(item));
}
}
return ret;
}
case 'File': {
if ('brave' in navigator)
await snooze(1000);
return new File([src.value], src.name, {
lastModified: src.lastModified,
type: src.type
});
}
case 'Blob': {
if ('brave' in navigator)
await snooze(1000);
return new Blob([src.value], {
type: src.type
});
}
case 'Object': {
const ret = {} as any;
for (const prop in src.value) {
ret[prop] = await bravedeserialize(src.value[prop]);
}
return ret;
}
}
}
const pendingFetches = new Map<MessagePort, { [id in number]: { fetchFully: boolean } }>();
const bgCorsFetch = async (c: MessagePort, id: number, input: string, init?: RequestInit) => {
if (input.startsWith('//')) // firefox??
input = 'https:' + input;
if (init?.body && execution_mode == "chrome_api")
init.body = await deserialize(init.body);
if (init?.body && execution_mode == "chrome_api") {
init.body = await bravedeserialize(init.body);
}
try {
const k = await fetch(input, init);
@ -165,7 +210,7 @@ const bgCorsFetch = async (c: MessagePort, id: number, input: string, init?: Req
}
e.close();
reader?.releaseLock();
} catch(e) {
} catch (e) {
const err = e as Error;
c.postMessage({
id,

73
src/platform.ts

@ -184,42 +184,59 @@ async function serialize(src: any): Promise<any> {
return ret;
}
function cleanupSerialized(src: any) {
if (typeof src != "object")
return src;
switch (src.cls) {
case 'FormData': {
for (const [key, items] of src.value) {
for (const item of items) {
cleanupSerialized(item);
}
}
break;
async function braveserialize(root: any): Promise<any> {
const transfer: Transferable[] = [];
const ser = async (src: any): Promise<any> => {
if (src instanceof FormData) {
const value = [];
for (const kv of src)
value.push([kv[0], await Promise.all(src.getAll(kv[0]).map(ser))]);
return {
cls: 'FormData', value,
};
}
case 'File': {
URL.revokeObjectURL(src.value);
break;
if (src instanceof File) {
const { name, type, lastModified } = src;
const value = await src.arrayBuffer();
transfer.push(value);
return {
cls: 'File',
name, type, lastModified, value,
};
}
case 'Blob': {
URL.revokeObjectURL(src.value);
break;
if (src instanceof Blob) {
const { type } = src;
const value = await src.arrayBuffer();
transfer.push(value);
return {
cls: 'Blob', type, value,
};
}
case 'Object': {
for (const prop in src.value) {
cleanupSerialized(src.value[prop]);
}
if (src === null || src === undefined || typeof src != "object")
return src;
const ret = {
cls: 'Object',
value: {}
} as any;
for (const prop in src) {
ret.value[prop] = await ser(src[prop]);
}
}
return ret;
};
return [await ser(root), transfer];
}
export const corsFetch = async (input: string, init?: RequestInit, lsn?: EventTarget) => {
const id = gid++;
let transfer: Transferable[] = [];
if (init?.body) {
// Chrom* can't pass around FormData and File/Blobs between
// the content and bg scripts, so the data is passed through bloburls
if (execution_mode == "chrome_api")
init.body = await serialize(init.body);
if (execution_mode == "chrome_api") {
[init.body, transfer] = await braveserialize(init.body);
}
}
const prom = new Promise<Awaited<ReturnType<typeof fetch>>>((_, rej) => {
@ -247,13 +264,7 @@ export const corsFetch = async (input: string, init?: RequestInit, lsn?: EventTa
s = 0;
const cmdbuff: any[] = [];
let cleaned = false;
lqueue[id] = (async (e: any) => {
if (!cleaned && execution_mode == "chrome_api" && init?.body) {
cleanupSerialized(init.body);
cleaned = true;
}
// this is computed from the background script because the content script may
// request everything to be delivered in one chunk, defeating the purpose
if (e.progress) {
@ -360,7 +371,7 @@ export const corsFetch = async (input: string, init?: RequestInit, lsn?: EventTa
port1.postMessage({
id, name: 'corsFetch', args: [input, init]
});
}, transfer);
});
return prom;
};

Loading…
Cancel
Save