Browse Source

Merge branch 'main' into 中出し

pull/46/head
coomdev 2 years ago
parent
commit
301585f9dc
  1. 18
      .gitignore
  2. BIN
      PEE-chrome.crx
  3. 21
      README.md
  4. 34
      build-chrome.js
  5. 4
      build-ff.js
  6. 1544
      chrome/b4k/board.js
  7. 6
      chrome/b4k/bootstrap.min.js
  8. 660
      chrome/b4k/fuuka.js
  9. 16645
      chrome/b4k/highlight.pack.js
  10. 180
      chrome/b4k/lazyload.js
  11. 246
      chrome/b4k/plugins.js
  12. 9
      chrome/manifest.json
  13. 2
      chrome_update.xml
  14. 1544
      firefox/b4k/board.js
  15. 6
      firefox/b4k/bootstrap.min.js
  16. 660
      firefox/b4k/fuuka.js
  17. 16645
      firefox/b4k/highlight.pack.js
  18. 180
      firefox/b4k/lazyload.js
  19. 246
      firefox/b4k/plugins.js
  20. 4
      firefox/manifest.json
  21. 2
      firefox_update.json
  22. 3
      main.meta.js
  23. 15049
      main.user.js
  24. BIN
      pngextraembedder-0.213-an+fx.xpi
  25. BIN
      pngextraembedder-0.222-an+fx.xpi
  26. 2
      src/Components/PostOptions.svelte
  27. 8
      src/main.ts
  28. 8
      src/pngv3.ts
  29. 7
      src/utils.ts
  30. 2
      src/websites/index.ts

18
.gitignore

@ -20,3 +20,21 @@ rollup.config.js
.vscode/settings.json
key.pem
chrome.pem
1641560780544.png
1642033228102.png
a.png
converted.png
cuck.png
dd.png
f106d2459fc348494ae39e33c0905e885f3fe6b4ae7d1f8dc171ad85b94132b1.png
file.png
index.html
localstorage.html
out.png
rtlt7x.png
test.png
chrome/1449696017588.png
firefox/1449696017588.png
rev/index.html
rev/out.png
1641737123922.png

BIN
PEE-chrome.crx

Binary file not shown.

21
README.md

