Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions plugins/AdminBackend/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,25 +122,45 @@
itemRow(reference, menu).after(...rows);
}

function x() {
for (const root of document.querySelectorAll(SELECTOR)) {
const id = visible(root) && userIdOf(root);
function within(root, selector) {
const found = [];
if (root.nodeType === Node.ELEMENT_NODE && root.matches(selector)) found.push(root);
if (root.querySelectorAll) found.push(...root.querySelectorAll(selector));
return found;
}

function x(root = document) {
for (const profile of within(root, SELECTOR)) {
const id = visible(profile) && userIdOf(profile);
if (id) profileId = id;
}
for (const item of document.querySelectorAll('button,[role="menuitem"]')) {
if (!visible(item) || item.textContent.replace(/\s+/g, ' ').trim() !== 'Copy link to profile') continue;
for (const item of within(root, 'button,[role="menuitem"]')) {
if (item.textContent.replace(/\s+/g, ' ').trim() !== 'Copy link to profile' || !visible(item)) continue;
const menu = item.closest('[role="menu"],.c-menu');
if (menu) injectMenu(menu, item);
}
}

let timer = null;
const observer = new MutationObserver(() => {
const pendingRoots = new Set();
function queue(root) {
if (root.nodeType !== Node.ELEMENT_NODE) return;
for (const pending of pendingRoots) {
if (pending.contains(root)) return;
if (root.contains(pending)) pendingRoots.delete(pending);
}
pendingRoots.add(root);
}
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => mutation.addedNodes.forEach(queue));
if (!pendingRoots.size) return;
if (timer) return;
timer = setTimeout(() => {
timer = null;
x();
}, 50);
const roots = [...pendingRoots];
pendingRoots.clear();
roots.forEach(x);
}, 100);
});

function boot() {
Expand Down
58 changes: 45 additions & 13 deletions plugins/LastSeen/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,12 @@
);
return { ts: ts[0], user: sender ? uid(sender) : uid(el) };
}
function scanMessages() {
function scanMessages(root = document) {
if (!S().showLastMessage) return;
document.querySelectorAll(ROW_SEL).forEach((row) => {
const rows = [];
if (root.nodeType === Node.ELEMENT_NODE && root.matches(ROW_SEL)) rows.push(root);
if (root.querySelectorAll) rows.push(...root.querySelectorAll(ROW_SEL));
rows.forEach((row) => {
const m = rowMsg(row);
if (m) markMsg(m.user, m.ts);
});
Expand All @@ -345,7 +348,7 @@
return null;
}

function roots() {
function roots(scope = document) {
const r = new Set();
for (const sel of [
'[data-qa="member_profile_pane"]',
Expand All @@ -365,7 +368,9 @@
]) {
let f;
try {
f = document.querySelectorAll(sel);
f = [];
if (scope.nodeType === Node.ELEMENT_NODE && scope.matches(sel)) f.push(scope);
if (scope.querySelectorAll) f.push(...scope.querySelectorAll(sel));
} catch {
continue;
}
Expand Down Expand Up @@ -531,9 +536,9 @@
(orig.trim() || 'Away');
}

function paint() {
function paint(scope = document) {
const s = S();
roots().forEach((root) => {
roots(scope).forEach((root) => {
const id = uid(root);
if (!id || id === 'USLACKBOT') return;
if (s.trackWatchlist) watch(id);
Expand All @@ -560,11 +565,18 @@
} catch {}
}
let pT = 0;
const sched = () => {
let fullScan = false;
const sched = (full = false) => {
fullScan ||= full;
if (pT) return;
pT = setTimeout(() => {
pT = 0;
pall();
if (fullScan) pall();
else {
style();
paint();
}
fullScan = false;
}, 200);
};

Expand All @@ -574,14 +586,34 @@
if (!document.body) return setTimeout(boot, 200);
patchWS();
pall();
const pendingRoots = new Set();
let mutationTimer = 0;
function queue(root) {
if (!root || root.nodeType !== Node.ELEMENT_NODE || root.closest('[data-slick-ls]')) return;
for (const pending of pendingRoots) {
if (pending.contains(root)) return;
if (root.contains(pending)) pendingRoots.delete(pending);
}
pendingRoots.add(root);
}
new MutationObserver((mutations) => {
const external = mutations.some((mutation) => {
const target = mutation.target;
return target.nodeType !== Node.ELEMENT_NODE || !target.closest('[data-slick-ls]');
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) queue(node.closest(SURF) || node);
});
});
if (external) sched();
if (!pendingRoots.size || mutationTimer) return;
mutationTimer = setTimeout(() => {
mutationTimer = 0;
const scopes = [...pendingRoots];
pendingRoots.clear();
scopes.forEach((scope) => {
scanMessages(scope);
paint(scope);
});
}, 150);
}).observe(document.body, { subtree: true, childList: true });
addEventListener('slick:plugin-settings', sched);
addEventListener('slick:plugin-settings', () => sched(true));
addEventListener('storage', (e) => {
if (e.key === 'slick:lastseen:cache') {
C = load();
Expand Down
25 changes: 23 additions & 2 deletions plugins/PrivateChannelMapper/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@
document.querySelectorAll(SEL).forEach(apply);
}

function applyWithin(root) {
if (root.nodeType === Node.ELEMENT_NODE && root.matches(SEL)) apply(root);
if (root.querySelectorAll) root.querySelectorAll(SEL).forEach(apply);
}

let overlay = null;
function closeEditor() {
if (overlay) {
Expand Down Expand Up @@ -185,11 +190,27 @@
});

let t = null;
const obs = new MutationObserver(() => {
const pendingRoots = new Set();
function queue(root) {
if (!root || root.nodeType !== Node.ELEMENT_NODE) return;
for (const pending of pendingRoots) {
if (pending.contains(root)) return;
if (root.contains(pending)) pendingRoots.delete(pending);
}
pendingRoots.add(root);
}
const obs = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'characterData') queue(mutation.target.parentElement?.closest(SEL));
mutation.addedNodes.forEach(queue);
});
if (!pendingRoots.size) return;
if (t) return;
t = setTimeout(() => {
t = null;
applyAll();
const roots = [...pendingRoots];
pendingRoots.clear();
roots.forEach(applyWithin);
}, 150);
});
function boot() {
Expand Down
44 changes: 36 additions & 8 deletions plugins/SlimMessageBox/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,32 @@
scope.classList.remove('slick-smb-stacked');
}
}
function applyDomHides() {
function applyDomHides(root) {
var s = settings();
for (var key in HIDE_DOM) {
if (!s[key]) continue;
document.querySelectorAll(SCOPE + ' ' + HIDE_DOM[key]).forEach(function (el) {
var insideScope = root.nodeType === Node.ELEMENT_NODE && root.closest(SCOPE);
var selector = insideScope ? HIDE_DOM[key] : SCOPE + ' ' + HIDE_DOM[key];
var elements = [];
if (root.nodeType === Node.ELEMENT_NODE && root.matches(selector)) elements.push(root);
if (root.querySelectorAll) elements.push.apply(elements, root.querySelectorAll(selector));
elements.forEach(function (el) {
el.style.setProperty('display', 'none', 'important');
});
}
}
function scan(root) {
var selector = SCOPE + ' .ql-editor, ' + SCOPE + ' [contenteditable="true"][role="textbox"]';
var editors = [];
if (root.nodeType === Node.ELEMENT_NODE && root.matches(selector)) editors.push(root);
if (root.querySelectorAll) editors.push.apply(editors, root.querySelectorAll(selector));
editors.forEach(evaluate);
var scope = root.nodeType === Node.ELEMENT_NODE && root.closest(SCOPE);
if (scope) scope.querySelectorAll('.ql-editor,[contenteditable="true"][role="textbox"]').forEach(evaluate);
applyDomHides(root);
}
function scanAll() {
document
.querySelectorAll(SCOPE + ' .ql-editor, ' + SCOPE + ' [contenteditable="true"][role="textbox"]')
.forEach(evaluate);
applyDomHides();
scan(document);
}
document.addEventListener(
'input',
Expand All @@ -78,12 +90,28 @@
window.addEventListener('resize', scanAll);
window.addEventListener('slick:plugin-settings', scanAll);
var pending = false;
new MutationObserver(function () {
var pendingRoots = new Set();
function queue(root) {
if (!root || root.nodeType !== Node.ELEMENT_NODE) return;
for (var existing of pendingRoots) {
if (existing.contains(root)) return;
if (root.contains(existing)) pendingRoots.delete(existing);
}
pendingRoots.add(root);
}
new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
queue(mutation.target.closest && mutation.target.closest(SCOPE));
mutation.addedNodes.forEach(queue);
});
if (!pendingRoots.size) return;
if (pending) return;
pending = true;
setTimeout(function () {
pending = false;
scanAll();
var roots = Array.from(pendingRoots);
pendingRoots.clear();
roots.forEach(scan);
}, 150);
}).observe(document.documentElement, { childList: true, subtree: true });
scanAll();
Expand Down
Loading