// ==UserScript== // @name 跟踪链接净化(B站, 百度,CSDN) // @name:zh-TW 跟蹤鏈接凈化(B站, 百度,CSDN)) // @name:en Clean Tracking URLs (Bilibili, Baidu, CSDN) // @namespace https://greasyfork.org/en/scripts/456881 // @version 0.4.7-2023.03.14 // @description 净化B站,百度(未加密的)和 CSDN 链接 // @description:zh-tw 凈化B站,百度(未加密的)和 CSDN 鏈接 // @description:en Clean Bilibili, Baidu (Unencrypted), CSDN Tracking URLs. // @author cilxe // @run-at document-body // @match *://*.bilibili.com/* // @exclude *://*.bilibili.com/api/* // @exclude *://api.bilibili.com/* // @exclude *://api.*.bilibili.com/* // @exclude *://bbq.bilibili.com/* // @match *://*.baidu.com/* // @match *://*.douyin.com/search/* // @match *://*.csdn.net/* // @match *://*.youku.com/* // @icon https://www.bilibili.com/favicon.ico // @license MIT // @downloadURL none // ==/UserScript== (() => { const DELAY_TIME = { fast: 600, normal: 1000, slow: 3000 }; let topScroll = 0; // onscroll events // Tracking or other params for each site const bilibiliParams = ['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', 't']; const baiduParams = ['rsv_idx', 'hisfilter', 'rsf', 'rsv_pq', 'rsv_t', 'qid', 'rsv_dl', // www.baidu.com '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', 'p_from', 'n_type', 'eqid', 'uname', 'uid', 'client_type', 'task', 'locate', 'page', 'type', 'is_new_user', // tieba.baidu.com 'frwh', 'obj_id', 'url', 'fid', 'fname', 'tid', '_t', 'topic_name', 'frs', 't']; const douyinParams = ['rsv_idx', 'hisfilter', 'source', 'aid', 'enter_from', 'focus_method', 'gid']; const csdnParams = ['spm', 'source', 'utm_source', 'ops_request_misc', 'request_id', 'biz_id', 'utm_medium', 'utm_term']; const youkuParams = ['spm', 'scm', 'from', 's']; // If block [Lucky Draw (The Selection)] popups on live.bilibili.com. const BlockLivePopups = true; let timeoutID; let intervalID; // Restore history state, remove redundant params function restoreState(siteParams) { const OLD_URL = window.location.href; const url = new URL(OLD_URL); const params = url.searchParams; siteParams.forEach((k) => { if (params.has(k)) { params.delete(k); } }); const NEW_URL = url.toString(); window.history.replaceState({}, 'Restore', NEW_URL); } // clean links function cleanLinks(siteParams) { 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); const params = url.searchParams; siteParams.forEach((k) => { if (params.has(k)) { params.delete(k); } }); links[i].href = url.toString(); } } } function deferredCleanLinks(delayTime) { timeoutID = setTimeout(() => { cleanLinks(bilibiliParams); clearTimeout(timeoutID); }, delayTime); } // ✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦ Bilibili ✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦ // 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); } // block clicking events (link, button, li) function blockBClickEvents() { 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 isLinkJumpVideo = links[i].classList.contains('video-time') || links[i].classList.contains('video'); if (!(isLinkJump && isLinkJumpVideo)) { links[i].addEventListener('click', (e) => { e.stopPropagation(); }, true); } } } } blockLinkEvents(); const buttons = document.getElementsByTagName('button'); function deferredBlock() { // blockLinkEvents(); removeBiliAds(); timeoutID = setTimeout(() => { blockLinkEvents(); removeBiliAds(); clearTimeout(timeoutID); }, DELAY_TIME.fast); } for (let i = 0; i < buttons.length; i += 1) { buttons[i].addEventListener('click', () => { // blockLinkEvents(); removeBiliAds(); deferredBlock(); }); } } function deferredBlockClickEvents(delayTime) { restoreState(bilibiliParams); timeoutID = setTimeout(() => { blockBClickEvents(); clearTimeout(timeoutID); }, delayTime); } // Loop execution when mouse moving function bilibiliListenMoving() { document.onmousemove = (e) => { if (e.clientY < 200) { cleanLinks(bilibiliParams); blockBClickEvents(); } }; } // Loop execution when mouse moving function biliListenScrolling() { window.onscroll = () => { // Current position const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (Math.abs(scrolls - topScroll) > 150) { removeBiliAds(); restoreState(bilibiliParams); cleanLinks(bilibiliParams); blockBClickEvents(); topScroll = scrolls; } }; } // clean top menu events function cleanBLTopMenu() { // bilibiliListenMoving(); document.onmousemove = (e) => { if (e.clientY < 200) { cleanLinks(bilibiliParams); blockBClickEvents(); } }; } // www.bilibili.com/*, ww.bilibili.com/v/popular/* function cleanBMainURL() { cleanLinks(bilibiliParams); removeBiliAds(); blockBClickEvents(); } // 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', () => { blockBClickEvents(); deferredBlockClickEvents(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', () => { deferredBlockClickEvents(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', () => { deferredBlockClickEvents(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', () => { timeoutID = setTimeout(() => { blockSearchEvents(); clearTimeout(timeoutID); }, DELAY_TIME.fast); }); } // search.bilibili.com/* function cleanBSearch() { blockBClickEvents(); blockBSearchItemEvents(); // vui_tabs--nav-item const lines = document.getElementsByTagName('li'); for (let i = 0; i < lines.length; i += 1) { lines[i].addEventListener('click', () => { blockBClickEvents(); deferredBlockClickEvents(DELAY_TIME.fast); }); } // 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', () => { blockBClickEvents(); deferredBlockClickEvents(DELAY_TIME.fast); }); } deferredBlockClickEvents(DELAY_TIME.normal); } // www.bilibili.com/video/* function cleanBVideoURL() { cleanLinks(bilibiliParams); blockBClickEvents(); const unfoldVideo = document.getElementsByClassName('rec-footer'); unfoldVideo[0].addEventListener('click', () => { cleanLinks(bilibiliParams); blockBClickEvents(); restoreState(bilibiliParams); }); // 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', () => { cleanLinks(bilibiliParams); removeBiliAds(); deferredBlockClickEvents(DELAY_TIME.normal); }, true); } timeoutID = setTimeout(() => { restoreState(bilibiliParams); cleanLinks(bilibiliParams); blockBClickEvents(); clearTimeout(timeoutID); }, DELAY_TIME.normal); } // space.bilibili.com/* function cleanBSpaceURL() { cleanLinks(bilibiliParams); blockBClickEvents(); bilibiliListenMoving(); } // 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')[i].style.visibility = 'hidden'; // document.getElementsByTagName('iframe')[i].style.opacity = 0; // iframes[i].style.display = 'none'; if (selection) { iframes[i].style.visibility = 'hidden'; } else { iframes[i].style.visibility = ''; } } } }; // live.bilibili.com/* function cleanBLive() { cleanLinks(bilibiliParams); blockBClickEvents(); const navis = document.getElementsByClassName('tabs__tag-item'); for (let i = 0; i < navis.length; i += 1) { navis[i].addEventListener('click', () => { deferredCleanLinks(DELAY_TIME.fast); }); } const tabItems = document.getElementsByClassName('tab-item'); for (let i = 0; i < tabItems.length; i += 1) { tabItems[i].addEventListener('click', () => { blockBClickEvents(); deferredCleanLinks(DELAY_TIME.fast); }); } window.onscroll = () => { const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (Math.abs(scrolls - topScroll) > 150) { cleanLinks(bilibiliParams); topScroll = scrolls; } }; intervalID = setInterval(livePopupBlock(BlockLivePopups), DELAY_TIME.normal); timeoutID = setTimeout(() => { clearInterval(intervalID); clearTimeout(timeoutID); }, DELAY_TIME.slow + 1000 * 300); } // ✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦ Baidu ✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦ function cleanBDLinks(siteParams) { cleanLinks(baiduParams); const links = document.getElementsByTagName('a'); for (let i = 0; i < links.length; i += 1) { if (links[i].href !== '') { const link = links[i].href; if (links[i].hostname.includes('zhidao.baidu.com') && links[i].pathname === '/q') { link.pathname = '/search'; } links[i].href = link.replace('from=', ''); } } const areas = document.getElementsByTagName('area'); if (areas.length === 1) { const areaURL = new URL(areas[0].href); const params = areaURL.searchParams; siteParams.forEach((k) => { if (params.has(k)) { params.delete(k); } }); areas[0].href = areaURL.toString(); } } function deferredCleanBDLinks(delayTime) { timeoutID = setTimeout(() => { cleanBDLinks(baiduParams); clearTimeout(timeoutID); }, delayTime - 100); } function blockBDTrackingEvents() { const links = document.getElementsByTagName('a'); for (let i = 0; i < links.length; i += 1) { links[i].addEventListener('click', () => { deferredCleanBDLinks(); }, true); } } // Baidu related search, Hot search URL cleaning function cleanBaiduURL() { restoreState(baiduParams); cleanBDLinks(baiduParams); blockBDTrackingEvents(); window.onscroll = () => { const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (Math.abs(scrolls - topScroll) > 150) { cleanLinks(baiduParams); topScroll = scrolls; } }; let x = 0; let y = 0; document.onmousemove = (e) => { if (Math.abs(e.clientX - x) > 10 || Math.abs(e.clientY - y) > 10) { cleanLinks(baiduParams); x = e.clientX; y = e.clientY; } }; } // ✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦ CSDN ✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦✦ function cleanCSDN() { restoreState(csdnParams); cleanLinks(csdnParams); // CSDN.net tracking events function blockCSDNEvents() { const links = document.getElementsByTagName('a'); for (let i = 0; i < links.length; i += 1) { links[i].addEventListener('click', (e) => { e.stopPropagation(); }, true); } } document.onmousemove = (e) => { if (e.clientY < 170 || e.clientY > 450) { cleanLinks(csdnParams); blockCSDNEvents(); } }; window.onscroll = () => { const scrolls = document.documentElement.scrollTop || document.body.scrollTop; if (Math.abs(scrolls - topScroll) > 150) { cleanLinks(csdnParams); blockCSDNEvents(); 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'); const isCSDN = realLocation.hostname.includes('csdn.net'); switch (true) { case isBilibili: // Bilibili restoreState(bilibiliParams); removeBiliMetadData(); removeBiliAds(); cleanBLTopMenu(); biliListenScrolling(); switch (isBilibili) { case isBmain: if (isBvideo) { timeoutID = setTimeout(() => { cleanBVideoURL(); clearTimeout(timeoutID); }, DELAY_TIME.fast); } else { timeoutID = setTimeout(() => { cleanBMainURL(); clearTimeout(timeoutID); }, DELAY_TIME.fast); } break; case isBsearch: cleanBSearch(); break; case isBspace: cleanBSpaceURL(); break; case isBlive: cleanBLive(); deferredCleanLinks(DELAY_TIME.normal + 200); deferredCleanLinks(DELAY_TIME.slow); break; default: // passport account message member t app manga show link cleanLinks(); break; } break; case isBaidu: cleanBaiduURL(); break; case isDouyin: restoreState(douyinParams); break; case isCSDN: cleanCSDN(); break; case realLocation.hostname.includes('youku.com'): cleanLinks(youkuParams); document.onmousemove = () => { cleanLinks(youkuParams); }; break; default: break; } }; })(); /* # Changelog v0.4.7-2023.03.14 - Clean Youku URLs. [Youku.com].(Testing) - Code reduction. - Performance optimisation and bug fixes. v0.4.6-2023.03.11 - Clean more baidu links. [Baidu] - Clean CSDN URLs. [csdn.net] - Script optimisation and bug fixes. - Code reduction. 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. */