// ==UserScript== // @name 跟踪链接净化(B站, 百度) // @name:zh-TW 跟蹤鏈接凈化(B站, 百度) // @name:en Clean Tracking URLs (Bilibili, Baidu) // @namespace https://greasyfork.org/en/scripts/456881 // @version 0.4.5 // @description 净化B站跟踪链接(推荐视频),百度<相关搜索、热搜>链接净化 // @description:zh-tw 凈化B站鏈接跟蹤(推薦視頻),百度<相關搜索、熱搜>鏈接凈化 // @description:en Clean Bilibili Tracking URLs (Recommended Videos), Baidu URLs. // @author cilxe // @match *://*.bilibili.com/* // @exclude *://*.bilibili.com/api/* // @exclude *://api.bilibili.com/* // @exclude *://api.*.bilibili.com/* // @exclude *://bbq.bilibili.com/* // @match *://www.baidu.com/* // @match *://zhidao.baidu.com/* // @match *://*.douyin.com/search/* // @icon https://www.bilibili.com/favicon.ico // @run-at document-start // @license MIT // @downloadURL none // ==/UserScript== (() => { const DELAY_TIME = { fast: 600, normal: 1000, slow: 3000 }; // Sites with its tracking or other params const Indexes = { bilibili: ['spm_id_from', 'spm_id', 'vd_source', 'from_spmid', 'csource', 'sourceFrom', 'hotRank', 'live_from', 'from', 'launch_id', 'msource', 'popular_rank', 'session_id', 'business', 'sort_field', 'broadcast_type', 'is_room_feed', 'is_live_full_webview', 'is_live_webview', 'refer_from', 'vt'], baidu: ['rsf', 'rsv_pq', 'rsv_t', 'qid', 'rsv_dl', 'sa', 'rqid', 'oq', 'gpc', 'usm', 'tfflag', 'ie', 'bs', 'rqlang', 'tn', 'sc_us', 'wfr', 'for', 'from', 'topic_pn', 'rsp', 'rs_src', 'f', 'rsv_page', 'dyTabStr', 'tn', 'ct', 'lm', 'site', 'sites', 'fr', 'cl', 'bsst', 'lid', 'rsv_spt', 'rsv_bp', 'src', 'sfrom', 'utm_source', 'utm_medium', 'refer', 'zp_fr', 'channel'], douyin: ['rsv_idx', 'hisfilter', 'source', 'aid', 'enter_from', 'focus_method', 'gid'], }; const sites = [Indexes.bilibili, Indexes.baidu, Indexes.douyin]; // If block [Lucky Draw (The Selection)] popups at live.bilibili.com. const BlockLivePopups = true; // Restore history state, remove redundant params function restoreState(site) { const OLD_URL = window.location.href; const url = new URL(OLD_URL); const params = url.searchParams; site.forEach((k) => { params.delete(k); }); const NEW_URL = url.toString(); window.history.replaceState({}, 'Restore', NEW_URL); } class cleanBili { } // Remove Bilibili metadata function removeBiliMetadData() { const metas = document.getElementsByTagName('meta'); for (let i = 0; i < metas.length; i += 1) { if (metas[i].name === 'spm_prefix') { metas[i].remove(); } } } // Remove Bilibili Card Ads function removeBiliAds() { let index = 0; do { const cardAds = document.getElementsByTagName('a'); for (let i = 0; i < cardAds.length; i += 1) { if (cardAds[i].hostname.includes('cm.bilibili.com')) { cardAds[i].remove(); } } index += 1; } while (index < 2); } // clean links function cleanBiliLinks(site) { const links = document.getElementsByTagName('a'); for (let i = 0; i < links.length; i += 1) { if (links[i].href !== '') { const url = new URL(links[i].href); site.forEach((k) => { url.searchParams.delete(k); }); links[i].href = url.toString(); } } } // block clicking events (link, button, li) function blockClickEvents() { function blockLinkEvents() { const links = document.getElementsByTagName('a'); for (let i = 0; i < links.length; i += 1) { if (links[i].getAttribute('data-video-time') === null) { const isLinkJump = links[i].classList.contains('jump-link'); const isVideoJump = links[i].classList.contains('video-time') || links[i].classList.contains('video'); if (!(isLinkJump && isVideoJump)) { links[i].addEventListener('click', (e) => { e.stopPropagation(); }, true); } } } } blockLinkEvents(); const buttons = document.getElementsByTagName('button'); for (let i = 0; i < buttons.length; i += 1) { buttons[i].addEventListener('click', () => { blockLinkEvents(); removeBiliAds(); setTimeout(() => { blockLinkEvents(); removeBiliAds(); }, DELAY_TIME.fast); setTimeout(() => { blockLinkEvents(); removeBiliAds(); }, DELAY_TIME.normal); }); } const userAvatars = document.getElementsByClassName('cover'); for (let i = 0; i < userAvatars.length; i += 1) { userAvatars[i].addEventListener('mouseover', () => { setInterval(() => { blockLinkEvents(); }, 80); }, true); } const userNames = document.getElementsByClassName('title'); for (let i = 0; i < userNames.length; i += 1) { userNames[i].addEventListener('mouseover', () => { setInterval(() => { blockLinkEvents(); }, 80); }, true); } // bili-dyn-avatar bili-dyn-title } // clean top menu events function cleanBLTopMenu() { setTimeout(() => { const topEntries = document.getElementsByClassName('v-popover-wrap'); // li for (let i = 0; i < topEntries.length; i += 1) { topEntries[i].addEventListener('mouseover', () => { blockClickEvents(); }, true); const entryLinks = topEntries[i].getElementsByTagName('a'); for (let index = 0; index < entryLinks.length; index += 1) { entryLinks[index].addEventListener('click', (e) => { e.stopPropagation(); }, true); } } const locItems = document.getElementsByClassName('loc-moveclip'); for (let i = 0; i < locItems.length; i += 1) { locItems[i].addEventListener('click', (e) => { e.stopPropagation(); }, true); } const rightItems = document.getElementsByClassName('right-entry__outside'); // div for (let i = 0; i < rightItems.length; i += 1) { rightItems[i].addEventListener('click', (e) => { e.stopPropagation(); }, true); } // 收藏 - 稍后再看 const favTabs = document.getElementsByClassName('tab-item'); // div for (let i = 0; i < favTabs.length; i += 1) { favTabs[i].addEventListener('click', () => { setTimeout(() => { blockClickEvents(); }, 800); }, true); } }, DELAY_TIME.slow); } // www.bilibili.com/*, ww.bilibili.com/v/popular/* function cleanBMainURL() { restoreState(sites[0]); function onFresh() { // www.bilibili.com/v/popular/ function blockPopEvents() { // block default events const videoCards = document.getElementsByClassName('video-card__content'); // div for (let i = 0; i < videoCards.length; i += 1) { videoCards[i].addEventListener('click', (e) => { e.stopPropagation(); }); } } if (window.location.href.includes('www.bilibili.com/v/popular')) { blockPopEvents(); // block navibar items clicking events const naviItems = document.getElementsByClassName('nav-tabs__item'); // div for (let i = 0; i < naviItems.length; i += 1) { naviItems[i].addEventListener('click', () => { setTimeout(() => { blockPopEvents(); blockClickEvents(); }, DELAY_TIME.fast + 100); setTimeout(() => { blockPopEvents(); }, DELAY_TIME.normal + 200); }); } // block traking link events after rank-tab clicked const tagUL = document.getElementsByClassName('rank-tab')[0]; // li if (tagUL != null) { const tagLIs = tagUL.getElementsByTagName('li'); for (let i = 0; i < tagLIs.length; i += 1) { tagLIs[i].addEventListener('click', () => { setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast + 100); }); } } } } onFresh(); cleanBiliLinks(sites[0]); removeBiliAds(); blockClickEvents(); // Loop execution while scrolling window.onscroll = () => { let topScroll = 0; // Scroll range const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (scrolls - topScroll > 120) { cleanBiliLinks(sites[0]); removeBiliAds(); blockClickEvents(); onFresh(); topScroll = scrolls; } }; } // bilibili search events function blockBSearchItemEvents() { function blockSearchEvents() { // input suggested items const suggestItems = document.getElementsByClassName('suggest-item'); for (let i = 0; i < suggestItems.length; i += 1) { suggestItems[i].addEventListener('click', () => { blockClickEvents(); setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast); }); } // search trending items const topSearchs = document.getElementsByClassName('trending-item'); for (let i = 0; i < topSearchs.length; i += 1) { topSearchs[i].addEventListener('click', () => { setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast); }); } // search history items const historyItems = document.getElementsByClassName('history-item'); for (let i = 0; i < historyItems.length; i += 1) { historyItems[i].addEventListener('click', () => { setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast); }); } } // search input area const searchInputs = document.getElementsByClassName('search-input-el'); searchInputs[0].addEventListener('click', () => { blockSearchEvents(); }); // clear icon const clearIcon = document.getElementsByClassName('clear-icon')[0]; clearIcon.addEventListener('click', () => { setTimeout(() => { blockSearchEvents(); }, DELAY_TIME.fast); }); } // search.bilibili.com/* function cleanBSearch() { restoreState(sites[0]); blockClickEvents(); blockBSearchItemEvents(); // vui_tabs--nav-item const lines = document.getElementsByTagName('li'); for (let i = 0; i < lines.length; i += 1) { lines[i].addEventListener('click', () => { blockClickEvents(); setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast + 100); }); } // paging button clicking event const pageButtons = document.getElementsByClassName('vui_pagenation--btn'); // div for (let i = 0; i < pageButtons.length; i += 1) { pageButtons[i].addEventListener('click', () => { blockClickEvents(); setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast + 100); restoreState(sites[0]); }); } setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast + 100); // loop execution while scrolling window.onscroll = () => { let topScroll = 0; const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (scrolls - topScroll > 120) { restoreState(sites[0]); cleanBiliLinks(sites[0]); blockClickEvents(); removeBiliAds(); topScroll = scrolls; } }; } // www.bilibili.com/video/* function cleanBVideoURL() { restoreState(sites[0]); cleanBiliLinks(sites[0]); blockClickEvents(); const unfoldVideo = document.getElementsByClassName('rec-footer'); unfoldVideo[0].addEventListener('click', () => { cleanBiliLinks(sites[0]); blockClickEvents(); restoreState(sites[0]); }); window.onscroll = () => { let topScroll = 0; const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (scrolls - topScroll > 120) { restoreState(sites[0]); cleanBiliLinks(sites[0]); blockClickEvents(); removeBiliAds(); topScroll = scrolls; } }; // video episodes/collections tracking state after clicked const episodes = document.getElementsByClassName('rec-footer'); // div for (let i = 0; i < episodes.length; i += 1) { episodes[i].addEventListener('click', () => { cleanBiliLinks(sites[0]); removeBiliAds(); setTimeout(() => { restoreState(sites[0]); blockClickEvents(); }, 1000); }, true); } setTimeout(() => { restoreState(sites[0]); cleanBiliLinks(sites[0]); blockClickEvents(); }, DELAY_TIME.slow); } // space.bilibili.com/* function cleanBSpaceURL() { cleanBiliLinks(sites[0]); blockClickEvents(); function run() { // paging class = 'be-pager' const lines = document.getElementsByTagName('li'); // li for (let i = 0; i < lines.length; i += 1) { lines[i].addEventListener('click', () => { blockClickEvents(); setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast); }); } // side navigation bar click events class = 'text' const links = document.getElementsByTagName('a'); // a for (let i = 0; i < links.length; i += 1) { links[i].addEventListener('click', () => { blockClickEvents(); setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast); }); } // navigation inputs (sorting) class = 'be-tab-input' const inputs = document.getElementsByTagName('input'); for (let i = 0; i < inputs.length; i += 1) { inputs[i].addEventListener('click', () => { blockClickEvents(); setTimeout(() => { blockClickEvents(); }, DELAY_TIME.fast); }); } } run(); window.onscroll = () => { let topScroll = 0; const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (scrolls - topScroll > 120) { cleanBiliLinks(sites[0]); run(); blockClickEvents(); topScroll = scrolls; } }; } // live.bilibili.coom popups const livePopupBlock = (selection) => { const iframes = document.getElementsByTagName('iframe'); for (let i = 0; i < iframes.length; i += 1) { if (iframes[i].src.includes('live-lottery')) { // document.getElementsByTagName('iframe')[2].style.visibility = 'hidden'; // document.getElementsByTagName('iframe')[2].style.opacity = 0; // iframes[i].style.display = 'none'; if (selection === true) { iframes[i].style.visibility = 'hidden'; } else { iframes[i].style.visibility = ''; } } } }; // live.bilibili.com/* function cleanBLive() { cleanBiliLinks(sites[0]); blockClickEvents(); const navis = document.getElementsByClassName('tabs__tag-item'); for (let i = 0; i < navis.length; i += 1) { navis[i].addEventListener('click', () => { setTimeout(() => { cleanBiliLinks(sites[0]); }, 100); setTimeout(() => { cleanBiliLinks(sites[0]); }, DELAY_TIME.normal); }); } const tabItems = document.getElementsByClassName('tab-item'); for (let i = 0; i < tabItems.length; i += 1) { tabItems[i].addEventListener('click', () => { blockClickEvents(); setTimeout(() => { cleanBiliLinks(sites[0]); }, 100); setTimeout(() => { cleanBiliLinks(sites[0]); }, DELAY_TIME.normal); }); } window.onscroll = () => { let topScroll = 0; const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (scrolls - topScroll > 120) { cleanBiliLinks(sites[0]); topScroll = scrolls; } }; const liveIntervalId = setInterval(livePopupBlock(BlockLivePopups), DELAY_TIME.normal); setTimeout(() => { clearInterval(liveIntervalId); }, DELAY_TIME.slow + 1000 * 300); } // Baidu related search, Hot search URL cleaning function cleanBaiduURL() { function cleanLinks(site) { const links = document.getElementsByTagName('a'); for (let i = 0; i < links.length; i += 1) { if (links[i].href !== '') { const url = new URL(links[i].href); site.forEach((k) => { url.searchParams.delete(k); }); // Mar. 2023 404 of zhidao.baidu.com/q?word= if (url.host.includes('zhidao.baidu.com') && url.pathname === '/q') { url.pathname = '/search'; } links[i].href = url.toString().replace('from=', ''); } } } cleanLinks(sites[1]); window.onscroll = () => { let topScroll = 0; const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (scrolls - topScroll > 120) { cleanLinks(sites[1]); topScroll = scrolls; } }; } // Handle different sites window.onload = () => { const realLocation = window.location; const isBilibili = realLocation.hostname.includes('bilibili.com'); const isBmain = realLocation.hostname.includes('www.bilibili.com'); const isBvideo = realLocation.href.includes('www.bilibili.com/video'); const isBsearch = realLocation.hostname.includes('search.bilibili.com'); const isBspace = realLocation.hostname.includes('space.bilibili.com'); const isBlive = realLocation.hostname.includes('live.bilibili.com'); const isBaidu = realLocation.hostname.includes('baidu.com'); const isDouyin = realLocation.hostname.includes('douyin.com'); switch (true) { case isBilibili: // Bilibili restoreState(sites[0]); cleanBiliLinks(sites[0]); removeBiliMetadData(); removeBiliAds(); cleanBLTopMenu(); switch (isBilibili) { case isBmain: if (isBvideo) { setTimeout(() => { cleanBVideoURL(); }, DELAY_TIME.fast); } else { setTimeout(() => { cleanBMainURL(); }, DELAY_TIME.fast); } break; case isBsearch: cleanBSearch(); break; case isBspace: setTimeout(() => { cleanBSpaceURL(); }, DELAY_TIME.fast); break; case isBlive: cleanBLive(); setTimeout(() => { cleanBiliLinks(sites[0]); }, DELAY_TIME.normal + 200); setTimeout(() => { cleanBiliLinks(sites[0]); }, DELAY_TIME.slow); break; default: // passport account message member t app manga show link blockClickEvents(); break; } break; case isBaidu: // Baidu restoreState(sites[1]); cleanBaiduURL(); setTimeout(() => { cleanBaiduURL(); }, DELAY_TIME.normal); break; case isDouyin: restoreState(sites[2]); break; default: break; } }; })(); /* # Changelog v0.4.5 2023.03.09 - Clean more URL under Baidu.com, replace search URL state. [Baidu] - Script optimisation and bug fixes. [bilibili] - Code reduction. v0.4.4 2023.03.05 - Restore history state at live.bilibili.com. [Bilibili] - Clean Bilibili Manga & Show links. [manga/show.bilibili.com] - Clean redundant params at douyin.com search page. [Douyin] - Code reduction. v0.4.3.1 2023.03.01 - Clean more links at live.bilibili.com. [Bilibili] - Script optimisation. v0.4.3 2023.02.24 - Block more tracking events. [Bilibili] - Clean more links.[Bilibili] - Restore link jump events at comment area. [Bilibili] - Script optimisation. [Bilibili] v0.4.2.1 2023.02.22 - Restore `` link click-events on precise time jump at comment area.[www.bilibili.com/video] v0.4.2 2023.02.07 - Optimised events at the search-input-block. [Bilibili] - Bug fixes. [search.bilibili.com, www.bilibili.com] v0.4.1.2 2023.01.28 - Bug fixes and performance optimisation. [Bilibili] v0.4.1.1 2023.01.25 - Expanded the effective pages of the script. [Bilibili] v0.4.1.0 2023.01.23 - Performance optimisation and bug fixes. - Code reduction. v0.4.0.1 2023.01.21 - Clean other untracked links. [space.bilibili.com] - Several bugs fixes. [bilibili.com] v0.4.0 2023.01.20 - Clean Bilibili Video page collections clicking event URL state changes. [www.bilibili.com/video/] - Clean Bilibili Search tracking events. [search.bilibili.com] - Clean other tracking events (top-menu clicking). [Bilibili] v0.3.8.3 2023.01.20 - Fixed tracking event after video sorting navigation bar items clicked. [space.bilibili.com] v0.3.8.2 2023.01.19 - Fixed navibar items click events [www.bilibili.com/v/popular]. v0.3.8.1 2023.01.13 - Clean more links of Baidu.com v0.3.8 2023.01.06 - Block Card-Ads for Bilibili. (And now blocked banner-ads & card-ads for Bilibili) - Block [Lucky Draw (The Selection)] popup at [live.bilibili.com]. Disabled by default. - (SET [{BlockLivePopups} = true] to enable it.) - The script may add menus to unlock custom setting. v0.3.7.1 2023.01.02 - Fixed [space.bilibili.com] effects after paged, navi-bar clicked or menu-item clicked. - Added support to clean tracking url at [search.bilibili.com]. v0.3.7 2023-01-02 - Naming optimisation. - Script handling optimisation. (Bilibili) - Added support to block part of Bilibili Ads. v0.3.6 2022.12.28 - Optimise Baidu related search URL, paging URL processing method. v0.3.5 2022.12.27 - Script logic optimisation. v0.3.4 2022.12.23 - Code optimisation. Fixed script's effect range. [Bilibili] v0.3.3 2022.12.23 - Added site support:Clean Baidu URLs. - Script optimisations. [space.bilibili.com] v0.3.2 2022.12.22 - Restore pushstate session (address bar url display, replace history). [Bilibili] - Minor optimisations. [Bilibili] v0.3.1 2022.12.22 - Optimized the effective range. [Bilibili] v0.3 2022.12.22 - Added Bilibili Home page, Popular/Rank page, now it can takeeffect on most pages. [Bilibili] v0.2 2022.12.21 - Added missing tags. [Bilibili] v0.1 2022.12.20 - Initial release. */