From c5b36dc3ae3c632da20fb09534e03e6aa84b75b6 Mon Sep 17 00:00:00 2001 From: Kimapr Date: Tue, 15 Apr 2025 21:25:35 +0500 Subject: [PATCH] Expand All CWs --- README.md | 2 ++ aKKKoma.js | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6e51f4c..eabba14 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ put this scrip into your grease monkey + +EDIT: scrip no longer works with grease monkey. use violent monkey instead my apollo cheese diff --git a/aKKKoma.js b/aKKKoma.js index 70cafe1..e4c5dfa 100644 --- a/aKKKoma.js +++ b/aKKKoma.js @@ -2,16 +2,50 @@ // @name kimarp aKKKoma modifications // @version 1 // @grant none +// @inject-into page // ==/UserScript== +// ViolentMonkey Recommended For This Script + ;(_=>{ if (!((document.querySelector("noscript")??{}).innerText == "To use Akkoma, please enable JavaScript.")) { return; } console.log("activating evil akkoma mode"); + let nonce = document.querySelector("script").nonce; + + // getEventListeners(elem: EventTarget, event; string): Set + // + // Get event listeners of an EventTarget. + // Return value: Set object containing the event listeners in question. + // + // Modifications of the returned Set by the caller results in undefined behavior. + // + let getEventListeners = ((proto, addEventListener, removeEventListener, elems, ensure, ensurex) => ( + // murder + addEventListener = proto.addEventListener, + removeEventListener = proto.removeEventListener, + elems = new WeakMap(), + ensure = k => (elems.get(k) ?? ensure((elems.set(k, new Map()), k))), + ensurex = (els, k) => (els.get(k) ?? (els.set(k, new Set()), ensurex(els, k))), + proto.addEventListener = function(t, lis, ...rest) { + let ret = addEventListener.apply(this, [t, lis, ...rest]); + ensurex(ensure(this), t).add(lis); + return ret; + }, + proto.removeEventListener = function(t, lis, ...rest) { + let ret = addEventListener.apply(this, [t, lis, ...rest]); + ensurex(ensure(this), t).delete(lis); + return ret; + }, + function(elem, t) { + return ensurex(ensure(elem), t); + } + ))(unsafeWindow.EventTarget.prototype); let style = document.createElement("style"); + style.nonce = nonce; style.textContent=` ._mfm_x2_ ._mfm_x2_ ._mfm_x2_, ._mfm_x2_ ._mfm_x2_ ._mfm_x3_, @@ -88,17 +122,80 @@ body { [0].style.gridTemplateAreas=""; } catch {} - var elem = function(tag,a,b){ - tag = document.createElement(tag); + var elemx = function(tag,ns,a,b) { + tag = ns ? document.createElementNS(ns, tag) : document.createElement(tag); Object.entries(a??{}).forEach(([k,v]) => tag.setAttribute(k,v)); (b??[]).map(e => (typeof e) == "string" ? document.createTextNode(e) : e) .forEach(e => tag.append(e)); return tag; }; + var elem = function(tag,a,b){ + return elemx(tag,null,a,b); + }; + var $ = (query, base) => base ? base.querySelectorAll(query) : document.querySelectorAll(query); var $0 = (query, base) => base ? base.querySelector(query) : document.querySelector(query); + var lastComment; + + var eatComments = x => (x + .flatMap(e => [...e.removedNodes]) + .filter(e => e instanceof Comment) + .forEach(e => lastComment = {obj: e, prev: e.prevSibling}) + ,x); + + var findAllShowHide = e => ({ + unhiders: [...$(".text-wrapper:not(.-tall-status) > .cw-status-hider", e)].filter(e => e.checkVisibility()), + hiders: [...$(".text-wrapper:not(.-tall-status) > .status-unhider", e)].filter(e => e.checkVisibility()), + }) + + var aquireParentThread = e => { + while (e) { + if (e.matches(".thread-body")) return e; + e = e.parentElement; + } + }; + + new MutationObserver(x => eatComments(x) + .flatMap(e => [...e.addedNodes]) + .filter(e => e.matches && e.matches('.Conversation .ExtraButtons div.popover')) + .map(e => $0("div.dropdown-menu", e)) + .forEach((e, x, exp, thread) => e.prepend(( + thread = aquireParentThread(e), + console.log("MEOW", thread, findAllShowHide(thread)), + x = elem("button", {class: "button-default dropdown-item dropdown-item-icon"}, [ + elemx("svg", "http://www.w3.org/2000/svg", { + class: "svg-inline--fa fa-fw", + "aria-hidden": "true", + focusable: "false", + "data-prefix": "fas", + "data-icon": "", + role: "img", + viewBox: "0 0 100 100", + }, [ + elemx("path", "http://www.w3.org/2000/svg", { + class: "", + fill: "currentColor", + d: "m 50.660539,0.0045101 c -0.645534,-0.01213881 -1.294703,1.754e-5 -1.945858,0.03899735 -1.411948,0.0845229 -2.835684,0.31198703 -4.257516,0.64938883 C 38.542997,1.8005311 33.899147,5.1598476 30.643098,8.9077496 27.383379,12.659877 25.219091,16.79805 23.376192,20.411935 L 3.7381004,57.047298 3.9142268,56.738711 C -7.5703242,75.610959 7.7541966,101.94204 29.914884,99.886616 h 42.92403 l -0.116853,-0.0017 C 83.788836,100.08403 92.592574,92.975791 96.831053,84.247017 101.0024,75.656523 101.41478,64.907121 95.896233,56.118138 L 73.683982,14.684427 C 69.268882,6.0241919 60.343554,0.18659192 50.660539,0.0045101 Z M 49.434428,13.082149 c 0.708497,-0.02575 1.4264,0.01697 2.142307,0.122078 4.295437,0.630654 8.539948,3.513478 10.521857,7.400998 a 6.5037781,6.5114945 0 0 0 0.06266,0.118688 l 22.308777,41.61514 a 6.5037781,6.5114945 0 0 0 0.291286,0.490009 c 2.873436,4.390121 2.843963,10.634761 0.372575,15.724365 -2.47139,5.089603 -6.686363,8.412003 -12.178123,8.313195 a 6.5037781,6.5114945 0 0 0 -0.116857,-0.0017 H 29.745531 a 6.5037781,6.5114945 0 0 0 -0.736682,0.04236 C 17.71564,88.197456 9.1296536,73.196865 15.022043,63.514057 A 6.5037781,6.5114945 0 0 0 15.19817,63.20547 L 34.839648,26.565021 a 6.5037781,6.5114945 0 0 0 0.06266,-0.118687 c 1.767303,-3.467518 3.585064,-6.727822 5.553062,-8.993102 1.967993,-2.265282 3.79268,-3.517979 6.467563,-3.992979 a 6.5037781,6.5114945 0 0 0 0.423377,-0.08986 c 0.68052,-0.168284 1.379616,-0.262494 2.088114,-0.288241 z m 0.613056,5.413835 c -1.393903,0 -2.595462,0.565514 -3.603817,1.693836 -0.978698,1.128323 -1.466591,2.627607 -1.466591,4.498247 0,0.77201 0.08794,1.944516 0.265883,3.51823 l 3.915425,36.077531 h 1.690136 l 4.003488,-36.077531 c 0.11863,-1.276786 0.177819,-2.271513 0.177819,-2.984137 0,-2.226952 -0.489585,-3.904017 -1.468284,-5.03234 -0.94904,-1.128322 -2.120157,-1.693836 -3.514059,-1.693836 z m -0.08806,53.180365 c -1.364245,0 -2.537055,0.490167 -3.515753,1.470026 -0.94904,0.950166 -1.422559,2.09389 -1.422559,3.430062 0,1.365863 0.473519,2.53837 1.422559,3.518229 0.978698,0.950165 2.151508,1.424247 3.515753,1.424247 1.364246,0 2.520989,-0.474082 3.470028,-1.424247 0.978699,-0.979859 1.466592,-2.152366 1.466591,-3.518229 0,-1.336172 -0.487892,-2.479896 -1.466591,-3.430062 -0.949039,-0.979859 -2.105782,-1.470026 -3.470028,-1.470026 z" + }) + ]), + elem("span", {}, [((exp = findAllShowHide(thread).unhiders.length != 0) ? "Expand" : "Close") + " all CWs"]) + ]), + x.addEventListener("click", ev => ( + ev = findAllShowHide(thread), + (exp ? ev.unhiders : ev.hiders).forEach(e => e.click()), + [...e.children] + .flatMap(e => [...getEventListeners(e,'click')]) + .filter(e => e?.value) + .filter(e => e.value[1]) + .filter(e=>e.value[1].name=="bound hidePopover") + .map(e => e.value[1])[0]() + )), x + ))) + ) + .observe(document.body, {childList:true, subtree:true}) + let makeCheckBox = (label, params, eater) => { let checkb;