@ -1,8 +1,6 @@
PNG Extra Embedder (PEE)
PNGExtraEmbedder (PEE)
========================
*Subsequently 'lolipiss' (**LOL** **I** **p**Want **i**To **s**Kill **s**Jannies)*
Can embed any file in a PNG/WebM/GIF 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.
@ -27,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.
- [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/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.213-an+fx.xpi) or [Chrome-based](https://chrome.google.com/webstore/detail/pngextraembedder/bfhpobiikighljcapcfmfganodihbicj))
- Install the correct WebExtension for your Browser ([Firefox](https://git.coom.tech/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pngextraembedder-0.222-an+fx.xpi) or [Chrome-based](https://chrome.google.com/webstore/detail/pngextraembedder/bfhpobiikighljcapcfmfganodihbicj))
For FF users, the extension is signed so you can just drag and drop it on your about:addons tab.
@ -38,8 +36,11 @@ How to Build
(You only need to care about this section if you're auditing the code or contributing to development)
`npm i` and `npm run build`
then install the generated main.user.js
`npm i` and
`npm run build` to build the userscript version.
`npm run build_chrome` to build the chromium webextension.
`npm run build_ff` to build the firefox webextension. (You'll have to do the signing yourself, though)
How to use
==========
@ -70,11 +71,11 @@ The "Contribute" checkbox makes your browser report posts with embeds you come a
## [NEW] b4k
b4k is a meanie, i disabled lazyloading of thumbnails, heck you person of african american descent.
b4k is a meanie, i disabled lazyloading of thumbnails, heck.
**ACK!**
If you want to use b4k, you will get warning prompts. I added a ton of warning screen so it shouldn't happen to you.
If you want to use b4k, you will get warning prompts. I added a ton of warning screens so it shouldn't happen to you.
Switch to the beta and enable this setting. If you're using TamperMonkey, it has something similar called "Instant Injection"
![ack](spm.png)
@ -106,13 +107,13 @@ The file-type detection package is huge as it detect many file types, but also d
## How do I know it's not a botnet???
You're free to audit the code. You don't have to audit the 18000 loc file, you just need to audit the 2000-something lines of typescript code in the `src` folder, build it as instructed, and compare it to the one distributed. If you're incapable of doing that, chances are you're already using unauditable extensions with backdoors anyway? dumb schizoposter.
You're free to audit the code. You don't have to audit the 22000 loc file, you just need to audit the 3000-something lines of typescript code in the `src` folder, build it as instructed, and compare it to the one distributed.
## But embedding is a bannable offense!!!11
Yeah, well use at your own risk, you double baka.
While it is true PEE used to allow you to embed complete files in your uploads, recent changes have made it much less practical (limited to really small files), so it's falling back to linking external content hosted on pomf-clones such as catbox.
While it is true PEE used to allow you to embed complete files in your uploads, recent changes to 4chans have made it much less practical (limited to really small files), so it's falling back to linking external content hosted on pomf-clones such as catbox.
Links are much smaller and as some PNG editing software injects their own metadata, 4chan is basically required to allow some little amount of it to go through, lest they inconvenience a lot of their users, so a link-embedding detection method cannot be generalized, meaning they rely on unpaid janny labor to moderate this kind of content.

34
build-chrome.js

@ -6,14 +6,14 @@ import { writeFileSync, readFileSync, copyFileSync } from 'fs'
import esbuild from "esbuild";
import esbuildSvelte from "esbuild-svelte";
import sveltePreprocess from "svelte-preprocess";
import path from 'path';
//import path from 'path';
import ChromeExtension from 'crx';
//import ChromeExtension from 'crx';
const crx = new ChromeExtension({
codebase: 'https://git.coom.tech/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/PEE-chrome.crx',
privateKey: readFileSync('./key.pem')
});
//const crx = new ChromeExtension({
// codebase: 'https://github.com/coomdev/pngextraembedder/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/PEE-chrome.crx',
// privateKey: readFileSync('./key.pem')
//});
let res = spawnSync("git", ["rev-list", "--count", "HEAD"]);
let rev = +res.stdout;
@ -58,7 +58,7 @@ const domains = [
const manif = {
"manifest_version": 2,
"update_url": "https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/chrome_update.xml",
// "update_url": "https://github.com/coomdev/pngextraembedder/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/chrome_update.xml",
"name": "PngExtraEmbedder",
"description": "Discover embedded files on 4chan and archives!",
"version": "0." + rev,
@ -95,7 +95,7 @@ const manif = {
const manif3 = {
"manifest_version": 3,
"update_url": "https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/chrome_update.xml",
// "update_url": "https://github.com/coomdev/pngextraembedder/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/chrome_update.xml",
"name": "PngExtraEmbedder",
"description": "Discover embedded files on 4chan and archives!",
"version": "0." + rev,
@ -103,11 +103,11 @@ const manif3 = {
"64": "1449696017588.png"
},
"permissions": [
"notifications",
"clipboardWrite",
"activeTab",
//"notifications",
//"clipboardWrite",
//"activeTab",
"declarativeNetRequestWithHostAccess",
"contextMenus",
//"contextMenus",
],
host_permissions: domains,
//"host_permissions":["<all_urls>"],
@ -195,9 +195,9 @@ const manif3 = {
writeFileSync('./chrome/manifest.json', JSON.stringify(lmanif, null, 2));
copyFileSync("./logo.png", "./chrome/1449696017588.png");
const ext = await crx.load('./chrome');
const crxBuffer = await ext.pack();
const updateXML = crx.generateUpdateXML();
writeFileSync('./chrome_update.xml', updateXML);
writeFileSync('./PEE-chrome.crx', crxBuffer);
//const ext = await crx.load('./chrome');
//const crxBuffer = await ext.pack();
//const updateXML = crx.generateUpdateXML();
//writeFileSync('./chrome_update.xml', updateXML);
//writeFileSync('./PEE-chrome.crx', crxBuffer);
})();

4
build-ff.js

@ -54,7 +54,7 @@ const manif = {
"manifest_version": 2,
"browser_specific_settings": {
"gecko": {
"update_url": "https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/firefox_update.json",
"update_url": "https://github.com/coomdev/pngextraembedder/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/firefox_update.json",
}
},
"name": "PngExtraEmbedder",
@ -161,7 +161,7 @@ const manif = {
"updates": [
{
"version": manif.version,
"update_link": "https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pee-firefox.zip",
"update_link": "https://github.com/coomdev/pngextraembedder/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/pee-firefox.zip",
}
]
}

1544
chrome/b4k/board.js

File diff suppressed because it is too large

6
chrome/b4k/bootstrap.min.js

File diff suppressed because one or more lines are too long

660
chrome/b4k/fuuka.js

@ -0,0 +1,660 @@
var b4kFuuka = new function () {
var _this = this;
this.props = {};
this.main = function () {
for (var idx in _this.modules) {
try {
_this.modules[idx] = new _this.modules[idx];
} catch (error) {
console.error(error);
}
}
};
this.runOnAll = function (func) {
func(document.body);
document.addEventListener(
"DOMNodeInserted",
function (event) {
if (
event.target &&
event.target.nodeType === Node.ELEMENT_NODE
) {
func(event.target);
}
}
);
};
this.modules = {
setRootClasses: function () {
document.documentElement.classList.add("foolfuuka");
document.documentElement.classList.add("javascript");
document.documentElement.classList.add(navigator.userAgent.match(/Mobi/) ? "mobile" : "desktop");
},
setThisProps: function () {
_this.props.vars = (window.backend_vars ? window.backend_vars : {});
_this.props.asAdmin = (document.querySelector("a[href$=\"/admin/\"]") !== null);
_this.props.isInBoard = (_this.props.vars.board_shortname != null);
_this.props.isInThread = (_this.props.vars.thread_id != null);
_this.props.isInSearch = (window.location.pathname.match(/^\/(.+?)\/search\//) !== null);
_this.props.isInReport = (window.location.pathname.match(/^\/(.+?)\/reports\//) !== null);
_this.props.isInPostView = (_this.props.isInBoard || _this.props.isInSearch || _this.props.isInReport);
_this.props.boardNameShort = (_this.props.isInBoard ? _this.props.vars.board_shortname : null);
_this.props.boardIsArchive = (_this.props.isInBoard ? (document.querySelector("input[name=\"file_image\"]") === null) : null);
_this.props.curThreadNumber = (_this.props.isInThread ? parseInt(_this.props.vars.thread_id) : null);
},
setBodyAttribs: function () {
if (_this.props.asAdmin) {
document.body.classList.add("as-admin");
}
if (_this.props.isInBoard) {
document.body.classList.add("is-board");
document.body.classList.add(_this.props.boardIsArchive ? "is-board-archive" : "is-board-normal");
document.body.classList.add("board-" + _this.props.boardNameShort);
}
if (_this.props.isInSearch) {
document.body.classList.add("is-search");
}
if (_this.props.isInPostView) {
document.body.classList.add("is-post-view");
}
},
setPostDatasets: function () {
_this.runOnAll(function (target) {
target.querySelectorAll("article.thread, article.post")
.forEach(
function (post) {
var postHeader;
var postBoardShow;
var postPosterName;
var postPosterTrip;
var postPosterLevel;
if (
_this.props.isInSearch &&
post.classList.contains("thread")
) {
return;
}
post.dataset.board = _this.props.boardNameShort;
post.dataset.number = post.id;
if (post.parentElement.id === "backlink") {
post.dataset.board = "";
}
postHeader = post.querySelector("header");
if (postHeader) {
postBoardShow = postHeader.querySelector(".post_show_board");
if (postBoardShow && postBoardShow.textContent) {
post.dataset.board = postBoardShow.textContent.replace(/\//g, "");
}
postPosterName = postHeader.querySelector(".post_author");
postPosterTrip = postHeader.querySelector(".post_tripcode");
postPosterLevel = postHeader.querySelector(".post_level");
if (postPosterName && postPosterName.textContent) { post.dataset.posterName = postPosterName.textContent; }
if (postPosterTrip && postPosterTrip.textContent) { post.dataset.posterTrip = postPosterTrip.textContent; }
if (postPosterLevel && postPosterLevel.textContent) { post.dataset.posterLevel = postPosterLevel.className.match(/\bpost_level_(.+)\b/)[1]; }
}
}
);
});
},
stopFontBoosting: function () {
if (navigator.userAgent.match(/Android/)) {
document.documentElement.classList.add("disable-font-boosting");
}
},
addThumbLazyLoad: function () {
var options;
options = {
src: "data-src",
srcset: "data-srcset",
selector: "img.lazyload",
root: null,
rootMargin: "5000px",
threshold: 0
}
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
window.lazyload(
target.querySelectorAll("img.lazyload"),
options
);
}
);
}
},
addPostIconText: function () {
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
target.querySelectorAll(".post_type > i")
.forEach(
function (item) {
var elem1;
var elem2;
var elem3;
elem1 = document.createElement("span");
elem1.title = item.title;
elem2 = document.createElement("span");
elem2.style.position = "relative";
elem2.style.top = "-1px";
elem2.style.marginLeft = "2px";
elem2.style.fontSize = "0.8em";
elem2.style.opacity = (document.body.classList.contains("midnight") ? "0.6" : null);
elem2.textContent =
(function () {
switch (item.classList[0]) {
case "icon-trash": return "Deleted";
case "icon-eye-close": return "Spoiler";
case "icon-pushpin": return "Sticky";
case "icon-lock": return "Locked";
case "icon-comment-alt": return "Ghost";
default: return "???";
}
})();
if (item.classList[0] === "icon-tag") {
item.style.display = "none";
return;
}
elem3 = item.cloneNode();
elem3.removeAttribute("title");
elem1.appendChild(elem3);
elem1.appendChild(elem2);
item.parentElement.replaceChild(elem1, item);
}
);
}
);
}
},
setCapcodeColors: function () {
if (_this.props.isInPostView) {
_this.runOnAll(function (target) {
var capcodeName;
var capcodeColor;
target.querySelectorAll(".post_poster_data .post_level")
.forEach(
function (capcode) {
capcodeName = capcode.className.match(/\bpost_level_(.+)\b/)[1];
capcodeColor = window.getComputedStyle(capcode).color;
if (_this.props.isInBoard && !_this.props.boardIsArchive) {
if (capcodeName === "administrator") capcodeColor = "#FF6C34";
}
if (document.body.classList.contains("midnight")) {
if (capcodeName === "moderator") capcodeColor = "#B200B2";
if (capcodeName === "developer") capcodeColor = "#0078FF";
}
capcode.parentElement.querySelectorAll("*")
.forEach(
function (item) {
item.style.color = capcodeColor;
}
);
if (_this.props.isInBoard) {
capcode.title = ("This user is " + (_this.props.boardIsArchive ? "a 4chan" : "an arch.b4k.co") + " " + capcodeName.toLowerCase() + ".");
}
}
);
});
}
},
setBannedMessages: function () {
return; // current version of foolfuuka has this built in
if (_this.props.isInPostView) {
_this.runOnAll(function (target) {
var match;
var bannu;
target.querySelectorAll("article .text")
.forEach(
function (comment) {
comment.childNodes.forEach(
function (node) {
if (node.textContent.includes("[banned]")) {
match = node.textContent.trim().match(/^\[banned\](.+)\[\/banned\]$/);
if (match) {
bannu = document.createElement("span");
bannu.className = "banned";
bannu.textContent = match[1];
node.parentNode.replaceChild(bannu, node);
}
}
}
);
}
);
});
}
},
addReportFormNote: function () {
if (_this.props.isInPostView) {
window.setInterval(
function () {
var dialogOuter;
var dialogInner;
dialogOuter = document.querySelector("#post_tools_modal.in");
if (
dialogOuter &&
dialogOuter.querySelector(".title").textContent.match(/^Report/)
) {
dialogInner = dialogOuter.querySelector(".model-note")
if (
dialogInner &&
dialogInner.classList.contains("edited") == false
) {
if (_this.props.isInBoard && !_this.props.boardIsArchive) {
dialogInner.innerHTML = "Posts should only be reported for reasons listed in the board rules.";
} else {
dialogInner.innerHTML = "Posts should only be reported for reasons listed in the <a href=\"/_/articles/info/\" target=\"_blank\">FAQ</a>.<br>Remember: This is not 4chan, so 4chan's rules do not apply here.";
}
dialogInner.classList.add("edited");
}
}
},
(200)
);
}
},
stopThreadUpdater: function () {
if (_this.props.isInBoard && _this.props.boardIsArchive) {
Object.defineProperty(
window,
"enableRealtimeThread",
{
value: function () { },
writable: false
}
);
}
},
fixSauceLinks: function () {
if (_this.props.isInPostView) {
_this.runOnAll(function (target) {
target.querySelectorAll(".post_file_controls > a")
.forEach(
function (sauce) {
if (sauce.protocol === "http:") sauce.protocol = "https:";
if (sauce.host === "google.com") sauce.host = "www.google.com";
}
);
});
}
},
fixBacklinkHash: function () {
var linkPost;
var linkBoard;
var linkNumber;
if (_this.props.isInThread) {
_this.runOnAll(function (target) {
target.querySelectorAll("article a.backlink")
.forEach(
function (link) {
linkBoard = link.dataset.board;
linkNumber = link.dataset.post;
if (
linkBoard &&
linkNumber &&
linkBoard === _this.props.boardNameShort
) {
linkPost = document.querySelector("article[id=\"" + linkNumber + "\"]");
if (
linkPost !== null &&
linkPost.dataset.board == linkBoard &&
linkPost.dataset.number == linkNumber
) {
link.href = ("#" + linkNumber);
}
}
}
);
});
}
},
fixMoonRuneFont: function () {
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
target.querySelectorAll(".text.shift-jis")
.forEach(
function (item) {
item.classList.remove("shift-jis");
}
);
}
);
}
},
addThreadComments: function () {
if(!window.localStorage.getItem("wtf")) return;
var topicBoard;
var topicNumber;
var controls;
var comThread;
var comScript;
if (window.localStorage.getItem("comments") == null) {
window.localStorage.setItem("comments", "1");
}
if (_this.props.isInThread) {
topicBoard = _this.props.boardNameShort;
topicNumber = _this.props.curThreadNumber;
if (topicBoard && topicNumber) {
window.disqus_config =
function () {
this.page.url = (_this.props.vars.default_url + topicBoard + "/thread/" + topicNumber + "/");
this.page.identifier = [window.location.hostname, "topic", topicBoard, topicNumber].join("/");
this.page.title = ("Topic /" + topicBoard + "/" + topicNumber);
};
controls = document.createElement("li");
controls.appendChild(document.createElement("label"));
controls.children[0].style.cursor = "pointer";
controls.children[0].style.padding = "11px 10px";
controls.children[0].style.paddingLeft = "30px";
controls.children[0].style.marginBottom = "0";
controls.children[0].style.color = "0";
controls.children[0].appendChild(document.createElement("input"));
controls.children[0].appendChild(document.createTextNode("Enable Thread Comments"));
controls.children[0].children[0].type = "checkbox";
controls.children[0].children[0].checked = false;
controls.children[0].children[0].style.marginTop = "-1px";
controls.children[0].children[0].style.marginRight = "5px";
/*comThread = document.createElement("div");
comThread.id = "disqus_thread";
comThread.style.display = "none";
comThread.style.marginTop = "20px";
comThread.style.marginBottom = "3px";
comThread.style.paddingLeft = "30px";
comThread.style.paddingRight = "30px";
comScript = document.createElement("script");
comScript.src = "https://arch-b4k-co.disqus.com/embed.js";
comScript.setAttribute("data-timestamp", (+new Date()));*/
comThread = document.createElement("div");
comThread.id = "commento";
comThread.style.display = "none";
comThread.style.marginTop = "20px";
comThread.style.marginBottom = "3px";
comScript = document.createElement("script");
comScript.src = "https://commento.b4k.co/js/commento.js";
comScript.setAttribute("data-page", ("/" + topicBoard + "/thread/" + topicNumber + "/"));
if (window.localStorage.getItem("comments") === "1") {
controls.children[0].children[0].checked = true;
comThread.style.display = "";
}
document.querySelectorAll("ul.nav")[1].appendChild(controls);
document.querySelector("article.thread").appendChild(comThread);
controls.children[0].style.color =
window.getComputedStyle(controls.previousElementSibling.children[0]).color;
if (window.localStorage.getItem("comments") === "1") {
document.querySelector("head").appendChild(comScript);
}
controls.querySelector("input")
.addEventListener(
"change",
function (event) {
window.localStorage.setItem("comments", (event.target.checked ? "1" : "0"));
disThread.style.display = (event.target.checked ? "" : "none");
if (event.target.checked) {
if (comScript.parentElement == null) {
document.querySelector("head").appendChild(comScript);
}
}
}
);
}
}
},
fixScriptErrors: function () {
var hash;
var temp;
hash = location.href.split(/#/)[1];
hash = (hash != null ? hash : "");
hash = hash.replace("q", "");
if (hash) {
if (document.getElementById(hash) == null) {
temp = document.createElement("span");
temp.id = hash;
temp.hidden = true;
temp.style.position = "absolute";
temp.style.top = "0";
temp.style.left = "0";
document.body.appendChild(temp);
}
}
},
hidePostButtons: function () {
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
target.querySelectorAll(".post_controls > a.btnr")
.forEach(
function (item) {
if (item.textContent === "Delete") item.hidden = true;
if (item.textContent === "Reply" && _this.props.boardIsArchive == true) item.hidden = true;
if (item.textContent === "Original" && _this.props.boardIsArchive == false) item.hidden = true;
}
);
}
);
}
},
doSearchRedirect: function () {
return; // this belongs in a userscript instead
if (
_this.props.isInSearch &&
document.querySelector("article.post") === null &&
document.querySelector("meta[http-equiv]") === null
) {
switch (_this.props.boardNameShort) {
default: break;
case "mlp": window.location.hostname = "desuarchive.org"; break;
}
}
},
stopLinkReferrers: function () {
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
target.querySelectorAll(".text a[target=\"_blank\"]")
.forEach(
function (item) {
item.referrerPolicy = "same-origin";
}
);
}
);
}
},
addSearchLimitationNote: function () {
return;
var tmp1;
var tmp2;
if (_this.props.isInSearch) {
tmp1 = document.querySelector("#main > h3.section_title");
if (tmp1) {
tmp2 = document.createElement("small");
tmp2.style = "margin-left: 10px";
tmp2.textContent = "Note: /v/ search goes back 1 year, /vg/ goes back 3 months.";
tmp1.appendChild(document.createTextNode(" "));
tmp1.appendChild(tmp2);
}
}
},
changeLastFiftyToHundred: function() {
// thread buttons
document.querySelectorAll(".post_controls > a.btnr")
.forEach(
function (item) {
if (item.textContent === "Last 50") {
item.textContent = "Last 100";
item.href = item.getAttribute("href").replace("/last/50/", "/last/100/");
}
}
);
// thread too big alert
document.querySelectorAll(".alert > a")
.forEach(
function (item) {
if (item.textContent === "view last 50 posts") {
item.textContent = "view last 100 posts";
item.href = item.getAttribute("href").replace("/last/50/", "/last/100/");
}
}
);
},
searchThreadStats: function() {
var topics;
var query;
var tmp1;
var tmp2;
if (_this.props.isInSearch) {
topics = [];
document.querySelectorAll("article.post.post_is_op")
.forEach(
function (item) {
topics.push({
"element": item,
"board": item.dataset.board,
"number": item.dataset.number
})
}
);
if (topics.length > 0) {
query = "";
topics.forEach(
function (item) {
query = (query + (query.length > 0 ? "," : "") + item.board + "." + item.number);
}
);
jQuery.ajax({
url: "https://b4k.co/4chan-arch-api.php",
method: "get",
dataType: "json",
data: {
"act": "replies",
"topics": query
},
success: function (data, textStatus, jqXHR) {
if (data) {
data.forEach(
function (item1) {
topics.forEach(
function (item2) {
if (
item1.board == item2.board,
item1.number == item2.number
) {
tmp1 = item2.element.querySelector(".post_file");
if (tmp1) {
tmp2 = document.createElement("span");
tmp2.textContent = ("Replies: " + (item1.cnt_reply - 1));
tmp2.style.marginLeft = "7px";
tmp1.appendChild(tmp2);
}
}
}
);
}
);
}
}
});
}
}
}
};
};

16645
chrome/b4k/highlight.pack.js

File diff suppressed because one or more lines are too long

180
chrome/b4k/lazyload.js

@ -0,0 +1,180 @@
/*!
* Lazy Load - JavaScript plugin for lazy loading images
*
* Copyright (c) 2007-2019 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* https://appelsiini.net/projects/lazyload
*
* Version: 2.0.0-rc.2
*
*/
(function (root, factory) {
if (typeof exports === "object") {
module.exports = factory(root);
} else if (typeof define === "function" && define.amd) {
define([], factory);
} else {
root.LazyLoad = factory(root);
}
}) (typeof global !== "undefined" ? global : this.window || this.global, function (root) {
"use strict";
if (typeof define === "function" && define.amd){
root = window;
}
const defaults = {
src: "data-src",
srcset: "data-srcset",
selector: ".lazyload",
root: null,
rootMargin: "0px",
threshold: 0
};
/**
* Merge two or more objects. Returns a new object.
* @private
* @param {Boolean} deep If true, do a deep (or recursive) merge [optional]
* @param {Object} objects The objects to merge together
* @returns {Object} Merged values of defaults and options
*/
const extend = function () {
let extended = {};
let deep = false;
let i = 0;
let length = arguments.length;
/* Check if a deep merge */
if (Object.prototype.toString.call(arguments[0]) === "[object Boolean]") {
deep = arguments[0];
i++;
}
/* Merge the object into the extended object */
let merge = function (obj) {
for (let prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
/* If deep merge and property is an object, merge properties */
if (deep && Object.prototype.toString.call(obj[prop]) === "[object Object]") {
extended[prop] = extend(true, extended[prop], obj[prop]);
} else {
extended[prop] = obj[prop];
}
}
}
};
/* Loop through each object and conduct a merge */
for (; i < length; i++) {
let obj = arguments[i];
merge(obj);
}
return extended;
};
function LazyLoad(images, options) {
this.settings = extend(defaults, options || {});
this.images = images || document.querySelectorAll(this.settings.selector);
this.observer = null;
this.init();
}
LazyLoad.prototype = {
init: function() {
/* Without observers load everything and bail out early. */
if (!root.IntersectionObserver) {
this.loadImages();
return;
}
let self = this;
let observerConfig = {
root: this.settings.root,
rootMargin: this.settings.rootMargin,
threshold: [this.settings.threshold]
};
this.observer = new IntersectionObserver(function(entries) {
Array.prototype.forEach.call(entries, function (entry) {
if (entry.isIntersecting) {
self.observer.unobserve(entry.target);
let src = entry.target.getAttribute(self.settings.src);
let srcset = entry.target.getAttribute(self.settings.srcset);
if ("img" === entry.target.tagName.toLowerCase()) {
if (src) {
entry.target.src = src;
}
if (srcset) {
entry.target.srcset = srcset;
}
} else {
entry.target.style.backgroundImage = "url(" + src + ")";
}
}
});
}, observerConfig);
Array.prototype.forEach.call(this.images, function (image) {
self.observer.observe(image);
});
},
loadAndDestroy: function () {
if (!this.settings) { return; }
this.loadImages();
this.destroy();
},
loadImages: function () {
if (!this.settings) { return; }
let self = this;
Array.prototype.forEach.call(this.images, function (image) {
let src = image.getAttribute(self.settings.src);
let srcset = image.getAttribute(self.settings.srcset);
if ("img" === image.tagName.toLowerCase()) {
if (src) {
image.src = src;
}
if (srcset) {
image.srcset = srcset;
}
} else {
image.style.backgroundImage = "url('" + src + "')";
}
});
},
destroy: function () {
if (!this.settings) { return; }
this.observer.disconnect();
this.settings = null;
}
};
root.lazyload = function(images, options) {
return new LazyLoad(images, options);
};
if (root.jQuery) {
const $ = root.jQuery;
$.fn.lazyload = function (options) {
options = options || {};
options.attribute = options.attribute || "data-src";
new LazyLoad($.makeArray(this), options);
return this;
};
}
return LazyLoad;
});

246
chrome/b4k/plugins.js

File diff suppressed because one or more lines are too long

9
chrome/manifest.json

@ -1,18 +1,13 @@
{
"manifest_version": 3,
"update_url": "https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/chrome_update.xml",
"name": "PngExtraEmbedder",
"description": "Discover embedded files on 4chan and archives!",
"version": "0.213",
"version": "0.222",
"icons": {
"64": "1449696017588.png"
},
"permissions": [
"notifications",
"clipboardWrite",
"activeTab",
"declarativeNetRequestWithHostAccess",
"contextMenus"
"declarativeNetRequestWithHostAccess"
],
"host_permissions": [
"https://*.coom.tech/*",

2
chrome_update.xml

@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<app appid='ilffidhdekahjldemialkgahicnajchb'>
<updatecheck codebase='https://git.coom.tech/coomdev/PEE/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/PEE-chrome.crx' version='0.213' prodversionmin='64.0.3242' />
<updatecheck codebase='https://github.com/coomdev/pngextraembedder/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/PEE-chrome.crx' version='0.220' prodversionmin='64.0.3242' />
</app>
</gupdate>

1544
firefox/b4k/board.js

File diff suppressed because it is too large

6
firefox/b4k/bootstrap.min.js

File diff suppressed because one or more lines are too long

660
firefox/b4k/fuuka.js

@ -0,0 +1,660 @@
var b4kFuuka = new function () {
var _this = this;
this.props = {};
this.main = function () {
for (var idx in _this.modules) {
try {
_this.modules[idx] = new _this.modules[idx];
} catch (error) {
console.error(error);
}
}
};
this.runOnAll = function (func) {
func(document.body);
document.addEventListener(
"DOMNodeInserted",
function (event) {
if (
event.target &&
event.target.nodeType === Node.ELEMENT_NODE
) {
func(event.target);
}
}
);
};
this.modules = {
setRootClasses: function () {
document.documentElement.classList.add("foolfuuka");
document.documentElement.classList.add("javascript");
document.documentElement.classList.add(navigator.userAgent.match(/Mobi/) ? "mobile" : "desktop");
},
setThisProps: function () {
_this.props.vars = (window.backend_vars ? window.backend_vars : {});
_this.props.asAdmin = (document.querySelector("a[href$=\"/admin/\"]") !== null);
_this.props.isInBoard = (_this.props.vars.board_shortname != null);
_this.props.isInThread = (_this.props.vars.thread_id != null);
_this.props.isInSearch = (window.location.pathname.match(/^\/(.+?)\/search\//) !== null);
_this.props.isInReport = (window.location.pathname.match(/^\/(.+?)\/reports\//) !== null);
_this.props.isInPostView = (_this.props.isInBoard || _this.props.isInSearch || _this.props.isInReport);
_this.props.boardNameShort = (_this.props.isInBoard ? _this.props.vars.board_shortname : null);
_this.props.boardIsArchive = (_this.props.isInBoard ? (document.querySelector("input[name=\"file_image\"]") === null) : null);
_this.props.curThreadNumber = (_this.props.isInThread ? parseInt(_this.props.vars.thread_id) : null);
},
setBodyAttribs: function () {
if (_this.props.asAdmin) {
document.body.classList.add("as-admin");
}
if (_this.props.isInBoard) {
document.body.classList.add("is-board");
document.body.classList.add(_this.props.boardIsArchive ? "is-board-archive" : "is-board-normal");
document.body.classList.add("board-" + _this.props.boardNameShort);
}
if (_this.props.isInSearch) {
document.body.classList.add("is-search");
}
if (_this.props.isInPostView) {
document.body.classList.add("is-post-view");
}
},
setPostDatasets: function () {
_this.runOnAll(function (target) {
target.querySelectorAll("article.thread, article.post")
.forEach(
function (post) {
var postHeader;
var postBoardShow;
var postPosterName;
var postPosterTrip;
var postPosterLevel;
if (
_this.props.isInSearch &&
post.classList.contains("thread")
) {
return;
}
post.dataset.board = _this.props.boardNameShort;
post.dataset.number = post.id;
if (post.parentElement.id === "backlink") {
post.dataset.board = "";
}
postHeader = post.querySelector("header");
if (postHeader) {
postBoardShow = postHeader.querySelector(".post_show_board");
if (postBoardShow && postBoardShow.textContent) {
post.dataset.board = postBoardShow.textContent.replace(/\//g, "");
}
postPosterName = postHeader.querySelector(".post_author");
postPosterTrip = postHeader.querySelector(".post_tripcode");
postPosterLevel = postHeader.querySelector(".post_level");
if (postPosterName && postPosterName.textContent) { post.dataset.posterName = postPosterName.textContent; }
if (postPosterTrip && postPosterTrip.textContent) { post.dataset.posterTrip = postPosterTrip.textContent; }
if (postPosterLevel && postPosterLevel.textContent) { post.dataset.posterLevel = postPosterLevel.className.match(/\bpost_level_(.+)\b/)[1]; }
}
}
);
});
},
stopFontBoosting: function () {
if (navigator.userAgent.match(/Android/)) {
document.documentElement.classList.add("disable-font-boosting");
}
},
addThumbLazyLoad: function () {
var options;
options = {
src: "data-src",
srcset: "data-srcset",
selector: "img.lazyload",
root: null,
rootMargin: "5000px",
threshold: 0
}
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
window.lazyload(
target.querySelectorAll("img.lazyload"),
options
);
}
);
}
},
addPostIconText: function () {
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
target.querySelectorAll(".post_type > i")
.forEach(
function (item) {
var elem1;
var elem2;
var elem3;
elem1 = document.createElement("span");
elem1.title = item.title;
elem2 = document.createElement("span");
elem2.style.position = "relative";
elem2.style.top = "-1px";
elem2.style.marginLeft = "2px";
elem2.style.fontSize = "0.8em";
elem2.style.opacity = (document.body.classList.contains("midnight") ? "0.6" : null);
elem2.textContent =
(function () {
switch (item.classList[0]) {
case "icon-trash": return "Deleted";
case "icon-eye-close": return "Spoiler";
case "icon-pushpin": return "Sticky";
case "icon-lock": return "Locked";
case "icon-comment-alt": return "Ghost";
default: return "???";
}
})();
if (item.classList[0] === "icon-tag") {
item.style.display = "none";
return;
}
elem3 = item.cloneNode();
elem3.removeAttribute("title");
elem1.appendChild(elem3);
elem1.appendChild(elem2);
item.parentElement.replaceChild(elem1, item);
}
);
}
);
}
},
setCapcodeColors: function () {
if (_this.props.isInPostView) {
_this.runOnAll(function (target) {
var capcodeName;
var capcodeColor;
target.querySelectorAll(".post_poster_data .post_level")
.forEach(
function (capcode) {
capcodeName = capcode.className.match(/\bpost_level_(.+)\b/)[1];
capcodeColor = window.getComputedStyle(capcode).color;
if (_this.props.isInBoard && !_this.props.boardIsArchive) {
if (capcodeName === "administrator") capcodeColor = "#FF6C34";
}
if (document.body.classList.contains("midnight")) {
if (capcodeName === "moderator") capcodeColor = "#B200B2";
if (capcodeName === "developer") capcodeColor = "#0078FF";
}
capcode.parentElement.querySelectorAll("*")
.forEach(
function (item) {
item.style.color = capcodeColor;
}
);
if (_this.props.isInBoard) {
capcode.title = ("This user is " + (_this.props.boardIsArchive ? "a 4chan" : "an arch.b4k.co") + " " + capcodeName.toLowerCase() + ".");
}
}
);
});
}
},
setBannedMessages: function () {
return; // current version of foolfuuka has this built in
if (_this.props.isInPostView) {
_this.runOnAll(function (target) {
var match;
var bannu;
target.querySelectorAll("article .text")
.forEach(
function (comment) {
comment.childNodes.forEach(
function (node) {
if (node.textContent.includes("[banned]")) {
match = node.textContent.trim().match(/^\[banned\](.+)\[\/banned\]$/);
if (match) {
bannu = document.createElement("span");
bannu.className = "banned";
bannu.textContent = match[1];
node.parentNode.replaceChild(bannu, node);
}
}
}
);
}
);
});
}
},
addReportFormNote: function () {
if (_this.props.isInPostView) {
window.setInterval(
function () {
var dialogOuter;
var dialogInner;
dialogOuter = document.querySelector("#post_tools_modal.in");
if (
dialogOuter &&
dialogOuter.querySelector(".title").textContent.match(/^Report/)
) {
dialogInner = dialogOuter.querySelector(".model-note")
if (
dialogInner &&
dialogInner.classList.contains("edited") == false
) {
if (_this.props.isInBoard && !_this.props.boardIsArchive) {
dialogInner.innerHTML = "Posts should only be reported for reasons listed in the board rules.";
} else {
dialogInner.innerHTML = "Posts should only be reported for reasons listed in the <a href=\"/_/articles/info/\" target=\"_blank\">FAQ</a>.<br>Remember: This is not 4chan, so 4chan's rules do not apply here.";
}
dialogInner.classList.add("edited");
}
}
},
(200)
);
}
},
stopThreadUpdater: function () {
if (_this.props.isInBoard && _this.props.boardIsArchive) {
Object.defineProperty(
window,
"enableRealtimeThread",
{
value: function () { },
writable: false
}
);
}
},
fixSauceLinks: function () {
if (_this.props.isInPostView) {
_this.runOnAll(function (target) {
target.querySelectorAll(".post_file_controls > a")
.forEach(
function (sauce) {
if (sauce.protocol === "http:") sauce.protocol = "https:";
if (sauce.host === "google.com") sauce.host = "www.google.com";
}
);
});
}
},
fixBacklinkHash: function () {
var linkPost;
var linkBoard;
var linkNumber;
if (_this.props.isInThread) {
_this.runOnAll(function (target) {
target.querySelectorAll("article a.backlink")
.forEach(
function (link) {
linkBoard = link.dataset.board;
linkNumber = link.dataset.post;
if (
linkBoard &&
linkNumber &&
linkBoard === _this.props.boardNameShort
) {
linkPost = document.querySelector("article[id=\"" + linkNumber + "\"]");
if (
linkPost !== null &&
linkPost.dataset.board == linkBoard &&
linkPost.dataset.number == linkNumber
) {
link.href = ("#" + linkNumber);
}
}
}
);
});
}
},
fixMoonRuneFont: function () {
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
target.querySelectorAll(".text.shift-jis")
.forEach(
function (item) {
item.classList.remove("shift-jis");
}
);
}
);
}
},
addThreadComments: function () {
if(!window.localStorage.getItem("wtf")) return;
var topicBoard;
var topicNumber;
var controls;
var comThread;
var comScript;
if (window.localStorage.getItem("comments") == null) {
window.localStorage.setItem("comments", "1");
}
if (_this.props.isInThread) {
topicBoard = _this.props.boardNameShort;
topicNumber = _this.props.curThreadNumber;
if (topicBoard && topicNumber) {
window.disqus_config =
function () {
this.page.url = (_this.props.vars.default_url + topicBoard + "/thread/" + topicNumber + "/");
this.page.identifier = [window.location.hostname, "topic", topicBoard, topicNumber].join("/");
this.page.title = ("Topic /" + topicBoard + "/" + topicNumber);
};
controls = document.createElement("li");
controls.appendChild(document.createElement("label"));
controls.children[0].style.cursor = "pointer";
controls.children[0].style.padding = "11px 10px";
controls.children[0].style.paddingLeft = "30px";
controls.children[0].style.marginBottom = "0";
controls.children[0].style.color = "0";
controls.children[0].appendChild(document.createElement("input"));
controls.children[0].appendChild(document.createTextNode("Enable Thread Comments"));
controls.children[0].children[0].type = "checkbox";
controls.children[0].children[0].checked = false;
controls.children[0].children[0].style.marginTop = "-1px";
controls.children[0].children[0].style.marginRight = "5px";
/*comThread = document.createElement("div");
comThread.id = "disqus_thread";
comThread.style.display = "none";
comThread.style.marginTop = "20px";
comThread.style.marginBottom = "3px";
comThread.style.paddingLeft = "30px";
comThread.style.paddingRight = "30px";
comScript = document.createElement("script");
comScript.src = "https://arch-b4k-co.disqus.com/embed.js";
comScript.setAttribute("data-timestamp", (+new Date()));*/
comThread = document.createElement("div");
comThread.id = "commento";
comThread.style.display = "none";
comThread.style.marginTop = "20px";
comThread.style.marginBottom = "3px";
comScript = document.createElement("script");
comScript.src = "https://commento.b4k.co/js/commento.js";
comScript.setAttribute("data-page", ("/" + topicBoard + "/thread/" + topicNumber + "/"));
if (window.localStorage.getItem("comments") === "1") {
controls.children[0].children[0].checked = true;
comThread.style.display = "";
}
document.querySelectorAll("ul.nav")[1].appendChild(controls);
document.querySelector("article.thread").appendChild(comThread);
controls.children[0].style.color =
window.getComputedStyle(controls.previousElementSibling.children[0]).color;
if (window.localStorage.getItem("comments") === "1") {
document.querySelector("head").appendChild(comScript);
}
controls.querySelector("input")
.addEventListener(
"change",
function (event) {
window.localStorage.setItem("comments", (event.target.checked ? "1" : "0"));
disThread.style.display = (event.target.checked ? "" : "none");
if (event.target.checked) {
if (comScript.parentElement == null) {
document.querySelector("head").appendChild(comScript);
}
}
}
);
}
}
},
fixScriptErrors: function () {
var hash;
var temp;
hash = location.href.split(/#/)[1];
hash = (hash != null ? hash : "");
hash = hash.replace("q", "");
if (hash) {
if (document.getElementById(hash) == null) {
temp = document.createElement("span");
temp.id = hash;
temp.hidden = true;
temp.style.position = "absolute";
temp.style.top = "0";
temp.style.left = "0";
document.body.appendChild(temp);
}
}
},
hidePostButtons: function () {
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
target.querySelectorAll(".post_controls > a.btnr")
.forEach(
function (item) {
if (item.textContent === "Delete") item.hidden = true;
if (item.textContent === "Reply" && _this.props.boardIsArchive == true) item.hidden = true;
if (item.textContent === "Original" && _this.props.boardIsArchive == false) item.hidden = true;
}
);
}
);
}
},
doSearchRedirect: function () {
return; // this belongs in a userscript instead
if (
_this.props.isInSearch &&
document.querySelector("article.post") === null &&
document.querySelector("meta[http-equiv]") === null
) {
switch (_this.props.boardNameShort) {
default: break;
case "mlp": window.location.hostname = "desuarchive.org"; break;
}
}
},
stopLinkReferrers: function () {
if (_this.props.isInPostView) {
_this.runOnAll(
function (target) {
target.querySelectorAll(".text a[target=\"_blank\"]")
.forEach(
function (item) {
item.referrerPolicy = "same-origin";
}
);
}
);
}
},
addSearchLimitationNote: function () {
return;
var tmp1;
var tmp2;
if (_this.props.isInSearch) {
tmp1 = document.querySelector("#main > h3.section_title");
if (tmp1) {
tmp2 = document.createElement("small");
tmp2.style = "margin-left: 10px";
tmp2.textContent = "Note: /v/ search goes back 1 year, /vg/ goes back 3 months.";
tmp1.appendChild(document.createTextNode(" "));
tmp1.appendChild(tmp2);
}
}
},
changeLastFiftyToHundred: function() {
// thread buttons
document.querySelectorAll(".post_controls > a.btnr")
.forEach(
function (item) {
if (item.textContent === "Last 50") {
item.textContent = "Last 100";
item.href = item.getAttribute("href").replace("/last/50/", "/last/100/");
}
}
);
// thread too big alert
document.querySelectorAll(".alert > a")
.forEach(
function (item) {
if (item.textContent === "view last 50 posts") {
item.textContent = "view last 100 posts";
item.href = item.getAttribute("href").replace("/last/50/", "/last/100/");
}
}
);
},
searchThreadStats: function() {
var topics;
var query;
var tmp1;
var tmp2;
if (_this.props.isInSearch) {
topics = [];
document.querySelectorAll("article.post.post_is_op")
.forEach(
function (item) {
topics.push({
"element": item,
"board": item.dataset.board,
"number": item.dataset.number
})
}
);
if (topics.length > 0) {
query = "";
topics.forEach(
function (item) {
query = (query + (query.length > 0 ? "," : "") + item.board + "." + item.number);
}
);
jQuery.ajax({
url: "https://b4k.co/4chan-arch-api.php",
method: "get",
dataType: "json",
data: {
"act": "replies",
"topics": query
},
success: function (data, textStatus, jqXHR) {
if (data) {
data.forEach(
function (item1) {
topics.forEach(
function (item2) {
if (
item1.board == item2.board,
item1.number == item2.number
) {
tmp1 = item2.element.querySelector(".post_file");
if (tmp1) {
tmp2 = document.createElement("span");
tmp2.textContent = ("Replies: " + (item1.cnt_reply - 1));
tmp2.style.marginLeft = "7px";
tmp1.appendChild(tmp2);
}
}
}
);
}
);
}
}
});
}
}
}
};
};

