Skip to content

Instantly share code, notes, and snippets.

@ChronoMonochrome
Last active August 22, 2024 22:01
Show Gist options
  • Save ChronoMonochrome/1ae13f96c6305aac7e9e82656d816009 to your computer and use it in GitHub Desktop.
Save ChronoMonochrome/1ae13f96c6305aac7e9e82656d816009 to your computer and use it in GitHub Desktop.
Block Ads on Yandex
// ==UserScript==
// @name BlockYaAds
// @description Block all ads on yandex.ru
// @version 0.5.6
// @author Chrono
// @license MIT
// @match https://mail.yandex.ru/*
// @match https://*yandex.ru/*
// @run-at document-start
// @grant none
// ==/UserScript==
(function() {
var ignoredClasses = [
"ns-view-abook",
"ns-view-advanced",
"ns-view-app",
"ns-view-attach",
"ns-view-browser",
"ns-view-collect",
"ns-view-compact-header",
"ns-view-compose",
"ns-view-contact-actions",
"ns-view-container",
"ns-view-copy",
"ns-view-fake",
"ns-view-fill",
"ns-view-folders",
"ns-view-footer",
"ns-view-header",
"ns-view-id",
"ns-view-infoline",
"ns-view-labels",
"ns-view-layout",
"ns-view-left",
"ns-view-loading",
"ns-view-mail",
"ns-view-main",
"ns-view-message",
"ns-view-message-react",
"ns-view-messages",
"ns-view-midgets",
"ns-view-mops",
"ns-view-notifi",
"ns-view-opt-in-subs-box",
"ns-view-opt-in-subs-view",
"ns-view-page",
"ns-view-ps-header",
"ns-view-quick",
"ns-view-react-left-column",
"ns-view-react-main-buttons",
"ns-view-react-quick-reply",
"ns-view-right",
"ns-view-service",
"ns-view-setup-abook",
"ns-view-setup-left",
"ns-view-sidebar-with-widgets",
"ns-view-sidebar-with-widgets-box",
"ns-view-system-alert-container",
"ns-view-skin",
"ns-view-tech",
"ns-view-themes",
"ns-view-thread",
"ns-view-timeline",
"ns-view-tip",
"ns-view-toolbar",
"ns-view-view"
];
// for all other subdomains remove all divs but the lists below
var specificIgnoredClasses = [
"AdvRsyaCrossPage",
"App",
"b-page",
"Button",
"Carousel",
"cbir",
"Cbir",
"clearfix",
"copyright",
"Content",
"content",
"detect",
"Divider",
"Extra",
"extra",
"fade",
"favicon",
"Favicon",
"Fetch",
"FewLines",
"Flex",
"Footer",
"footer",
"header",
"Header",
"Host",
"i-bem",
"i-react",
"image_history",
"ImagesViewer-Content",
"ImagesViewer-Footer",
"ImagesViewer-Layout",
"ImagesViewer-Modal",
"ImagesViewer-Paranja",
"ImagesViewer-Rim",
"ImagesViewer-Sidebar",
"ImagesViewer-TopSide",
"ImagesViewer-View",
"internal",
"Justifier",
"main",
"mini",
"List",
"Menu",
"Mini",
"Missing",
"MMFavicon",
"MMImage",
"MMOrganic",
"MMViewer",
"Modal",
"Organic",
"organic",
"overlay",
"navigation",
"Native",
"Open",
"Page",
"page",
"Pager",
"paranja",
"Path",
"path",
"presearch",
"Prevention",
"Related",
"Request",
"Root",
"Search",
"SendTimeMark",
"Serp",
"serp",
"Site",
"site",
"Skeleton",
"smart",
"Spyable",
"Svg",
"Swipe",
"Spin",
"spin",
"text",
"Typo",
"unread",
"User",
"Video",
"Viewer",
"z-index-group"
];
var miscellaneousClasses = [
"Container",
"CardDivider",
"Wrapper",
"Tags"
];
// default element visibility
var elementsVisibility = {};
// paths to exclude filtering on
var excludedPaths = [
"/all",
"/maps",
"/products",
"/search",
"/video/preview"
];
var numElements = 0;
var scriptStarted = false;
var lastRunMillis = 0;
function removeElements(selector, visibility, el) {
var number = 0;
if (visibility != "none") {
elementsVisibility[selector] = visibility;
}
el.style.display = visibility;
}
function hideInnerElements(container) {
container.querySelectorAll("*").forEach(function(innerEl) {
innerEl.style.display = "none";
});
}
var mutationConfig = {
attributes: true,
attributeOldValue: true,
characterData: true,
characterDataOldValue: true,
childList: true,
subtree: true
};
var observer;
function start() {
var isElementFound = false;
var divs = document.getElementsByTagName("div");
var currentUrl = window.location;
var baseUrl = currentUrl.host;
if (Date.now() - lastRunMillis < 300) {
lastRunMillis = Date.now();
return;
}
//console.log("start");
// skip filtering if not implemented
var exit = false;
excludedPaths.forEach(function(path) {
if (window.location.pathname.startsWith(path)) {
console.log(`filtering for ${path} is not implemented`);
exit = true;
return;
}
});
if (exit) return;
var rootNodes = document.getElementsByClassName("Root");
for (var i = 0; i < rootNodes.length; i++) {
var rootNode = rootNodes[i];
if (rootNode) {
if (rootNode.firstChild != undefined) {
if (rootNode.firstChild.classList != []) {
var ignoredClass = rootNode.firstChild.classList[0];
//console.log(ignoredClass + " is the root, skipping");
specificIgnoredClasses.push(ignoredClass);
}
}
}
}
// Specific case for "docviewer.yandex.ru"
if (baseUrl === "docviewer.yandex.ru") {
document.querySelectorAll("*").forEach(function(el) {
el.classList.forEach(function(className) {
if (className === "js-doc-html") {
var innerElements = el.querySelectorAll("*");
innerElements.forEach(function loop(el1) {
if (loop.stop) {
return;
}
if ((el1.tagName === "DIV") && el1.classList.length === 3) {
removeElements("." + el1.classList[0], "none", el);
loop.stop = true;
}
});
}
});
if (el.tagName.length > 10) {
el.style.display = "none";
}
});
}
for (i = 0; i < divs.length; i++) {
var div = divs[i];
if (window.location.pathname === "/images/search") {
var style = div.getAttribute("style");
if (style === "margin-bottom: 4px;" || div.offsetHeight === 72) {
div.classList.forEach(function(className) {
removeElements("." + className, "none", div);
});
}
}
div.classList.forEach(function(className) {
// Match classes for "mail.yandex.ru"
if ((baseUrl === "mail.yandex.ru") && !className.startsWith("ns-view-")) {
return;
}
// Classes to ignore
isElementFound = true;
// Hide specific class
if (className === "ComposeDoneDirect") {
removeElements("." + className, 'none', div);
}
for (var j = 0; j < miscellaneousClasses.length; j++) {
if (className.indexOf(miscellaneousClasses[j]) !== -1) {
isElementFound = false;
removeElements("." + className, elementsVisibility[className], div);
return;
}
}
for (j = 0; j < ignoredClasses.length; j++) {
if (className.startsWith(ignoredClasses[j])) {
isElementFound = false;
removeElements("." + className, elementsVisibility[className], div);
return;
}
}
if (className === "ImagesViewer") {
isElementFound = false;
removeElements("." + className, elementsVisibility[className], div);
return;
}
for (j = 0; j < specificIgnoredClasses.length; j++) {
if (className.startsWith(specificIgnoredClasses[j])) {
isElementFound = false;
}
}
if (className == "ImagesViewer-LayoutSideblock") {
console.log("ImagesViewer-LayoutSideblock");
if (div.firstChild.classList != undefined) {
div.firstChild.classList.forEach(function(imagesViewerClassName) {
if (!specificIgnoredClasses.includes(imagesViewerClassName)) {
console.log("found LayoutSideblock first child div");
specificIgnoredClasses.push(imagesViewerClassName);
}
});
}
}
if (isElementFound) {
console.log("Removed element with class:", className);
numElements = removeElements("." + className, "none", div);
}
});
if (baseUrl === "mail.yandex.ru" && numElements != 0) {
//console.log("disconnecting observer");
//observer.disconnect();
}
}
}
observer = new MutationObserver(start);
function deferredStart() {
setTimeout(function() {
if (document.body instanceof Node && !scriptStarted) {
lastRunMillis = Date.now();
observer.observe(document.body, mutationConfig);
scriptStarted = true;
}
deferredStart();
}, 200);
}
deferredStart();
console.log("BlockYaAds script is running.");
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment