NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name BlockYaAds // @description Block all ads on yandex.ru // @version 0.6.9 // @author Chrono // @license MIT // @match https://mail.yandex.ru/* // @match https://*yandex.ru/* // @match https://*yandex.eu/* // @match https://ya.ru/* // @run-at document-start // @grant none // ==/UserScript== (function() { var ignoredClasses = [ "_", "Aside", "Attach", "Avatar", "Badge", "Button2-Icon", "ButtonGroup", "ButtonGroup_gap_xl", "ButtonWithIcon-m__iconWrap", "cke", "CollapsibleToolbar__overflow", "CollapsibleToolbar__visible", "CollapsibleToolbar__zeroWidth", "CollectorIcon-m__root", "Collectors-m__root", "compose", "Compose", "Contact", "ContentHeader-m__header", "Control", "cut", "Cut", "dialog", "MidgetsPanel", "Separator", "Expander", "Filter-m__root", "Filters", "Folder", "Footer-m__footerContainer", "FooterItem-m__item", "Header", "HeaderSearch-m__root", "Image-Container", "Labels-m__root", "LabelsExpander-m__root", "Layout-m__root", "LeftColumn", "MainButtons", "MainContent", "Message", "Messenger", "PageLayout", "Popup", "PSHeader", "Prev", "Quote", "Recipient", "Related", "Right", "Root", "Section", "Sender", "Spin", "StatuslineRoot-m__root", "Svg360_root", "Tag-m__icon", "Tag-m__root", "Text", "Title", "Theme", "ToggleSelectedAction__root", "tooltip", "Tooltip", "User", "With", "WrappingList-m__extra", "WrappingList-m__item", "WrappingList-m__root", "WrappingList-m__tail", "WrappingList-m__withExtra", "WrappingList-m__withTail", "b-", "common-m__withGhostButton", "g-hidden", "is-collapsed", "js", "mail", "message-list-banner-portal", "messages-date-pager-float-box", "mid", "mr_css", "new__root", "ns-action", "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-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-promo-container", "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-skin", "ns-view-system-alert-container", "ns-view-tech", "ns-view-themes", "ns-view-themes-messages-list-control", "ns-view-themes-selector-box", "ns-view-themes-skin-rotater-box", "ns-view-thread", "ns-view-timeline", "ns-view-timeline-box", "ns-view-timeline-collapsed", "ns-view-timeline-loader-box", "ns-view-timeline-toggle", "ns-view-timeline-wrap", "ns-view-tip", "ns-view-toolbar", "ns-view-toolbar-box", "ns-view-view", "qa", "react", "ScreenLayer", "search", "styles__buttons", "styles__item", "styles__messages", "styles__root", "styles__wrapper", "theme-overrides-m__root", "ui-dialog", "ui-widget", "ui-corner", "ui-front", "_nb-popup", "nb-popup", "ui-resizable-handle", "ui-resizable-s" ]; // 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", // ya.ru classes "headline", "weather", "usermenu-portal", "body", "search3", "link-bro", "i-mini-bem", "simple-popup" ]; var miscellaneousClasses = [ "Container", "CardDivider", "Wrapper", "Tags" ]; // default element visibility var elementsVisibility = {}; // paths to exclude filtering on var excludedPaths = [ "/all", "/maps", "/products", "/search", "/showcaptcha", "/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 containsAnyIgnoredClass(div, ignoredClasses) { const divClasses = Array.from(div.classList); return divClasses.some(divClass => ignoredClasses.some(ignoredClass => divClass.indexOf(ignoredClass) !== -1) ); } function start() { var isElementFound = false; var divs = document.querySelectorAll('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"; } }); } // Match classes for "mail.yandex.ru" if (baseUrl === "mail.yandex.ru") { divs.forEach(div => { // Check if div has any classes if (div.classList.length > 0) { // Only process divs with at least one class if (!containsAnyIgnoredClass(div, ignoredClasses)) { div.remove(); console.log(div) } } }); } 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 anything but "mail.yandex.ru" if (baseUrl === "mail.yandex.ru") { return; } // if (currentUrl == "https://ya.ru") { 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; } } 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."); })();