16645
firefox/b4k/highlight.pack.js

File diff suppressed because one or more lines are too long

180
firefox/b4k/lazyload.js

@ -0,0 +1,180 @@
/*!
* Lazy Load - JavaScript plugin for lazy loading images
*
* Copyright (c) 2007-2019 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* https://appelsiini.net/projects/lazyload
*
* Version: 2.0.0-rc.2
*
*/
(function (root, factory) {
if (typeof exports === "object") {
module.exports = factory(root);
} else if (typeof define === "function" && define.amd) {
define([], factory);
} else {
root.LazyLoad = factory(root);
}
}) (typeof global !== "undefined" ? global : this.window || this.global, function (root) {
"use strict";
if (typeof define === "function" && define.amd){
root = window;
}
const defaults = {
src: "data-src",
srcset: "data-srcset",
selector: ".lazyload",
root: null,
rootMargin: "0px",
threshold: 0
};
/**
* Merge two or more objects. Returns a new object.
* @private
* @param {Boolean} deep If true, do a deep (or recursive) merge [optional]
* @param {Object} objects The objects to merge together
* @returns {Object} Merged values of defaults and options
*/
const extend = function () {
let extended = {};
let deep = false;
let i = 0;
let length = arguments.length;
/* Check if a deep merge */
if (Object.prototype.toString.call(arguments[0]) === "[object Boolean]") {
deep = arguments[0];
i++;
}
/* Merge the object into the extended object */
let merge = function (obj) {
for (let prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
/* If deep merge and property is an object, merge properties */
if (deep && Object.prototype.toString.call(obj[prop]) === "[object Object]") {
extended[prop] = extend(true, extended[prop], obj[prop]);
} else {
extended[prop] = obj[prop];
}
}
}
};
/* Loop through each object and conduct a merge */
for (; i < length; i++) {
let obj = arguments[i];
merge(obj);
}
return extended;
};
function LazyLoad(images, options) {
this.settings = extend(defaults, options || {});
this.images = images || document.querySelectorAll(this.settings.selector);
this.observer = null;
this.init();
}
LazyLoad.prototype = {
init: function() {
/* Without observers load everything and bail out early. */
if (!root.IntersectionObserver) {
this.loadImages();
return;
}
let self = this;
let observerConfig = {
root: this.settings.root,
rootMargin: this.settings.rootMargin,
threshold: [this.settings.threshold]
};
this.observer = new IntersectionObserver(function(entries) {
Array.prototype.forEach.call(entries, function (entry) {
if (entry.isIntersecting) {
self.observer.unobserve(entry.target);
let src = entry.target.getAttribute(self.settings.src);
let srcset = entry.target.getAttribute(self.settings.srcset);
if ("img" === entry.target.tagName.toLowerCase()) {
if (src) {
entry.target.src = src;
}
if (srcset) {
entry.target.srcset = srcset;
}
} else {
entry.target.style.backgroundImage = "url(" + src + ")";
}
}
});
}, observerConfig);
Array.prototype.forEach.call(this.images, function (image) {
self.observer.observe(image);
});
},
loadAndDestroy: function () {
if (!this.settings) { return; }
this.loadImages();
this.destroy();
},
loadImages: function () {
if (!this.settings) { return; }
let self = this;
Array.prototype.forEach.call(this.images, function (image) {
let src = image.getAttribute(self.settings.src);
let srcset = image.getAttribute(self.settings.srcset);
if ("img" === image.tagName.toLowerCase()) {
if (src) {
image.src = src;
}
if (srcset) {
image.srcset = srcset;
}
} else {
image.style.backgroundImage = "url('" + src + "')";
}
});
},
destroy: function () {
if (!this.settings) { return; }
this.observer.disconnect();
this.settings = null;
}
};
root.lazyload = function(images, options) {
return new LazyLoad(images, options);
};
if (root.jQuery) {
const $ = root.jQuery;
$.fn.lazyload = function (options) {
options = options || {};
options.attribute = options.attribute || "data-src";
new LazyLoad($.makeArray(this), options);
return this;
};
}
return LazyLoad;
});

