Remove ad posts from VK.com

removes ad posts from feed and walls by keywords

2018-05-07 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name            Remove ad posts from VK.com
// @version         0.7.20180507.2
// @description	    removes ad posts from feed and walls by keywords
// @match           *://*.vk.com/*
// @grant           none
// @copyright       2016, StSav012
// @author          StSav012
// @namespace       vkap
// @run-at          document-idle
// ==/UserScript==

"use strict";

var actualCode = '(' + function() {
	"use strict";
	var keywords = [
		"РЕПОСТ", "REPOST",
		"д(е|e)л(а|a)ть (|\")(р|p)(е|e)п(о|o)(с|c)т(|\")", "д(е|e)л(а|a)й(т|)(е|e|) (|\")(р|p)(е|e)п(о|o)(с|c)т(|\")",
		"делавшему (|\")(р|p)(е|e)п(о|o)(с|c)т(|\")", "(Р|р|P|p)(е|e)п(о|o)(с|c)т( этой| данной|) записи",
		"(П|п)одели(ться|сь)(| этой|этим) (записью|сообщением)",
		"(р|p)(е|e)п(о|o)(с|c)тни этот пост",
		"(а|a)йк(и|)( и|,) (р|p)(е|e)п(о|o)(с|c)т(ы|)",
		"(З|з)абирай(|те)(| себе) на стену", "(С|с)охрани(|ть|те)(| себе) (на стену|этот пост)",
		"(З|з)акрепить( эту запись| ее| её)( у себя|) на стене",
		"озыгрыш по репосту", "репоснет эту запись", "за репост даем", "бонус за репост",
		"ВСТУПАЙ(ТЕ|)", "ВСТУПИТЕ", "(В|в)ступ(и|ить|аем|ите|айте|ай) в(| нашу| эту) (группу|сообщество)",
		"(В|в)ступай(|те)",
		"БЫТЬ ПОДПИСАННЫМ(|И) НА СООБЩЕСТВО", "(та|ы)ть( нашим|) (подписчиком|участником)",
		"(С|с) (В|в)ас репост и (быть|стать) мои другом",
		"ДОБАВЬ", "ДОБАВЛЯЙТЕ", "(Д|д)обавляй(|ся|тесь)(| ко мне) в друзья",
		"Зайди(|те) поглазеть на эти посты", "Заходи(|те) на раздач(у|и)",
		"ОСТАВЬ(|ТЕ) ЗАЯВКУ", "(О|о)ставь(|те) заявку",
		"Регистрация всего за", "Регистрация пока бесплатна", "Успей зарегистрироваться",
		"ЗАПИШИСЬ НА ",
		"БЕСПЛАТН", "бесплатно дадим", "Получить бесплатн", "бесплатно откроем (В|в)ам",
		"качать бесплатно",
		"ПОДАРОК",
		"СКИДК(А|И|ОК|У|ОЙ|Е)", "Выбирай со скидкой", "с нереальными скидками", "дарим скидку", "Скидки на весь ассортимент",
		"(С|с)делать это со скидкой",
		"За репост скидка",
		"Заказ(атъ|ать|ывайте|ывай) со скидкой",
		"ВЫИГРАЙ", "получи шанс выиграть", "Выигрaй",
		"КОНКУРС", "Внимание! Конкурс!",
		"АКЦИ(Я|И|Ю|ЕЙ)", "Мега-Акция", "Акция до конца", "#акция",
		"РОЗЫГРЫШ", "Ссылка на розыгрыш", "в сообществе проходит супер-розыгрыш", "(У|у)частвуй(те|) в (Р|р)озыгрыше",
		"(Р|р)озыгрыш только для подписчиков",
		"(Т|т)олько (для|среди) (подписч|участн)иков(| нашей| этой| нашего| этого) (группы|сообщества)",
		"обедител(и|ь) буд(у|е)т выбран(ы|) случайным образом",
		"РАСПРОДАЖА", "Последняя распродажа топовых", "Ликвидация склада",
		"Успейте оставить заявку", "Успейте забронировать", "Спешите получить",
		"СКОРО ОТКРЫТИЕ",
		"Записывайтесь на бесплатное занятие",
		"ПОДПИШИСЬ", "ПОДПИСЫВАЙСЯ", "(П|п)одпишись", "(П|п)одпишитесь (на|-|\\+) ", "(П|п)одписывай(ся|тесь) (на|-|\\+) ",
		"(П|п)одписывайся", "(П|п)одписываемся!",
		"ыть подписчиком", "ыть подписанным", "(П|п)одписался на", "(П|п)одписаться", "(П|п)одпишись и ты",
		"(П|п)одписаться на (группу|паблик|сообщество)", "(П|п)одписаться на канал можно здесь",
		"(П|п)одписаться \\+", "\\+ Подписаться", "Приглашаем подписаться на",
		"(П|п)одписывай на ", "забывайте подписываться на", "\">Подписывайтесь<\\/",
		"КУПИТЬ", "ЗАКАЖИТЕ", "Заказать можно тут", "(С|с)делайте заказ прямо сейчас",
		"Подарок можно забрать", "Вы сможете забрать ваш подарок", "Быстрая доставка",
		"бизнес-(план|проект)",
		"Читать продолжение ", "Читaйтe пoлнocтью здecь", "Смотреть ответ в источнике",
		"Подробн(ее|ости)( акции|) (здесь|на странице)", "Ты должен видеть это", "Ты должен это видеть", "зна(ть|й|вайте) подробн(ее|ости)",
		"(мотрите|ереходите) по ссылке", "Условия акции можно найти здесь", "смотреть дальше", "больше подробностей внутри",
		"Узнай(|,)( как|)(|,) тут", // ← facepalm
		"Центр образовательных технологий Advance",
		"«Как развить свою память» или «Секреты эффективного обучения»",
		"Начни играть тут", "начни играть в", "Играй тут", "Качай игру",
		"NovaPizza.ru", "skypeteach.ru", "english4now.com", "advance-club.ru", "sdelano.ru", "edgarkulikov.ru", "citystarwear.com",
		"befree-school.ru", "bright-shopping.ru", ".sale-gooods.ru", "www.kopikot.ru", ".bebetter.guru", "www.in-build.ru",
		"1media-buyer.ru", "itunes.apple.com%2Fapp%2Fapple-store%2Fid695634432", "sale-stop.ru", "offersboard.ru", "artskills.ru",
		"elementaree.ru", "start-mobile.net", ".hitnsale.ru", "вконкурс.рф", "printbar.ru", "tracking.leaddealer.net", "envylab.ru",
		"job.beeline.ru",
		"newstockgeneration.space", "zarabotays.ru", "zarabotoki.ru", "zarabotokgames.ru", ".advertapp.ru",	// suspicious sites
		"class=\"wall_marked_as_ads\"",	"class=\"pi_signed ads_mark\"",// to avoid ads from groups
		//"ads_promoted_post",	// to avoid promoted posts; reused later
		"app_title_"	// that's to avoid ads from games
	];
	var urls = [
		"/domavern", "/businessstrategy", "/virashopru", "/tri10oe", "/kinona5", "/watson_club", "/brutal_kitchen",
		"/vkchydaku", "/brandclubkiiik", "/princapioff", "/illusthigh", "/chestnoeauto", "/otdamdarom"
	];
	var banned_reposts_from = [         // no reposts by these groups and users are shown
		"/rhymesee"
	];
	var selectors = [
		"div.reply",
		"div.feed_row, div.wall_item, div.post_copy, div.post_fixed, div#page_wall_posts>div.page_block"
	];
	var dom_ad = [	// beware: these rules might break the site
        "div.wall_item.feedAssistance",	    // to hide friends suggestions (arguable)
		"div.ads_ad_box",
		"div[data-ad-block-uid]"
	];
	var divs;	// selected tags list
	function cleanAd() {
		for (let s of selectors) {
			divs = document.querySelectorAll(s);
			for (let d of divs) {				// we check it from the very beginning and to the end
				if (d.getAttribute('no_ad') != 'true') {	// from https://greasyfork.org/ru/scripts/1978-vk-com-no-politic-feed/code
					// does it worth checking the post?
					var eliminated = false;
					for (let w of keywords) {
						var pattern = new RegExp(w);
						if (pattern.test(d.innerHTML)) {
							// d.style.backgroundColor = "red"; // ← for debugging purposes
                            // console.log(d); // ← for debugging purposes
							d.parentNode.removeChild(d);
							eliminated = true;
							break;
						}
					}
					if (!eliminated) {
						for (let u of urls) {
							if (!window.location.pathname.includes(u) && d.innerHTML.includes(u)) {
								// d.style.backgroundColor = "red"; // ← for debugging purposes
                                // console.log(d); // ← for debugging purposes
								d.parentNode.removeChild(d);
								eliminated = true;
								break;
							}
						}
					}
                    if (!eliminated) {
                        for (let br of banned_reposts_from) {
                            if (d.innerHTML.includes("<a class=\"author\" href=\"" + br + "\"") &&
                                d.innerHTML.includes("class=\"copy_quote\"")) {
								// d.style.backgroundColor = "red"; // ← for debugging purposes
                                // console.log(d); // ← for debugging purposes
								d.parentNode.removeChild(d);
								eliminated = true;
								break;
							}
                        }
                    }
					if (!eliminated && d.querySelector("span.wall_copy_more") === null) {
						d.setAttribute('no_ad', 'true');
					}
				}
			}
		}
		for (let a of dom_ad) {
			divs = document.querySelectorAll(a);
			for (let ad of divs) {
				ad.parentNode.removeChild(ad);
			}
		}
	}
	cleanAd();
	// see http://stackoverflow.com/a/14570614
	var observeDOM = (function() {
		var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
			eventListenerSupported = window.addEventListener;

		return function(obj, callback) {
			if (MutationObserver) {
				// define a new observer
				var obs = new MutationObserver(function(mutations) {
					if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) {
						callback();
					}
				});
				// have the observer observe foo for changes in children
				obs.observe(obj, {childList: true, subtree: true});
			}
			else if (eventListenerSupported) {
				obj.addEventListener('DOMNodeInserted', callback, false);
				obj.addEventListener('DOMNodeRemoved', callback, false);
			}
		};
	})();
	var containers = document.querySelectorAll('body');
	for (let c of containers) {
		observeDOM(c, cleanAd);
	}
} + ')();';
var script = document.createElement('script');
script.textContent = actualCode;
(document.body||document.documentElement).appendChild(script);