// ==UserScript==
// @name FB Mobile - Clean my feeds
// @namespace Violentmonkey Scripts
// @version 1.00
// @description Removes Sponsored and Suggested posts from Facebook mobile chromium/react version
// @license GNU General Public License v3.0
// @author https://github.com/webdevsk
// @match https://m.facebook.com/*
// @match https://www.facebook.com/*
// @match https://touch.facebook.com/*
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAbwAAAG8B8aLcQwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHZSURBVDiNnZFLSFRxFMa/c1/jjIzYpGEjxFQUCC5a9BKJIAtRzEXEFaJFZXRrIQMtk3a1lWo3iwqkTS0kZyGCA4VNFNEmWwU9MIoiscZp7jzuvf9zWogXogS9Z3fO4fv4feeQiCBKjY8M9Nca3lUtkhqAUnwNoPcUheC63b+z5qm3nmelIxGwkMMir+/MzJSNzYodZ7/ZolKXADoDAJsmSJXahpXiXxPThdlIBlCSFUh+rd1wBNvuttLu1sOGae7zYjy4Nt8QgXpoXbzf9/HVYNfi3O+KK5XP5V3rEti2rde3pHvyuVtFAMB8/JjWJLlEU0M7nlnE0e1fjGVqPgVg4b8E0rHnHoSeDY1mx/CCUiIyiVZdQ8YE7bVgdpCWCqrj6xIQ0Rtm/qlB3okXywHoDJcxAnWa0OPtpb8M8nPP06V6tVD3/Mqj2zcOApjA0/g5AU6HYl7llcAANP4WHnH6SfEQ65hPJuJdvh8cuDs165y8nO1bqiZb4KoyVhhYVoDLqxEDAwT+EBqwwAGwm4jQmmyGF/g3Y3pi+MLU2U9UCjKUwCga/BUmAT8CiDIAnRfCyI8LxSNCeABgh1uro+zWlq7YQ9v++WXe7GWDziu/bcS0+AQGvr8EgD/aK7uaswjePgAAAABJRU5ErkJggg==
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addStyle
// @grant GM_addValueChangeListener
// @grant GM_removeValueChangeListener
// @run-at document-end
// @downloadURL https://update.greasyfork.icu/scripts/479868/FB%20Mobile%20-%20Clean%20my%20feeds.user.js
// @updateURL https://update.greasyfork.icu/scripts/479868/FB%20Mobile%20-%20Clean%20my%20feeds.meta.js
// ==/UserScript==
// src/config.ts
var devMode = false;
var pathnameMatches = ["/"];
var bodyId = "app-body";
var screenRootSelector = "#screen-root";
var routeNodeSelector = "[data-screen-id]:first-child";
var postContainerSelector = "[data-pull-to-refresh-action-id]";
var possibleTargetsSelectorInPost = "span.f2:not(.a), span.f5, [style^='margin-top:9px; height:21px'] > .native-text";
var navBarSelector = "[role='tablist']";
var showPlaceholder = true;
var theme = {
textColor: "ffffff",
iconColor: "e4e6eb",
bgClassName: "bg-fallback",
iconBgClassName: "icon-bg-fallback"
};
// src/lib/block-counter.ts
class BlockCounter {
static instance = null;
elm = null;
whitelisted = 0;
blacklisted = 0;
constructor() {}
static getInstance() {
if (!BlockCounter.instance) {
BlockCounter.instance = new BlockCounter;
}
return BlockCounter.instance;
}
register() {
if (!this.elm) {
this.elm = document.createElement("div");
this.elm.id = "block-counter";
document.body.appendChild(this.elm);
if (devMode)
console.log("block counter register successful");
} else if (!document.body.contains(this.elm)) {
document.body.appendChild(this.elm);
if (devMode)
console.log("block counter register successful");
}
this.render();
return () => this.destroy();
}
render() {
if (this.elm) {
this.elm.innerHTML = `
Whitelisted: ${this.whitelisted}
Blacklisted: ${this.blacklisted}
`;
}
}
destroy() {
if (this.elm && document.body.contains(this.elm)) {
this.elm.remove();
}
}
increaseWhite() {
this.whitelisted += 1;
this.render();
}
increaseBlack() {
this.blacklisted += 1;
this.render();
}
}
// src/lib/make-navbar-sticky.ts
var makeNavbarSticky = () => {
const navbar = document.querySelector(navBarSelector);
const screenRoot = document.querySelector(screenRootSelector);
navbar.classList.add(theme.bgClassName);
Object.assign(navbar.style, {
position: "sticky",
top: "-1px",
zIndex: "1",
insetInline: "0"
});
Object.assign(screenRoot.style, {
overflow: "visible"
});
};
// src/lib/menu-buttons-injector.ts
class MenuButtonsInjector {
static instance = null;
buttonsInjected = false;
buttonElements = [];
constructor() {}
static getInstance() {
if (!MenuButtonsInjector.instance) {
MenuButtonsInjector.instance = new MenuButtonsInjector;
}
return MenuButtonsInjector.instance;
}
inject() {
if (this.buttonsInjected) {
console.warn("Menu buttons already injected");
return () => {
this.destroy();
};
}
this.injectButtons();
this.buttonsInjected = true;
if (devMode)
console.log("Menu buttons injected successfully");
return () => {
this.destroy();
};
}
setupTabBarStyles() {
const tabBarEle = document.querySelector('[role="tablist"]');
if (tabBarEle) {
tabBarEle.style.position = "sticky";
tabBarEle.style.zIndex = "1";
tabBarEle.style.top = "0";
}
}
createButton(id, imgSrc) {
const button = document.createElement("div");
button.id = id;
button.className = "customBtns";
button.innerHTML = `
`;
return button;
}
injectButtons() {
const titleBarEle = document.querySelector(".filler")?.nextElementSibling;
if (!titleBarEle || !(titleBarEle instanceof HTMLElement)) {
if (devMode)
console.error("Title bar element not found");
return;
}
const innerScreenText = document.querySelector("#screen-root .fixed-container.top .f2")?.textContent || "";
if (innerScreenText)
return;
this.destroy();
this.buttonElements = [];
if (!document.getElementById("settingsBtn")) {
const settingsBtn = this.createButton("settingsBtn", "https://static.xx.fbcdn.net/rsrc.php/v4/yC/r/FgGUIEUfnev.png");
titleBarEle.after(settingsBtn);
this.buttonElements.push(settingsBtn);
}
if (!document.getElementById("feedsBtn")) {
const feedsBtn = this.createButton("feedsBtn", "https://static.xx.fbcdn.net/rsrc.php/v4/yB/r/Bc4BAjXDBat.png");
titleBarEle.after(feedsBtn);
this.buttonElements.push(feedsBtn);
}
}
destroy() {
if (!this.buttonsInjected)
return;
this.buttonElements.forEach((button) => {
if (devMode)
console.log("Removing button:", button);
button.remove();
});
this.buttonElements = [];
this.buttonsInjected = false;
}
}
// src/utils/watch-for-selectors.ts
function watchForSelectors(selectors, callback, options = {}) {
if (!Array.isArray(selectors))
throw new Error("watchForSelectors: Selectors must be an array");
if (!callback || typeof callback !== "function")
throw new Error("watchForSelectors: Callback must be a function");
if (typeof options !== "object")
throw new Error("watchForSelectors: Options must be an object");
if ("resolver" in options && typeof options.resolver !== "function")
throw new Error("watchForSelectors: Resolver must be a function that resolves to boolean");
const elements = selectors.map((selector) => document.querySelector(selector));
if (options.resolver?.(elements) ?? elements.every((elm) => elm !== null)) {
callback();
return () => null;
}
const observer = new MutationObserver((_, observer2) => {
const elements2 = selectors.map((selector) => document.querySelector(selector));
if (options.resolver?.(elements2) ?? elements2.every((elm) => elm !== null)) {
observer2.disconnect();
callback();
}
});
observer.observe(options.target ?? document, options.observerOptions ?? { childList: true, subtree: true });
options.signal?.addEventListener("abort", () => {
observer.disconnect();
}, { once: true });
return observer.disconnect.bind(observer);
}
function watchForSelectorsPromise(selectors, options = {}) {
return new Promise((resolve, reject) => {
watchForSelectors(selectors, resolve, options);
options.signal?.addEventListener("abort", () => reject(new Error("Aborted by signal")));
});
}
// src/lib/on-ready-for-scripting.ts
var onReadyForScripting = async (cb) => {
let cleanupFn = null;
const main = () => {
if (devMode)
console.log("Main node found. Running cleanup function and restarting...");
cleanupFn?.();
cleanupFn = cb();
};
await watchForSelectorsPromise([screenRootSelector]);
onNavigation((routeNode) => {
if (devMode)
console.log("onNavigation callback called");
if (!pathnameMatches.some((pathname) => pathname === location.pathname)) {
if (devMode)
console.log("Not on main page. Terminating...");
return () => null;
}
if (document.querySelector(postContainerSelector))
main();
const observer = new MutationObserver((mutationList) => {
if (devMode)
console.log("Main node detector mutation detected");
for (const mutation of mutationList) {
for (const node of mutation.addedNodes) {
if (node instanceof HTMLElement && node.nodeType === Node.ELEMENT_NODE && node.matches(postContainerSelector)) {
main();
}
}
}
});
observer.observe(routeNode, {
childList: true
});
return () => {
cleanupFn?.();
cleanupFn = null;
observer.disconnect();
};
});
};
var onNavigation = async (cb) => {
let cleanupFn = null;
const screenRoot = document.querySelector(screenRootSelector);
const initialRouteNode = screenRoot.querySelector(routeNodeSelector);
if (initialRouteNode && initialRouteNode instanceof HTMLElement) {
cleanupFn = cb(initialRouteNode);
}
new MutationObserver((mutationList) => {
if (devMode)
console.log("Running navigation mutation");
for (const mutation of mutationList) {
for (const node of mutation.addedNodes) {
if (node instanceof HTMLElement && node.nodeType === Node.ELEMENT_NODE && node.matches(routeNodeSelector)) {
if (devMode)
console.log("Navigation detected, ", node);
cleanupFn?.();
cleanupFn = cb(node);
}
}
}
}).observe(screenRoot, {
childList: true
});
};
// src/lib/register-auto-reload-after-idle.ts
function registerAutoReloadAfterIdle(minutes = 15) {
let leaveTime = null;
let ctrl = new AbortController;
if (devMode)
console.log("Auto reload after idle registered");
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
leaveTime = new Date;
} else {
if (!leaveTime)
return;
const currentTime = new Date;
const timeDiff = (currentTime.getTime() - leaveTime.getTime()) / 60000;
if (timeDiff > minutes)
location.reload();
}
}, { signal: ctrl.signal });
return () => {
ctrl.abort();
ctrl = new AbortController;
if (devMode)
console.log("Auto reload after idle unregistered", ctrl.signal);
ctrl.signal.throwIfAborted();
};
}
// src/data/keywords-per-language.ts
var keywordsPerLanguage = {
placeholderMessage: {
"en-US": "Removed",
en: "Removed",
bn: "বাতিল"
},
suggested: {
"en-US": "Suggested",
en: "Suggested",
bn: "আপনার জন্য প্রস্তাবিত"
},
sponsored: {
"en-US": "Sponsored",
en: "Sponsored",
bn: "স্পনসর্ড"
},
uncategorized: {
"en-US": ["Join", "Follow"],
en: ["Join", "Follow"],
bn: ["ফলো করুন", "যোগ দিন"]
},
peopleYouMayKnow: {
"en-US": "People You May Know",
en: "People You May Know"
},
reels: {
"en-US": "Reels",
en: "Reels"
}
};
// src/data/filters-database.ts
var filtersDatabase = {
suggested: {
title: "Suggested",
description: "Removes un-needed algorithm suggested posts",
icon: "\uDB86\uDD01",
keywordsDB: keywordsPerLanguage.suggested
},
sponsored: {
title: "Sponsored",
description: "Removes annoying ads",
icon: "\uDB86\uDC11",
keywordsDB: keywordsPerLanguage.sponsored
},
reels: {
title: "Reels",
description: "Removes annoying short videos",
icon: "\uDB80\uDF83",
keywordsDB: keywordsPerLanguage.reels
},
peopleYouMayKnow: {
title: "People You May Know",
description: "Removes suggested friends",
icon: "\uDB80\uDF8D",
keywordsDB: keywordsPerLanguage.peopleYouMayKnow
},
uncategorized: {
title: "Uncategorized",
description: "Removes suggested pages with join/follow link",
icon: "\uDB86\uDC02",
keywordsDB: keywordsPerLanguage.uncategorized
}
};
// src/lib/get-own-language-filters.ts
var getOwnLangFilters = (obj) => navigator.languages.flatMap((lang) => obj[lang]);
// src/lib/purge-element.ts
var purgeElement = ({
element,
reason,
author,
placeHolderMessage,
sponsoredFilters
}) => {
element.tabIndex = -1;
element.dataset.purged = "true";
if (showPlaceholder && !sponsoredFilters.includes(reason)) {
element.dataset.actualHeight = "32";
element.classList.add(theme.bgClassName);
element.style.height = "2rem";
const overlay = document.createElement("article");
overlay.className = "placeholder";
overlay.innerHTML = `${placeHolderMessage}: ${author} (${reason})
`;
element.appendChild(overlay);
} else {
element.dataset.actualHeight = "0";
element.dataset.forceHide = "true";
element.style.height = "0rem";
const { previousElementSibling: prevElm } = element;
if (!(prevElm && prevElm instanceof HTMLElement) || prevElm.dataset.actualHeight !== "1")
return;
prevElm.style.marginTop = "0px";
prevElm.style.height = "0px";
prevElm.dataset.actualHeight = "0";
}
for (const image of element.querySelectorAll("img")) {
image.dataset.src = image.src;
image.removeAttribute("src");
image.dataset.nulled = "true";
}
};
// src/lib/spinner.ts
class Spinner {
static instance = null;
elm = null;
isVisible = false;
constructor() {}
static getInstance() {
if (!Spinner.instance) {
Spinner.instance = new Spinner;
}
return Spinner.instance;
}
register() {
if (!this.elm) {
this.elm = document.createElement("div");
this.elm.id = "spinner";
this.elm.innerHTML = ``;
document.body.appendChild(this.elm);
if (devMode)
console.log("Spinner register successful");
} else if (!document.body.contains(this.elm)) {
document.body.appendChild(this.elm);
if (devMode)
console.log("Spinner register successful");
}
return () => this.destroy();
}
destroy() {
if (this.elm && document.body.contains(this.elm)) {
this.elm.remove();
}
}
show() {
this.isVisible = true;
if (this.elm) {
this.elm.style.display = "block";
}
}
hide() {
this.isVisible = false;
if (this.elm) {
this.elm.style.display = "none";
}
}
}
// src/lib/whitelisted-filters-storage.ts
class WhitelistedFiltersStorage {
storageKey = "whitelisted-filters";
listenerId = null;
defaultValue = [];
cache = [];
static instance = null;
static getInstance() {
if (!WhitelistedFiltersStorage.instance) {
WhitelistedFiltersStorage.instance = new WhitelistedFiltersStorage;
}
return WhitelistedFiltersStorage.instance;
}
register() {
const initialValue = GM_getValue(this.storageKey, this.defaultValue);
this.update(initialValue);
if (devMode)
console.log("WhitelistedFiltersStorage register successful");
return this.onChange();
}
update(value) {
if (Array.isArray(value) && value.every((val) => typeof val === "string")) {
this.cache = value;
} else {
this.cache = this.defaultValue;
this.set(this.defaultValue);
}
}
get() {
return this.cache;
}
set(filters) {
if (devMode)
console.log("Set new filters", filters);
GM_setValue(this.storageKey, filters);
}
onChange(cb) {
this.listenerId = GM_addValueChangeListener(this.storageKey, (_name, _oldValue, newValue, _remote) => {
if (devMode)
console.log("New filter value", newValue);
this.update(newValue);
cb?.(this.get());
});
return () => {
if (this.listenerId)
GM_removeValueChangeListener(this.listenerId);
};
}
}
// src/lib/run-feeds-cleaner.ts
var runFeedsCleaner = () => {
if (devMode)
console.log("navigator.languages", navigator.languages);
const root = document.querySelector(postContainerSelector);
const whitelistedStorageInstance = WhitelistedFiltersStorage.getInstance();
const allFilters = Object.keys(filtersDatabase);
const whitelistedFilters = whitelistedStorageInstance.get();
const activeFilters = [];
const setActiveFilters = (whitelistedFilters2) => {
activeFilters.length = 0;
activeFilters.push(...new Set(allFilters.flatMap((filter) => whitelistedFilters2.includes(filter) ? [] : getOwnLangFilters(filtersDatabase[filter].keywordsDB)).filter((d) => d)));
};
setActiveFilters(whitelistedFilters);
whitelistedStorageInstance.onChange(setActiveFilters);
const sponsoredFilters = getOwnLangFilters(filtersDatabase.sponsored.keywordsDB);
const placeHolderMessage = getOwnLangFilters(keywordsPerLanguage.placeholderMessage)[0];
const checkElement = (element) => {
if (element.dataset.purged === "true")
return;
let suspect = false;
let reason = null;
let raw = null;
for (const span of element.querySelectorAll(possibleTargetsSelectorInPost)) {
if (!activeFilters.some((str) => span.textContent?.includes(str)))
continue;
suspect = true;
reason = span.innerHTML.split("\uDB81\uDF8B")[0];
raw = span.innerHTML;
break;
}
if (!suspect) {
BlockCounter.getInstance().increaseWhite();
return;
}
BlockCounter.getInstance().increaseBlack();
purgeElement({
element,
reason: reason ?? raw ?? "",
author: element.querySelector("span.f2")?.innerHTML ?? "",
placeHolderMessage,
sponsoredFilters
});
};
if (devMode)
console.log("Initial checking");
for (const element of root.querySelectorAll("[data-tracking-duration-id]")) {
checkElement(element);
}
if (devMode)
console.log("Initial checking done");
if (devMode)
console.log("Mutation observer setup for new posts");
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.addedNodes.length === 0)
continue;
if (devMode)
console.log("Checking posts count:", mutation.addedNodes.length);
Spinner.getInstance().show();
for (const element of mutation.addedNodes) {
if (!(element instanceof HTMLElement) || element.nodeType !== Node.ELEMENT_NODE)
continue;
if (!element.hasAttribute("data-tracking-duration-id"))
continue;
checkElement(element);
}
Spinner.getInstance().hide();
}
});
observer.observe(root, {
childList: true
});
if (devMode)
console.log("Mutation observer setup for new posts done on", root);
return () => {
observer.disconnect();
if (devMode)
console.log("Mutation observer for posts disconnected");
};
};
// src/lib/settings-menu-injector.ts
var closeMenuIcon = "\uDB85\uDE73";
class SettingsMenuInjector {
static instance;
ctrl;
overlayId = "settingsOverlay";
constructor() {
this.ctrl = new AbortController;
}
static getInstance() {
if (!SettingsMenuInjector.instance) {
SettingsMenuInjector.instance = new SettingsMenuInjector;
}
return SettingsMenuInjector.instance;
}
generateSettingsOverlay() {
return `
${Object.entries(filtersDatabase).map(([filterType, item]) => {
return `
`;
}).join(`
`).concat(`
`)}
`;
}
handleCheckboxChange = (event) => {
const target = event.target;
if (!target.matches(`#${this.overlayId} input[type="checkbox"]`))
return;
const { name, checked } = target;
if (!Object.keys(filtersDatabase).includes(name))
return;
const whiteListedFilters = WhitelistedFiltersStorage.getInstance().get();
const isWhiteListed = whiteListedFilters.includes(name);
if (!checked === isWhiteListed)
return;
WhitelistedFiltersStorage.getInstance().set(isWhiteListed ? whiteListedFilters.filter((filter) => filter !== name) : [...whiteListedFilters, name]);
};
handleDocumentClick = (event) => {
const target = event.target;
if (target.matches("#settingsBtn")) {
this.show();
} else if (target.matches("#closeMenuTile")) {
this.hide();
} else if (target.matches("#feedsBtn")) {
document.querySelector('[aria-label="Facebook Menu"]')?.click();
watchForSelectors(['[aria-label="Feeds"]'], () => {
document.querySelector('[aria-label="Feeds"]').click();
}, {
signal: this.ctrl.signal,
target: document.querySelector(screenRootSelector)
});
}
};
setupEventListeners() {
document.addEventListener("click", this.handleDocumentClick, {
signal: this.ctrl.signal
});
document.addEventListener("change", this.handleCheckboxChange, {
signal: this.ctrl.signal
});
}
destroyEventListeners() {
this.ctrl.signal.throwIfAborted();
this.ctrl.abort();
}
inject() {
if (devMode)
console.log("SettingsMenuInjector inject called");
this.ctrl = new AbortController;
this.setupEventListeners();
if (devMode)
console.log("SettingsMenuInjector inject successful");
return () => {
if (devMode)
console.log("SettingsMenuInjector cleanup called");
this.hide();
this.destroyEventListeners();
};
}
show() {
if (devMode)
console.log("SettingsMenuInjector show called");
if (document.getElementById(this.overlayId))
return;
document.body.insertAdjacentHTML("beforeend", this.generateSettingsOverlay());
}
hide() {
if (devMode)
console.log("SettingsMenuInjector hide called");
document.getElementById(this.overlayId)?.remove();
}
}
// src/lib/updateThemeConfigWhenPossible.ts
var updateThemeConfigWhenPossible = () => watchForSelectors([
".native-text:last-child",
'[role="tablist"]>*:last-child .native-text',
'[aria-label="Search Facebook"] [class*="bg-"]'
], () => {
const bgClassName = document.querySelector('[role="tablist"]>*:last-child').classList.values().find((v) => v.startsWith("bg-"));
const iconBgClassName = document.querySelector('[aria-label="Search Facebook"] [class*="bg-"]').classList.values().find((v) => v.startsWith("bg-"));
if (!bgClassName || !iconBgClassName)
return;
theme.bgClassName = bgClassName;
theme.iconBgClassName = iconBgClassName;
theme.textColor = getComputedStyle(document.querySelector(".native-text:last-child")).color;
theme.iconColor = getComputedStyle(document.querySelector('[role="tablist"]>*:last-child .native-text')).color;
if (devMode)
console.log("Theme assignment successful");
}, {
target: document.querySelector(postContainerSelector)
});
// src/styles/style.css
var style_default = '.dialog-screen{background-color:#0000007f;flex-direction:column;justify-content:flex-end;display:flex;position:fixed;inset:0;overflow-y:auto}.settings-container{padding-block:2rem;padding-inline:.5rem;position:relative;& .settings-header{flex-direction:column;gap:.5rem;margin-bottom:1rem;padding:.5rem 1rem;display:flex;& .settings-title{font-size:1.5rem;font-weight:600}}& .settingsItem{grid-template-columns:max-content minmax(0,1fr) max-content;align-items:center;gap:.75rem;min-height:2.5rem;padding:.5rem;display:grid;& *{pointer-events:none}& .settingsIcon{font-size:1.5rem}& .settingsLabel{font-size:1rem;font-weight:600;display:block}& .settingsDescription{white-space:nowrap;text-overflow:ellipsis;width:100%;display:block;overflow:hidden}}}.bg-fallback:before{content:"";z-index:-1;background-color:#242526;width:100%;height:100%;position:absolute;top:0;left:0}.icon-bg-fallback:before{content:"";left:calc((100% - var(--diameter))/2);top:calc((100% - var(--diameter))/2);width:var(--diameter);height:var(--diameter);z-index:-1;background-color:#ffffff1a;border-radius:50%;position:absolute}.fb-check{cursor:pointer;user-select:none;vertical-align:middle;align-items:center;font-family:sans-serif;display:inline-flex;& input{display:none}& .checkmark{border:2px solid;border-radius:3px;width:18px;height:18px;transition:background-color .2s;position:relative}& input:checked+.checkmark{background-color:#1877f2}& input:checked+.checkmark:after{content:"";border:2px solid #fff;border-width:0 2px 2px 0;width:5px;height:10px;position:absolute;top:0;left:4px;transform:rotate(45deg)}}.customBtns{z-index:2;width:45px;height:43px;position:absolute;pointer-events:all!important;settingsBtn{left:calc(100dvw - 138px)}feedsBtn{left:calc(100dvw - 180px)}&>div{z-index:0;--diameter:35px;box-sizing:border-box;flex-direction:column;flex-shrink:0;width:35px;height:35px;margin-top:4px;margin-left:5px;display:flex;position:relative}& img{filter:grayscale();object-fit:contain;width:100%;height:100%;position:absolute}}div[data-purged=true]{pointer-events:none;height:32px;position:relative;overflow-y:hidden;&[data-force-hide=true]{pointer-events:none;height:0;overflow-y:hidden}&>div{display:none!important}& .placeholder{pointer-events:auto;place-items:center;padding-inline:.5rem;display:grid;position:absolute;inset:0;& p{text-overflow:ellipsis;white-space:nowrap;text-align:center;width:100%;overflow:hidden}}}[data-screen-id]:first-child [data-comp-id~="22222"]{display:none!important}#block-counter{z-index:99;color:#ddd;pointer-events:none;background:#323436;border-radius:.2rem;flex-wrap:wrap;gap:.5rem;padding:.5rem 1rem;font-size:.8rem;display:flex;position:fixed;top:0;left:0}#spinner{pointer-events:none;z-index:100;position:fixed;top:20px;left:16px}';
// src/index.ts
(() => {
if (document.body.id !== bodyId) {
console.error("ID 'app-body' not found.");
return;
}
if (!document.head.contains(GM_addStyle(style_default)))
console.error("Failed to add style node");
onReadyForScripting(() => {
console.log("Ready for scripting");
const aborts = [
updateThemeConfigWhenPossible(),
...devMode ? [BlockCounter.getInstance().register()] : [],
WhitelistedFiltersStorage.getInstance().register(),
MenuButtonsInjector.getInstance().inject(),
SettingsMenuInjector.getInstance().inject(),
runFeedsCleaner(),
registerAutoReloadAfterIdle()
];
makeNavbarSticky();
return () => {
console.log("Not Ready for scripting");
aborts.forEach((abort) => abort?.());
aborts.length = 0;
};
});
})();