diff --git a/README.md b/README.md index 493f408..4c6c80f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,16 @@ PNGExtraEmbedder (PEE) ======================== +!NOTE!: the userscript version is now deprecated and broken. + Can embed any file in a PNG/WebM/GIF/JPEG and upload it to a third-party host through 4chan. Requires a userscript manager, such as ViolentMonkey. It should work with 4chan's native extension but 4ChanX is highly recommended as it is much more tested. Also supports desuarchive. +Kohlchan support is being worked on. Right now works barely on Chrome. +There's no server-side caching for kohlchan. Buttons to embed will only be added to the quick reply form. + How to Install ============== diff --git a/build-chrome.js b/build-chrome.js index e39d13d..fbd86e5 100644 --- a/build-chrome.js +++ b/build-chrome.js @@ -33,6 +33,7 @@ const domains = [ "https://fireden.net/*", "https://thebarchive.com/*", "https://archiveofsins.com/*", + "https://kohlchan.net/*" ]; const manif3 = { diff --git a/build-ff.js b/build-ff.js index 5d07f49..e363c17 100644 --- a/build-ff.js +++ b/build-ff.js @@ -51,7 +51,9 @@ const domains = [ "https://*.donmai.us/*", "https://*.lolibooru.moe/*", "https://*.allthefallen.moe/*", - "https://desu-usergeneratedcontent.xyz/*" + "https://desu-usergeneratedcontent.xyz/*", + "https://kohlchan.net/*" + ]; const manif = { diff --git a/chrome/_metadata/generated_indexed_rulesets/_ruleset1 b/chrome/_metadata/generated_indexed_rulesets/_ruleset1 index 35ab271..93ae551 100644 Binary files a/chrome/_metadata/generated_indexed_rulesets/_ruleset1 and b/chrome/_metadata/generated_indexed_rulesets/_ruleset1 differ diff --git a/chrome/b4k-csp.json b/chrome/b4k-csp.json index 8f3c2ac..4474b81 100644 --- a/chrome/b4k-csp.json +++ b/chrome/b4k-csp.json @@ -12,7 +12,7 @@ }, "condition": { "requestDomains": [ - "arch.b4k.co", "desuarchive.org", "boards.4chan.org", "boards.4channel.org" + "arch.b4k.co", "desuarchive.org", "boards.4chan.org", "boards.4channel.org", "kohlchan.net" ], "resourceTypes": [ "main_frame" diff --git a/chrome/dist/main.js b/chrome/dist/main.js index 71b3dcd..c3c27b3 100644 --- a/chrome/dist/main.js +++ b/chrome/dist/main.js @@ -73,7 +73,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 324]; + define_BUILD_VERSION_default = [0, 326]; } }); @@ -8574,7 +8574,8 @@ "b4k.co", "fireden.net", "thebarchive.com", - "archiveofsins.com" + "archiveofsins.com", + "kohlchan.net" ]; function supportedAltDomain(s) { return altdomains.includes(s); @@ -20225,7 +20226,7 @@ init_define_BUILD_VERSION(); init_esbuild_inject(); function add_css13(target) { - append_styles(target, "svelte-120v8nn", ".clickable.svelte-120v8nn.svelte-120v8nn{cursor:pointer;float:right}.root.svelte-120v8nn>span.svelte-120v8nn{display:flex;gap:10px;border:1px solid;padding:10px;border-radius:5px;font-weight:bolder;color:white;min-width:45vw}.root.svelte-120v8nn.svelte-120v8nn{position:fixed;top:0;left:50%;transform:translateX(-50%);display:flex;flex-direction:column;gap:10px}.error.svelte-120v8nn.svelte-120v8nn{background-color:crimson}.info.svelte-120v8nn.svelte-120v8nn{background-color:cornflowerblue}.warning.svelte-120v8nn.svelte-120v8nn{background-color:darkgoldenrod}.success.svelte-120v8nn.svelte-120v8nn{background-color:green}"); + append_styles(target, "svelte-5t4r47", ".clickable.svelte-5t4r47.svelte-5t4r47{cursor:pointer;float:right}.root.svelte-5t4r47>span.svelte-5t4r47{display:flex;gap:10px;border:1px solid;padding:10px;border-radius:5px;font-weight:bolder;color:white;min-width:45vw}.root.svelte-5t4r47.svelte-5t4r47{position:fixed;top:0;left:50%;transform:translateX(-50%);display:flex;flex-direction:column;gap:10px}.error.svelte-5t4r47.svelte-5t4r47{background-color:crimson}.info.svelte-5t4r47.svelte-5t4r47{background-color:cornflowerblue}.warning.svelte-5t4r47.svelte-5t4r47{background-color:darkgoldenrod}.success.svelte-5t4r47.svelte-5t4r47{background-color:green}"); } function get_each_context6(ctx, list, i) { const child_ctx = ctx.slice(); @@ -20251,8 +20252,8 @@ t0 = text(t0_value); span0 = element("span"); span0.textContent = "X"; - attr(span0, "class", "clickable svelte-120v8nn"); - attr(span1, "class", span1_class_value = null_to_empty(ctx[4].type) + " svelte-120v8nn"); + attr(span0, "class", "clickable svelte-5t4r47"); + attr(span1, "class", span1_class_value = null_to_empty(ctx[4].type) + " svelte-5t4r47"); this.first = span1; }, m(target, anchor) { @@ -20268,7 +20269,7 @@ ctx = new_ctx; if (dirty & 1 && t0_value !== (t0_value = ctx[4].content + "")) set_data(t0, t0_value); - if (dirty & 1 && span1_class_value !== (span1_class_value = null_to_empty(ctx[4].type) + " svelte-120v8nn")) { + if (dirty & 1 && span1_class_value !== (span1_class_value = null_to_empty(ctx[4].type) + " svelte-5t4r47")) { attr(span1, "class", span1_class_value); } }, @@ -20297,7 +20298,7 @@ for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } - attr(div, "class", "root svelte-120v8nn"); + attr(div, "class", "root svelte-5t4r47"); }, m(target, anchor) { insert(target, div, anchor); @@ -20431,9 +20432,35 @@ getCurrentBoard: V4chan.getCurrentBoard, getCurrentThread: V4chan.getCurrentThread }; + var KChan = { + getFileThumbnail: (post) => post.querySelector("figure.uploadCell"), + getPost: (post) => post.querySelector(".innerPost"), + postsWithFiles: (h) => [...(h || document).querySelectorAll(".postCell:has(figure)")], + settingsHost: () => document.getElementById("navOptionsSpanThread"), + catalogControlHost: () => document.getElementById("divTools"), + getImageLink: async function* (post) { + yield post.querySelector('a.imgLink[target="_blank"]')?.href || ""; + }, + getFilename: (post) => { + const a = post.querySelector(".imgLink > img"); + if (a && a.title) + return a.title; + return a?.textContent || ""; + }, + getMD5: (post) => "", + getThumbnailLink: (post) => post.querySelector(".imgLink > img")?.getAttribute("src") || "", + getInfoBox: (post) => post.querySelector("div.uploadDetails"), + getPostIdPrefix: () => "", + getTextBox: (post) => post.querySelector(".divMessage"), + getCurrentBoard: () => location.pathname.split("/")[1], + getCurrentThread: () => +location.pathname.split("/")[3] + }; var getQueryProcessor = (is4chanX) => { if (["boards.4chan.org", "boards.4channel.org"].includes(location.host)) return is4chanX ? X4chan : V4chan; + if (location.host == "kohlchan.net") { + return KChan; + } if (document.querySelector('meta[name="generator"]')?.getAttribute("content")?.startsWith("FoolFuuka")) return FoolFuuka; }; @@ -21720,6 +21747,8 @@ } }, 5e3, { trailing: true }); var shouldUseCache = () => { + if (location.host == "kohlchan.net") + return false; if (cappState.isCatalog) return false; if (!csettings5) @@ -21872,7 +21901,7 @@ if (cappState.isCatalog) op = +post.id.slice(2); else - op = +location.pathname.match(/\/thread\/(.*)/)[1]; + op = qp.getCurrentThread() || 0; if (shouldUseCache()) { res2 = await getEmbedsFromCache(qp.getCurrentBoard(), +qp.getCurrentThread(), post.id); } @@ -22000,6 +22029,18 @@ Use the WebExtension version of PEE if you want to use b4k!`); qr.files = dt.files; }); } + if (!document.body) { + let bodyRes; + const bodyInit = new Promise((r) => bodyRes = r); + const mo2 = new MutationObserver((r) => { + if (document.body) { + mo2.disconnect(); + bodyRes(); + } + }); + mo2.observe(document.documentElement, { childList: true, subtree: true }); + await bodyInit; + } if (!cappState.isCatalog) { const mo = new MutationObserver((reco) => { for (const rec of reco) @@ -22031,18 +22072,6 @@ Use the WebExtension version of PEE if you want to use b4k!`); mo.observe(e, { childList: true, subtree: true }); }); } - if (!document.body) { - let bodyRes; - const bodyInit = new Promise((r) => bodyRes = r); - const mo2 = new MutationObserver((r) => { - if (document.body) { - mo2.disconnect(); - bodyRes(); - } - }); - mo2.observe(document.documentElement, { childList: true, subtree: true }); - await bodyInit; - } document.addEventListener("QRDialogCreation", (e) => { const a = document.createElement("span"); const po = new PostOptions_default({ @@ -22059,7 +22088,12 @@ Use the WebExtension version of PEE if you want to use b4k!`); } }; const obs = new MutationObserver(somethingChanged); - if (!cappState.is4chanX) { + if (location.host == "kohlchan.net") { + target = e.detail; + a.style.display = "inline-block"; + const filesinp = target.querySelector("#selectedDivQr"); + filesinp.parentElement?.appendChild(a); + } else if (!cappState.is4chanX) { target = e.detail; a.style.display = "inline-block"; target.querySelector("input[type=submit]")?.insertAdjacentElement("beforebegin", a); @@ -22072,6 +22106,21 @@ Use the WebExtension version of PEE if you want to use b4k!`); obs.observe(filesinp, { attributes: true }); } }, { once: !cappState.is4chanX }); + if (location.host == "kohlchan.net") { + setTimeout(() => { + const no = document.querySelector("#quick-reply"); + console.log("emitting qrdialog"); + document.dispatchEvent(new CustomEvent("QRDialogCreation", { + detail: no + })); + const s = document.createElement("script"); + s.src = chrome.runtime.getURL("kohlchan-hooks.js"); + s.onload = function() { + s.remove(); + }; + (document.head || document.documentElement).appendChild(s); + }, 1e3); + } try { cp = new CommandProcessor(); } catch { @@ -22080,7 +22129,7 @@ Use the WebExtension version of PEE if you want to use b4k!`); else fireNotification("error", "You may be using 4chanX\n\nGo to 4chanX's settings, Advanced > JS Whitelist and add 'blob:' without quotes to the list."); } - if (!is4chanX && location.host.startsWith("boards.4chan")) { + if (!is4chanX && location.host.startsWith("boards.4chan") || location.host == "kohlchan.net") { const notificationHost = document.createElement("span"); new NotificationsHandler_default({ target: notificationHost @@ -22182,9 +22231,12 @@ Use the WebExtension version of PEE if you want to use b4k!`); }); document.addEventListener("ThreadUpdate", async (e) => { const newPosts = e.detail.newPosts; + const qp2 = getQueryProcessor(cappState.is4chanX); + if (!qp2) + return; for (const post of newPosts) { - const postContainer = document.getElementById("pc" + post.substring(post.indexOf(".") + 1)); - const fn = qp.getFilename(postContainer); + const postContainer = document.getElementById(qp2.getPostIdPrefix() + post.substring(post.indexOf(".") + 1)); + const fn = qp2.getFilename(postContainer); if (fn) { if (!processed.has(postContainer.id)) { appState.update((v) => { diff --git a/chrome/kohlchan-hooks.js b/chrome/kohlchan-hooks.js new file mode 100644 index 0000000..3c8c51d --- /dev/null +++ b/chrome/kohlchan-hooks.js @@ -0,0 +1,35 @@ + +const pc = postCommon; +const pcasf = pc.addSelectedFile.bind(pc); +let prevFile; +pc.addSelectedFile = (f, unk) => { + pcasf(f, unk); + // will only embed in the first file + const refresh = () => { + const currentFile = pc.selectedFiles[0]; + if (prevFile != currentFile) { + prevFile = currentFile; + document.dispatchEvent(new CustomEvent("PEEFile", { detail: prevFile })); + } + }; + refresh(); + const rb = pc.selectedDiv.lastChild?.getElementsByClassName("removeButton")[0]; + if (rb) + rb.addEventListener("click", refresh); +}; + +document.addEventListener("QRSetFile", (e) => { + if (pc.selectedFiles.length > 0) + pc.selectedFiles[0] = e.detail.file; +}); + +const taup = thread.addUnreadPost.bind(thread); +thread.addUnreadPost = (e) => { + taup(e); + + document.dispatchEvent(new CustomEvent("ThreadUpdate", { + detail: { + newPosts: ['b.' + e.postId] + } + })); +} \ No newline at end of file diff --git a/chrome/manifest.json b/chrome/manifest.json index 3098d3b..caba2f2 100644 --- a/chrome/manifest.json +++ b/chrome/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "PngExtraEmbedder", "description": "Discover embedded files on 4chan and archives!", - "version": "0.324", + "version": "0.326", "icons": { "64": "1449696017588.png" }, @@ -44,7 +44,8 @@ "https://b4k.co/*", "https://fireden.net/*", "https://thebarchive.com/*", - "https://archiveofsins.com/*" + "https://archiveofsins.com/*", + "https://kohlchan.net/*" ], "css": [], "run_at": "document_start", diff --git a/dist/main.js b/dist/main.js index 377496a..1d6cfbd 100644 --- a/dist/main.js +++ b/dist/main.js @@ -73,7 +73,7 @@ var define_BUILD_VERSION_default; var init_define_BUILD_VERSION = __esm({ ""() { - define_BUILD_VERSION_default = [0, 324]; + define_BUILD_VERSION_default = [0, 326]; } }); @@ -20243,9 +20243,35 @@ getCurrentBoard: V4chan.getCurrentBoard, getCurrentThread: V4chan.getCurrentThread }; + var KChan = { + getFileThumbnail: (post) => post.querySelector("figure.uploadCell"), + getPost: (post) => post.querySelector(".innerPost"), + postsWithFiles: (h) => [...(h || document).querySelectorAll(".postCell:has(figure)")], + settingsHost: () => document.getElementById("navOptionsSpanThread"), + catalogControlHost: () => document.getElementById("divTools"), + getImageLink: async function* (post) { + yield post.querySelector('a[target="_blank"]')?.getAttribute("href") || ""; + }, + getFilename: (post) => { + const a = post.querySelector(".imgLink > img"); + if (a && a.title) + return a.title; + return a?.textContent || ""; + }, + getMD5: (post) => "", + getThumbnailLink: (post) => post.querySelector(".imgLink > img")?.getAttribute("src") || "", + getInfoBox: (post) => post.querySelector("div.uploadDetails"), + getPostIdPrefix: () => "", + getTextBox: (post) => post.querySelector(".divMessage"), + getCurrentBoard: () => location.pathname.split("/")[1], + getCurrentThread: () => +location.pathname.split("/")[3] + }; var getQueryProcessor = (is4chanX) => { if (["boards.4chan.org", "boards.4channel.org"].includes(location.host)) return is4chanX ? X4chan : V4chan; + if (location.host == "kohlchan.net") { + return KChan; + } if (document.querySelector('meta[name="generator"]')?.getAttribute("content")?.startsWith("FoolFuuka")) return FoolFuuka; }; diff --git a/main.d.ts b/main.d.ts index db5b92a..5415eb8 100644 --- a/main.d.ts +++ b/main.d.ts @@ -142,7 +142,7 @@ declare const QR: any; declare const BUILD_VERSION: [number, number]; declare const execution_mode: 'userscript' | 'chrome_api' | 'ff_api' | 'worker'; declare const isBackground: boolean; -declare const chrome: typeof browser; +declare const chrome: typeof browser & {declarativeNetRequest: any}; declare const _DOMParser: typeof DOMParser; declare const manifest: 2 | 3; declare function GM_addElement(parent: HTMLElement, tagname: string, attrs: Record); diff --git a/src/Components/NotificationsHandler.svelte b/src/Components/NotificationsHandler.svelte index f121a6e..e94a9f5 100644 --- a/src/Components/NotificationsHandler.svelte +++ b/src/Components/NotificationsHandler.svelte @@ -1,25 +1,25 @@
@@ -33,7 +33,6 @@