您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add some function on site "vk.com"
// ==UserScript== // @name VK Mod // @name:ru Мод для Вконтакте // @namespace SoThUg // @version 0.11 // @description Add some function on site "vk.com" // @description:ru Добавляет разные функции на сайт вконтакте // @author SoThUg // @icon https://github.com/sothug/vk-mod/blob/master/icon.png?raw=true // @match *://vk.com/* // @match *://*.vk.com/* // @start-at document-start // @grant none // ==/UserScript== "use strict" const script_name = "VK Mod" const storageName = "vk_mod_preference" const DNTName = "vk_mod_do_not_type" const DNRName = "vk_mod_do_not_read" const default_storage = { ads_left: true, ads_block: true, marked_as_ads: true, story: false, recom_friend: true, recom_app: true, popul_clips: true, round: true, audio_ads: true, dnr: true, dnr_audio: true, dnt: true, dnt_audio: true, getDeep: 100 } // vars on window var vk = {id: 0}, // window.vk ap, // window.ap - аудиоплеер cur = {peer: 0}, // window.cur vkMod, // window.vkMod w, // window uiActionsMenu, // window.uiActionsMenu TopMenu // window.TopMenu var get = { varOnWindow(id, callback = null, deep = 1) { if (!isrtype(id, "", "get.varOnWindow")) { return false } if (!!w[id]) { console.debug(`get.varOnWindow: ${id} успешно получен`) callback.call(this, id, w[id]) return true } if (deep > get.deep) { console.error(`get.varOnWindow: ${id} - превышен лимит ожидания(${get.deep})`) return false } w.setTimeout(get.varOnWindow, 100, id, callback, deep + 1) console.debug(`get.varOnWindow: ${id} - ожидание(${deep})`) }, elementOnDOM(id, callback = null, deep = 1) { if (!isrtype(id, "", "get.elementOnDOM")) { return false } if (document.querySelectorAll(id).length) { console.debug(`get.elementOnDOM: "${id}" успешно получен`) callback.call(this, id, document.querySelectorAll(id)) return true } if (deep > get.deep) { console.error(`get.elementOnDOM: "${id}" - превышен лимит ожидания(${get.deep})`) return false } w.setTimeout(get.elementOnDOM, 100, id, callback, deep + 1) console.debug(`get.elementOnDOM: "${id}" - ожидание(${deep})`) } } Object.defineProperty(get, "deep", { get: () => {return getStorageForId(storageName, vk.id)["getDeep"]}, set: (val) => {setStorageForId(storageName, "getDeep", val, vk.id)}, enumerable: true, configurable: true }) var menu = { html: ` <div id="vk_mod_menu"> <div id="vk_mod_menu_bg" onclick="vkMod.menu.close()"></div> <div id="vk_mod_menu_wrap"> <div class="popup_box_container" style="width: fit-content;height: auto;margin-top: 15vh;z-index: 10500;position: relative;" tabindex="0"> <div class="box_layout"> <div class="vk_mod_menu_box_title box_title_wrap" style=""> <div class="box_x_button" aria-label="Закрыть" tabindex="0" role="button" onclick="vkMod.menu.close()"></div> <div class="box_title_controls" style="display: none;">Здесь что-то может быть</div> <div class="box_title">Настройки VK Mod</div> </div> <div class="vk_mod_menu_box_body box_body" style="display: block;padding: 1vh 2vh 1vh 2vh"> <div class="settings_line"> <div class="settings_label">Реклама</div> <div class="settings_labeled_text"> <div class="settings_labeled_row"> <input id="vk_mod_settigns_ads_left" type="checkbox" class="vk_mod_input _checkbox input_ads_left" onchange=" vkMod.setStorageForId('vk_mod_preference', 'ads_left', document.getElementsByClassName('input_ads_left')[0].checked, vk.id); vkMod.styles.updateStyles('ads_left') vkMod.menu.updateInputs('ads_left') "> <label for="vk_mod_settigns_ads_left">Выключить рекламу слева</label> </div> <div class="settings_labeled_row"> <input id="vk_mod_settigns_ads_block" type="checkbox" class="vk_mod_input _checkbox input_ads_block" onchange=" vkMod.setStorageForId('vk_mod_preference', 'ads_block', document.getElementsByClassName('input_ads_block')[0].checked, vk.id); vkMod.styles.updateStyles('ads_block') vkMod.menu.updateInputs('ads_block') "> <label for="vk_mod_settigns_ads_block">Выключить блок "Рекламная запись"</label> </div> <div class="settings_labeled_row"> <input id="vk_mod_settigns_marked_as_ads" type="checkbox" class="vk_mod_input _checkbox input_marked_as_ads" onchange=" vkMod.setStorageForId('vk_mod_preference', 'marked_as_ads', document.getElementsByClassName('input_marked_as_ads')[0].checked, vk.id); vkMod.styles.updateStyles('marked_as_ads') vkMod.menu.updateInputs('marked_as_ads') "> <label for="vk_mod_settigns_marked_as_ads">Выключить посты с проплаченной рекламой</label> </div> </div> </div> <div class="settings_line"> <div class="settings_label">Лента новостей</div> <div class="settings_labeled_text"> <div class="settings_labeled_row"> <input id="vk_mod_settigns_recom_friend" type="checkbox" class="vk_mod_input _checkbox input_recom_friend" onchange=" vkMod.setStorageForId('vk_mod_preference', 'recom_friend', document.getElementsByClassName('input_recom_friend')[0].checked, vk.id); vkMod.styles.updateStyles('recom_friend') vkMod.menu.updateInputs('recom_friend') "> <label for="vk_mod_settigns_recom_friend">Включить "Рекомендованные друзья"</label> </div> <div class="settings_labeled_row"> <input id="vk_mod_settigns_recom_app" type="checkbox" class="vk_mod_input _checkbox input_recom_app" onchange=" vkMod.setStorageForId('vk_mod_preference', 'recom_app', document.getElementsByClassName('input_recom_app')[0].checked, vk.id); vkMod.styles.updateStyles('recom_app') vkMod.menu.updateInputs('recom_app') "> <label for="vk_mod_settigns_recom_app">Включить блок "Рекомендованные приложения"</label> </div> <div class="settings_labeled_row"> <input id="vk_mod_settigns_popul_clips" type="checkbox" class="vk_mod_input _checkbox input_popul_clips" onchange=" vkMod.setStorageForId('vk_mod_preference', 'popul_clips', document.getElementsByClassName('input_popul_clips')[0].checked, vk.id); vkMod.styles.updateStyles('popul_clips') vkMod.menu.updateInputs('popul_clips') "> <label for="vk_mod_settigns_popul_clips">Включить блок "Популярные клипы"</label> </div> </div> </div> <div class="settings_line"> <div class="settings_label">Интерфейс</div> <div class="settings_labeled_text"> <div class="settings_labeled_row"> <input id="vk_mod_settigns_story" type="checkbox" class="vk_mod_input _checkbox input_story" onchange=" vkMod.setStorageForId('vk_mod_preference', 'story', document.getElementsByClassName('input_story')[0].checked, vk.id); vkMod.styles.updateStyles('story') vkMod.menu.updateInputs('story') "> <label for="vk_mod_settigns_story">Выключить блок историй</label> </div> <div class="settings_labeled_row"> <input id="vk_mod_settigns_round" type="checkbox" class="vk_mod_input _checkbox input_round" onchange=" vkMod.setStorageForId('vk_mod_preference', 'round', document.getElementsByClassName('input_round')[0].checked, vk.id); vkMod.styles.updateStyles('round') vkMod.menu.updateInputs('round') "> <label for="vk_mod_settigns_round">Включить закругления</label> </div> </div> </div> <div class="settings_line"> <div class="settings_label">Аудио</div> <div class="settings_labeled_text"> <div class="settings_labeled_row"> <input id="vk_mod_settigns_audio_ads" type="checkbox" class="vk_mod_input _checkbox input_audio_ads" onchange=" vkMod.setStorageForId('vk_mod_preference', 'audio_ads', document.getElementsByClassName('input_audio_ads')[0].checked, vk.id); vkMod.menu.updateInputs('audio_ads') "> <label for="vk_mod_settigns_audio_ads">Выключить рекламу в аудиоплеере</label> </div> </div> </div> <div class="settings_line"> <div class="settings_label">Активность</div> <div class="settings_labeled_text"> <div class="settings_labeled_row"> <input id="vk_mod_settigns_dnr" type="checkbox" class="vk_mod_input _checkbox input_dnr" onchange=" vkMod.setStorageForId('vk_mod_preference', 'dnr', document.getElementsByClassName('input_dnr')[0].checked, vk.id); vkMod.menu.updateInputs('dnr') "> <label for="vk_mod_settigns_dnr" class="label_for_checkbox">Нечиталка</label> </div> <div class="settings_labeled_row"> <input id="vk_mod_settigns_dnr_audio" type="checkbox" class="vk_mod_input _checkbox input_dnr_audio" onchange=" vkMod.setStorageForId('vk_mod_preference', 'dnr_audio', document.getElementsByClassName('input_dnr_audio')[0].checked, vk.id); vkMod.menu.updateInputs('dnr_audio') "> <label for="vk_mod_settigns_dnr_audio" class="label_for_checkbox">Нечиталка голосовых</label> </div> <div class="settings_labeled_row"> <input id="vk_mod_settigns_dnt" type="checkbox" class="vk_mod_input _checkbox input_dnt" onchange=" vkMod.setStorageForId('vk_mod_preference', 'dnt', document.getElementsByClassName('input_dnt')[0].checked, vk.id); vkMod.menu.updateInputs('dnt') "> <label for="vk_mod_settigns_dnt">Неписалка</label> </div> <div class="settings_labeled_row"> <input id="vk_mod_settigns_dnt_audio" type="checkbox" class="vk_mod_input _checkbox input_dnt_audio" onchange=" vkMod.setStorageForId('vk_mod_preference', 'dnt_audio', document.getElementsByClassName('input_dnt_audio')[0].checked, vk.id); vkMod.menu.updateInputs('dnt_audio') "> <label for="vk_mod_settigns_dnt_audio">Неписалка голосовых</label> </div> </div> </div> <div class="settings_line"> <div class="settings_label">Системные</div> <div class="settings_labeled_text"> <div class="settings_labeled_row"> <input id="vk_mod_settigns_getDeep" type="number" class="vk_mod_input _number input_getDeep dark" onchange=" vkMod.setStorageForId('vk_mod_preference', 'getDeep', document.getElementsByClassName('input_getDeep')[0].value, vk.id); vkMod.menu.updateInputs('getDeep') "> <label for="vk_mod_settigns_getDeep">Глубина ожидания переменной</label> </div> <div class="settings_labeled_row"> <button id="vk_mod_settigns_updateInputs" class="vk_mod_button button_updateInputs flat_button dark" onclick="vkMod.menu.updateInputs()"> Обновить поля ввода в меню </button> </div> <div class="settings_labeled_row"> <button id="vk_mod_settigns_updateStyles" class="vk_mod_button button_updateStyles flat_button dark" onclick="vkMod.styles.updateStyles()"> Обновить стили </button> </div> </div> </div> </div> <div class="box_controls_wrap"> <div class="box_controls"> <table cellspacing="0" cellpadding="0" class="fl_r"> <tbody> <tr><td> <button class="flat_button secondary has_tooltip" onclick="vkMod.setStorage('vk_mod_preference', vk.id, vkMod.default_storage); vkMod.menu.updateInputs(); vkMod.styles.updateStyles()"> Настройки по умолчанию <span class="tooltiptext">Устанавливает настройки по умолчанию</span> </button> <button class="flat_button has_tooltip" onclick="location.href='https://vk.me/join/AJQ1d94uiBiCO4Ymc0eeuD_f'"> Перейти в беседу <span class="tooltiptext">Откроет беседу обсуждения данного мода</span> </button> </td></tr> </tbody> </table> <div class="box_controls_text _box_controls_text">VK Mod 0.11</div> </div> <div></div> </div> </div> </div> </div> </div> `, updateInputs(id = undefined) { if (id) { let el = document.getElementsByClassName(`input_${id}`)[0] if (getStorageForId(storageName, vk.id)[id] == undefined) { setStorageForId(storageName, id, default_storage[id], vk.id) } console.debug("updateInputs:", id, getStorageForId(storageName, vk.id)[id]) if (el.type == "number") { el.value = getStorageForId(storageName, vk.id)[id] } if (el.type == "checkbox") { el.checked = getStorageForId(storageName, vk.id)[id] } } else { let inputs_class = ["ads_left", "ads_block", "marked_as_ads", "story", "recom_friend", "recom_app", "popul_clips", "round", "audio_ads", "dnr", "dnr_audio", "dnt", "dnt_audio", "getDeep"] inputs_class.forEach((e, i, a) => { let el = document.getElementsByClassName(`input_${e}`)[0] if (getStorageForId(storageName, vk.id)[e] == undefined) { setStorageForId(storageName, e, default_storage[e], vk.id) } console.debug("updateInputs:", e, getStorageForId(storageName, vk.id)[e]) if (el.type == "number") { el.value = getStorageForId(storageName, vk.id)[e] } if (el.type == "checkbox") { el.checked = getStorageForId(storageName, vk.id)[e] } }) } }, show() { if (!document.getElementById("vk_mod_menu")) { document.body.insertAdjacentHTML("afterBegin", menu.html) } if (!document.getElementById("vk_mod_style_menu")) { document.head.insertAdjacentHTML("beforeEnd", styles.menu) } menu.updateInputs() }, close() { if (document.getElementById("vk_mod_menu")) { document.getElementById("vk_mod_menu").remove() } if (document.getElementById("vk_mod_style_menu")) { document.getElementById("vk_mod_style_menu").remove() } } } var styles = { menu: ` <style id="vk_mod_style_menu"> [dir] #vk_mod_menu_bg { background: rgba(0, 0, 0, 0.7); } [dir=ltr] #vk_mod_menu, #vk_mod_menu_bg { left: 0; } #vk_mod_menu, #vk_mod_menu_bg { position: fixed; width: 100%; height: 100%; z-index: 10000; top: 0; } .vk_mod_menu_box_body { max-height: 50vmin; overflow-y: auto; } .vk_mod_input._number { width: 10vmax; } [dir] .settings_line { margin: 0; padding: 15px 0 14px; border-bottom: 1px solid var(--steel_gray_80); } [dir=ltr] .settings_label { padding: 6px 10px 6px 0; float: left; } .settings_label { color: var(--gray_600); width: 145px; line-height: 16px; } [dir=ltr] .settings_labeled_text { margin: 0 0 8px 155px; } [dir] .settings_labeled_text { padding-top: 6px; } .settings_labeled_row { margin-bottom: 5px; } .has_tooltip { display: inline-block !important; } .has_tooltip ._underlined { border-bottom: 1px dotted black; } .has_tooltip .tooltiptext { visibility: hidden !important; opacity: 0; transition: 0.5s; background-color: black; color: #fff; text-align: center; border-radius: 6px; padding: 5px; position: absolute !important; z-index: 150000; } .has_tooltip:hover .tooltiptext { visibility: visible !important; opacity: 1; transition: 0.5s 0.5s; z-index: 150000; } </style> `, ads_left: ` <style id="vk_mod_style_ads_left"> #ads_left { display: none !important; } </style> `, ads_block: ` <style id="vk_mod_style_ads_block"> ._ads_block_data_w { display: none !important; } </style> `, marked_as_ads: ` <style id="vk_mod_style_marked_as_ads"> .marked_as_ads { display: none !important; } </style> `, story: ` <style id="vk_mod_style_story"> .stories_feed_wrap, .page_story_photo { display: none !important; } </style> `, recom_friend: ` <style id="vk_mod_style_recom_friend"> .feed_friends_recomm { display: none !important; } </style> `, recom_app: ` <style id="vk_mod_style_recom_app"> .apps_feedRightAppsBlock { display: none !important; } </style> `, popul_clips: ` <style id="vk_mod_style_popul_clips"> .ShortVideoFeedBlock { display: none !important; } </style> `, round: ` <style id="vk_mod_style_round"> .flat_button.profile_btn_cut_right { border-radius: 0px 10px 10px 0px !important; } .flat_button.profile_btn_cut_left { border-radius: 10px 0px 0px 10px !important; } .page_block, .eltt, #top_profile_menu, .ts_cont_wrap, .flat_button, .token, .left_count_wrap, .ms_items_more, .BaseModal__content, .ChatSettings, .ui_actions_menu, .page_actions_wrap, .submit_post_field, .box_no_title.box_no_buttons { border-radius: 10px !important; } .ui_search_input_block { border-radius: 8px !important; } .page_block_header, .page_block_h2, .ui_tabs_header, .box_title_wrap, .page_cover, .PopupHeader, .box_no_title, .ui_tabs, .ui_tabs_box { border-radius: 10px 10px 0px 0px !important; } .box_controls, .box_no_buttons, .ChatSettings__content { border-radius: 0px 0px 10px 10px !important; } </style> `, updateStyles(id = undefined) { if (id) { let el = document.getElementById(`vk_mod_style_${id}`) if (getStorageForId(storageName, vk.id)[id] == undefined) { setStorageForId(storageName, id, default_storage[id], vk.id) } console.debug("updateStyles:", id, getStorageForId(storageName, vk.id)[id]) if (getStorageForId(storageName, vk.id)[id] && !el) { document.head.insertAdjacentHTML("beforeEnd", styles[id]) } if (!getStorageForId(storageName, vk.id)[id] && el) { el.remove() } } else { let styles_list = ["ads_left", "ads_block", "marked_as_ads", "story", "recom_friend", "recom_app", "popul_clips", "round"] styles_list.forEach((e, i, a) => { let el = document.getElementById(`vk_mod_style_${e}`) if (getStorageForId(storageName, vk.id)[e] == undefined) { setStorageForId(storageName, e, default_storage[e], vk.id) } console.debug("updateStyles:", e, getStorageForId(storageName, vk.id)[e]) if (getStorageForId(storageName, vk.id)[e] && !el) { document.head.insertAdjacentHTML("beforeEnd", styles[e]) } if (!getStorageForId(storageName, vk.id)[e] && el) { el.remove() } }) } } } function getStorage(name = storageName) { let storage = JSON.parse(localStorage.getItem(name)) if ((name == storageName) && !storage) { return default_storage } return storage || {} } function getStorageForId(name, id) { let storage = JSON.parse(localStorage.getItem(name)) if ((name == storageName) && !storage) { return default_storage } return storage[id] || {} } function setStorage(name, key, value) { console.debug("setStorage(", name, ',', key, ',', value, ')') let storage = getStorage(name) storage[key] = value localStorage.setItem(name, JSON.stringify(storage)) } function setStorageForId(name, key, value, id) { console.debug("setStorageForId(", name, ',', key, ',', value, ',', id, ')') let storage = getStorage(name), storage_for_id = storage[id] || {} storage_for_id[key] = value storage[id] = storage_for_id localStorage.setItem(name, JSON.stringify(storage)) } function getDNTStatus(id) { return !(getStorageForId(storageName, vk.id)["dnt_preference"] || '').match(`.${id}.`) } function setDNTStatus(id, val = true) { console.debug("setDNTStatus(", id, ",", val, ")") let DNT = (getStorageForId(storageName, vk.id)["dnt_preference"] || '') if (val && DNT.match(`.${id}.`)) { setStorageForId(storageName, "dnt_preference", DNT.replace(`.${id}.`, ""), vk.id) } if (!val && !DNT.match(`.${id}.`)) { setStorageForId(storageName, "dnt_preference", DNT + `.${id}.`, vk.id) } } function getDNRStatus(id) { return !(getStorageForId(storageName, vk.id)["dnr_preference"] || '').match(`.${id}.`) } function setDNRStatus(id, val = true) { console.debug("setDNRStatus(", id, ",", val, ")") let DNR = (getStorageForId(storageName, vk.id)["dnr_preference"] || '') if (val && DNR.match(`.${id}.`)) { setStorageForId(storageName, "dnr_preference", DNR.replace(`.${id}.`, ""), vk.id) } if (!val && !DNR.match(`.${id}.`)) { setStorageForId(storageName, "dnr_preference", DNR + `.${id}.`, vk.id) } } function postsAds(id, oldVal, val) { switch (id) { case "cur": console.log(val.wallPage || val.rowsCont) if (getStorageForId(storageName, vk.id)["marked_as_ads"] == undefined) { setStorageForId(storageName, "marked_as_ads", default_storage["marked_as_ads"], vk.id) } let post_page = (val.wallPage || val.rowsCont) if (getStorageForId(storageName, vk.id)["marked_as_ads"] && post_page) { post_page.getElementsByClassName("wall_marked_as_ads").forEach((e, i, a) => { e.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.classList.add("marked_as_ads") }) if (post_page == val.wallPage) { get.varOnWindow("wall", (id, val) => { let {showMore} = val val.showMore = function() { let result = showMore.apply(this, Array.prototype.slice.call(arguments)) post_page.getElementsByClassName("wall_marked_as_ads").forEach((e, i, a) => { e.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.classList.add("marked_as_ads") }) return result } }) } if (post_page == val.rowsCont) { get.varOnWindow("feed", (id, val) => { let {showMore} = val val.showMore = function() { let result = showMore.apply(this, Array.prototype.slice.call(arguments)) post_page.getElementsByClassName("wall_marked_as_ads").forEach((e, i, a) => { e.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.classList.add("marked_as_ads") }) return result } }) } } return val default: return val } } function setUI(id, val) { if (!isrtype(id, "", "setUI")) { return undefined } switch(id) { case "uiActionsMenu": let {show} = val val.show = function(t, e, i) { show.apply(this, Array.prototype.slice.call(arguments)) let el = (document.getElementsByClassName("im-action_mute")[0] || document.getElementsByClassName("im-action_unmute")[0]); if (!el) { return !1 } if (!document.getElementsByClassName("im-action_dnr").length && !document.getElementsByClassName("im-action_dnt").length) { el.insertAdjacentHTML("beforeBegin", `<style type="text/css"> [dir] .ui_actions_menu_item.im-action.im-action_dnr.true::before, .ui_actions_menu_item.im-action.im-action_dnt.true::before { background-position: 5px -405px; } [dir] .ui_actions_menu_item.im-action.im-action_dnr.false::before, .ui_actions_menu_item.im-action.im-action_dnt.false::before { background-position: 5px -305px; } </style>`) el.insertAdjacentHTML("beforeBegin", `<a id="im_dnr" tabindex="0" role="link" class="ui_actions_menu_item _im_action im-action im-action_dnr" onclick=" window.cur && !!cur.peer && vkMod.setDNRStatus(cur.peer, !vkMod.getDNRStatus(cur.peer)); this.text = vkMod.getDNRStatus(cur.peer) ? ' Выключить нечиталку' : ' Включить нечиталку'; this.classList.add((vkMod.getDNRStatus(cur.peer)).toString()); this.classList.remove((!vkMod.getDNRStatus(cur.peer)).toString()) "> ${vkMod.getDNRStatus(cur.peer) ? "Выключить нечиталку" : "Включить нечиталку"} </a>`) el.insertAdjacentHTML("beforeBegin", `<a id="im_dnt" tabindex="0" role="link" class="ui_actions_menu_item _im_action im-action im-action_dnt" onclick=" window.cur && !!cur.peer && vkMod.setDNTStatus(cur.peer, !vkMod.getDNTStatus(cur.peer)); this.text = vkMod.getDNTStatus(cur.peer) ? ' Выключить неписалку' : ' Включить неписалку'; this.classList.add((vkMod.getDNTStatus(cur.peer)).toString()); this.classList.remove((!vkMod.getDNTStatus(cur.peer)).toString()) "> ${vkMod.getDNTStatus(cur.peer) ? "Выключить неписалку" : "Включить неписалку"} </a>`) el.insertAdjacentHTML("beforeBegin", `<div class="ui_actions_menu_sep"></div>`) document.getElementById("im_dnr").classList.add((vkMod.getDNRStatus(cur.peer)).toString()) document.getElementById("im_dnr").classList.remove((!vkMod.getDNRStatus(cur.peer)).toString()) document.getElementById("im_dnt").classList.add((vkMod.getDNTStatus(cur.peer)).toString()) document.getElementById("im_dnt").classList.remove((!vkMod.getDNTStatus(cur.peer)).toString()) } } break; case "#top_profile_menu": let el = document.getElementById("top_profile_menu") if (!document.getElementById("top_vk_mod_menu_link")) { el.lastElementChild.insertAdjacentHTML("beforeBegin", `<a class="top_profile_mrow" id="top_vk_mod_menu_link" onclick="vkMod && vkMod.menu.show()" style=""> Настройки VK Mod </a>`) el.lastElementChild.insertAdjacentHTML("beforeBegin", `<div class="top_profile_sep"></div>`) } break default: console.error(`setUI has no id: ${id}`) return () => {} } } function isrtype(id, rid, name) { if (typeof id !== typeof "") { console.error(`${name}: id must be a ${typeof rid}`) return false } return true } function XHRListener() { const {send} = XMLHttpRequest.prototype XMLHttpRequest.prototype.send = function (data) { if (/type=typing/.test(data) && getStorageForId(storageName, vk.id)["dnt"] && getDNTStatus(data.match(/peer=([0-9]+)/)[1])) { return this.abort() } if (/type=audiomessage/.test(data) && getStorageForId(storageName, vk.id)["dnt_audio"] && getDNTStatus(data.match(/peer=([0-9]+)/)[1])) { return this.abort() } if (/act=a_mark_read/.test(data) && getStorageForId(storageName, vk.id)["dnr"] && getDNRStatus(data.match(/peer=([0-9]+)/)[1])) { return this.abort() } if (/act=a_mard_listened/.test(data) && getStorageForId(storageName, vk.id)["dnr_audio"] && getDNTStatus(data.match(/peer=([0-9]+)/)[1])) { return this.abort() } return send.apply(this, Array.prototype.slice.call(arguments)) } } function watcher(id, oldVal, val) { console.debug("Watcher:", id, oldVal, val); switch(id) { case "_adman": if (getStorageForId(storageName, vk.id)["audio_ads"] && val != null) { let {start} = val; val.start = function(a) {start.apply(this, Array.prototype.slice.call(arguments)); setTimeout(function() {val.skip()}, 100)}; } return val default: return val } } function objWatch() { /* * object.watch polyfill * * 2012-04-03 * * By Eli Grey, http://eligrey.com * Public Domain. * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. */ // object.watch if (!w.Object.prototype.watchh) { w.Object.defineProperty(w.Object.prototype, "watchh", { enumerable: false , configurable: true , writable: false , value: function (prop, handler) { var oldval = this[prop] , newval = oldval , getter = function () { return newval; } , setter = function (val) { oldval = newval; return newval = handler.call(this, prop, oldval, val); } ; if (delete this[prop]) { // can't watch constants w.Object.defineProperty(this, prop, { get: getter , set: setter , enumerable: true , configurable: true }); } } }); } // object.unwatch if (!w.Object.prototype.unwatchh) { w.Object.defineProperty(w.Object.prototype, "unwatchh", { enumerable: false , configurable: true , writable: false , value: function (prop) { var val = this[prop]; delete this[prop]; // remove accessors this[prop] = val; } }); } } function setWindow(w) { w.vkMod = {} vkMod = w.vkMod vkMod.default_storage = default_storage vkMod.getStorage = getStorage vkMod.getStorageForId = getStorageForId vkMod.setStorage = setStorage vkMod.setStorageForId = setStorageForId vkMod.getDNTStatus = getDNTStatus vkMod.setDNTStatus = setDNTStatus vkMod.getDNRStatus = getDNRStatus vkMod.setDNRStatus = setDNRStatus vkMod.get = get vkMod.menu = menu vkMod.styles = styles } (function(window, undefined) { w = window if (w.self != w.top) return console.info(script_name) objWatch() XHRListener() setWindow(window) get.varOnWindow("uiActionsMenu", (id, val) => {uiActionsMenu = val; setUI(id, val)}) get.elementOnDOM("#top_profile_menu", (id, val) => {setUI(id, val)}) get.varOnWindow("vk", (id, val) => {vk = val; styles.updateStyles()}) get.varOnWindow("ap", (id, val) => {ap = val; ap.ads.watchh(`_adman`, watcher)}) get.varOnWindow("cur", (id, val) => { cur = val w.watchh(`cur`, postsAds) postsAds("cur", null, cur) }) w.addEventListener('load', function() { }) })(window)