246
firefox/b4k/plugins.js

File diff suppressed because one or more lines are too long

4
firefox/manifest.json

@ -2,12 +2,12 @@
"manifest_version": 2,
"browser_specific_settings": {
"gecko": {
"update_url": "https://git.coom.tech/fuckjannies/lolipiss/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/firefox_update.json"
"update_url": "https://github.com/coomdev/pngextraembedder/raw/branch/%E4%B8%AD%E5%87%BA%E3%81%97/firefox_update.json"
}
},
"name": "PngExtraEmbedder",
"description": "Discover embedded files on 4chan and archives!",
"version": "0.213",
"version": "0.222",
"icons": {
"64": "1449696017588.png"
},

2
firefox_update.json

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

3
main.meta.js

@ -1,7 +1,7 @@
// ==UserScript==
// @name PNGExtraEmbed
// @namespace https://coom.tech/
// @version 0.207
// @version 0.222
// @description uhh
// @author You
// @match https://boards.4channel.org/*
@ -23,6 +23,7 @@
// @grant GM.setValue
// @grant GM_openInTab
// @grant GM.openInTab
// @grant GM_addElement
// @grant unsafeWindow
// @run-at document-start
// @connect 4chan.org

15049
main.user.js

File diff suppressed because it is too large

BIN
pngextraembedder-0.213-an+fx.xpi

Binary file not shown.

BIN
pngextraembedder-0.222-an+fx.xpi

Binary file not shown.

2
src/Components/PostOptions.svelte

@ -36,7 +36,7 @@
const isSame = (a: File | null, b: File | null) => {
if (a == null || b == null) return false;
(["size", "name", "lastModified"] as const).every((e) => a[e] == b[e]);
return (["size", "name", "lastModified"] as const).every((e) => a[e] == b[e]);
};
document.addEventListener("PEEFile", async (e) => {

8
src/main.ts

@ -194,7 +194,7 @@ const processPost = async (post: HTMLDivElement) => {
};
const versionCheck = async () => {
const txt = (await (await ifetch("https://git.coom.tech/coomdev/PEE/raw/branch/%e4%b8%ad%e5%87%ba%e3%81%97/main.meta.js")).text());
const txt = (await (await ifetch("https://github.com/coomdev/pngextraembedder/raw/branch/%e4%b8%ad%e5%87%ba%e3%81%97/main.meta.js")).text());
const [lmajor, lminor] = txt.split('\n')
.filter(e => e.includes("// @version"))[0].match(/.*version\s+(.*)/)![1].split('.')
.map(e => +e);
@ -556,11 +556,13 @@ if (supportedAltDomain(location.host)) {
let file = scr.src.slice(scr.src.lastIndexOf('/') + 1);
if (file.includes('?'))
file = file.slice(0, file.lastIndexOf('?'));
scr.src = `https://based.coom.tech/` + file;
if (execution_mode == "userscript")
scr.src = `https://based.coom.tech/` + file;
else
scr.src = chrome.runtime.getURL('b4k/' + file);
return;
}
if ((scr.src && !scr.src.startsWith('https://ajax.googleapis.com/')) || scr.innerHTML.includes('googletagmanager') || scr.src.startsWith("data:")) {
console.log(scr);
scr.parentElement?.removeChild(scr);
}
}

8
src/pngv3.ts

@ -2,7 +2,13 @@ import { Buffer } from "buffer";
import type { EmbeddedFile, ImageProcessor } from "./main";
import { PNGDecoder, PNGEncoder } from "./png";
import { decodeCoom3Payload } from "./utils";
import { settings } from "./stores";
export let csettings: Parameters<typeof settings['set']>[0];
settings.subscribe(b => {
csettings = b;
});
const CUM3 = Buffer.from("doo\0" + "m");
const BufferReadStream = (b: Buffer) => {
@ -35,7 +41,7 @@ const extract = async (png: Buffer) => {
case 'IDAT':
// eslint-disable-next-line no-fallthrough
case 'IEND':
return ret;
return ret.slice(0, csettings.maxe);
// eslint-disable-next-line no-fallthrough
default:
break;

7
src/utils.ts

@ -179,23 +179,16 @@ export const decodeCoom3Payload = async (buff: Buffer) => {
if (hasThumbnail) {
thumbsize = header.readInt32LE(ptr);
ptr += 4;
// if (execution_mode == 'userscript')
thumb = Buffer.from(await (await ifetch(pee, { headers: { 'user-agent': '', range: `bytes=${ptr}-${ptr + thumbsize}` } })).arrayBuffer());
// else
// thumb = `https://loli.piss/${domain}${file}/${ptr}/${ptr + thumbsize}`;
ptr += thumbsize;
}
const unzip = async (lsn?: EventTarget) =>
Buffer.from(await (await ifetch(pee, { headers: { 'user-agent': '', range: `bytes=${ptr}-${size - 1}` } }, lsn)).arrayBuffer());
let data;
// if (execution_mode == 'userscript') {
data = unzip;
if (size < 3072) {
thumb = data = await unzip();
}
// } else {
// data = `https://loli.piss/${domain}${file}/${ptr}/${size - 1}`;
// }
return {
filename: fn,
// if file is small, then just get it fully

2
src/websites/index.ts

@ -67,7 +67,6 @@ export const FoolFuuka: QueryProcessor = {
settingsHost: () => document.querySelector(".letters") as any,
catalogControlHost: () => document.getElementById("index-options") as HTMLDivElement,
getImageLink: async function *(post: HTMLElement) {
yield post.querySelector('a[rel]')?.getAttribute('href') || '';
if (location.host == "arch.b4k.co") { //get hecked
const pid = post.id.match(/\d+/)![0];
const board = location.pathname.match(/\/(..?.?)\//)![1];
@ -75,6 +74,7 @@ export const FoolFuuka: QueryProcessor = {
const data = await res.json();
yield data.media.media_link;
}
yield post.querySelector('a[rel]')?.getAttribute('href') || '';
},
getFilename: (post: HTMLElement) => {
const opfn = post.querySelector('a.post_file_filename')?.textContent;

Loading…
Cancel
Save