- // ==UserScript==
- // @name spm_Track_Block_Tool
- // @namespace _s7util__
- // @version 0.5.0
- // @description:en Remove [spm] track paramter in URL
- // @description 移除链接中的spm跟踪参数
- // @author shc0743
- // @match *://*/*
- // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
- // @grant none
- // @license GPL-3
- // @supportURL https://github.com/shc0743/MyUtility/issues/new
- // @run-at document-start
- // ==/UserScript==
-
- /*
- Description:
- 说明:
-
- This user script removes the spm paramter in <a href> elements.
- 此脚本移除 <a href> 元素中的spm参数。
-
- If it doesn't work, try refreshing it a few times or wait a while.
- 若无法生效,请尝试刷新几次或等一会。
-
- Examples:
- 示例:
-
- https://www.bilibili.com/video/av170001?spm_id_from=114514
- -> https://www.bilibili.com/video/av170001
-
- https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514&query2=data3
- -> https://www.bilibili.com/video/av170001?query1=arg2&query2=data3
-
- https://www.bilibili.com/video/av170001?spm=114514.1919810#hash
- -> https://www.bilibili.com/video/av170001#hash
-
- https://www.bilibili.com/video/av170001?spm=114514.1919810&query2=data3#hash1
- -> https://www.bilibili.com/video/av170001?query2=data3#hash1
- */
-
- (function(window) {
- 'use strict';
-
- // Your code here...
-
- //var expr = /\?[\s\S]*spm/i;
- var track_args_list = [
- 'spm', 'spm_id_from', 'from_source'
- ];
- /**
- * 去除字符串中的spm参数
- * @param {String} str
- * @returns 去除spm后的结果
- */
- var remove_spm = function (str) {
- var newstr = '';
- var len = str.length;
- var is_in_query_part = false; // 只去除查询参数部分,避免正常url被替换而导致404
-
- for (let i = 0; i < len; ++i) {
- if (str[i] == '?') is_in_query_part = true;
- if (!is_in_query_part) { // 时机未到,跳过
- newstr += str[i];
- continue;
- }
-
- let need_break = true;
- for (let j = 0; j < track_args_list.length; ++j) {
- need_break = true;
- if (track_args_list[j] == str.substring(i,
- i + track_args_list[j].length - 0)) {
- // 检测到 “spm”
- while ((++i) < len) {
- if (str[i] == '&') { // 不能单独保留一个 & 号
- i++; break; // 去掉
- }
- if (str[i] == '#') break; // 保留hash部分
- }
- if (i == len) break; // 越界,直接break,以免url出现undefined
- }
- need_break = false;
- }
- if (need_break) break;
- newstr += str[i]; //
- }
-
- /*
- @deprecated 此移除器不按预期工作
- */
- // newstr = str;
- // for (let i = 0; i < track_args_list.length; ++i) {
- // let index = newstr.indexOf(track_args_list[i] + '=');
- // if (index + 1) { // found
- // let par_end = newstr.indexOf('&', index);
- // if (par_end == 0)
- // par_end = newstr.indexOf('#', index);
-
- // let str1 = newstr.substr(0, index);
- // let str2 = newstr.substr(par_end);
- // newstr = str1 + str2;
- // }
- // }
-
- var _lastchar;
- for (let i = 0; i < newstr.length; ++i) {
- _lastchar = newstr[newstr.length - 1];
- if (_lastchar == '?' || _lastchar == '&') { // 如果移除后只剩下 ? 或 &
- newstr = newstr.substr(0, newstr.length - 1); // 去掉
- _lastchar = newstr[newstr.length - 1];
- if (_lastchar == '?' || _lastchar == '&') // 再次检测
- newstr = newstr.substr(0, newstr.length - 1);
- } else break;
- }
- // Bug-Fix:
- // https://example.com/example?q1=arg&spm=123#hash1
- // -> https://example.com/example?q1=arg&#hash1
- // Invalid URL syntax at ^^
- newstr = newstr.replace(/\&\#/igm, '#');
- newstr = newstr.replace(/\?\#/igm, '#');
- return newstr;
- }
- var test_spm = function (str) {
- for (let i = 0; i < track_args_list.length; ++i)
- if (new RegExp(track_args_list[i], 'i').test(str))
- return true;
- return false;
- };
- var _realwindowopen = window.open;
-
- var _link_click = function (event) {
- if (!(/http/i.test(this.href))) return;
- event.preventDefault();
- // 防止被再次加入spm
- this.href = remove_spm(this.href);
- _realwindowopen(this.href, this.target || '_self');
- return false;
- };
- var _link_mouseover = function () {
- if (test_spm(this.href))
- this.href = remove_spm(this.href);
- };
- var linkclickhandlerinit = function () {
- var el = document.querySelectorAll('a[href]');
- for (let i = el.length - 1; i >= 0; --i) {
- if (test_spm(el[i].href)) {
- // 链接已经被加入spm , 需要移除
- el[i].href = remove_spm(el[i].href);
- }
- el[i].removeEventListener('click', _link_click);
- el[i].addEventListener('click', _link_click, true);
- el[i].removeEventListener('mouseover', _link_mouseover);
- el[i].addEventListener('mouseover', _link_mouseover, false);
- }
- };
- window.addEventListener('load', function (event) {
- window.setInterval(linkclickhandlerinit, 5000);
- window.setTimeout(linkclickhandlerinit, 1000);
- window.setTimeout(linkclickhandlerinit, 500);
- window.setTimeout(linkclickhandlerinit, 1);
- try {
- Object.defineProperty(window, 'open', {
- value: function (url, target, features) {
- return _realwindowopen(
- remove_spm(url),
- target,
- features);
- },
- writable: false,
- enumerable: true,
- configurable: true
- }); // 重定义window.open 以阻止弹出窗口中的spm
- }
- catch (error) {
- console.warn("This browser doesn't support redefining" +
- " window.open , so [SpmBlockTool] cannot remove" +
- " spm in popup window.\nError:", error);
- }
- });
-
- // 移除当前页面的spm
- // 当然,实际上spm已经在userscript加载前被发送到服务器,
- // 所以该功能仅美化url.
- // 如果要禁用该功能,删除下面一行开头的斜杠。
- //if(0)
- // Remove spm from current page
- // Of course, in fact, SPM has been sent to the server
- // before userscript is loaded, so this function only beautifies the URL.
- // If you want to disable this feature, remove the slash
- // at the beginning of the following line:
- //if(0)
- if (test_spm(location.href)) {
- window.history.replaceState({},
- document.title,
- remove_spm(location.href));
- }
-
- /*
- var test_urls = [
- 'https://www.bilibili.com/video/BV18X4y1N7Yh',
- 'https://www.bilibili.com/video/BV18X4y1N7Yh?spm_id_from=114514',
- 'https://www.bilibili.com/video/BV18X4y1N7Yh?spm=114514.1919810',
- 'https://www.bilibili.com/video/BV18X4y1N7Yh?spm_id_from=114514.123',
-
- 'https://www.bilibili.com/video/av170001',
- 'https://www.bilibili.com/video/av170001?spm_id_from=114514',
- 'https://www.bilibili.com/video/av170001?spm=114514.1919810',
- 'https://www.bilibili.com/video/av170001?spm_id_from=114514.123',
-
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514',
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm=114514.1919810',
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514.123',
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514',
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm=114514.1919810',
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514.123',
-
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514&query2=data3',
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm=114514.1919810&query2=data3',
-
- 'https://www.bilibili.com/video/av170001?spm_id_from=114514#hash',
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm_id_from=114514#hash1',
- 'https://www.bilibili.com/video/av170001?query1=arg2&spm=114514.1919810#hash1',
-
- 'https://www.bilibili.com/video/av170001?spm_id_from=114514&query2=data3#hash1',
- 'https://www.bilibili.com/video/av170001?spm=114514.1919810&query2=data3#hash1',
- ];
- for(let i=0;i<test_urls.length;++i){
- let el=document.createElement('a');
- el.href=test_urls[i];
- el.innerHTML=i+1 + '';
- document.documentElement.appendChild(el);
- }
- for(let i=0;i<test_urls.length;++i){
- let el=document.createElement('a');
- el.href=test_urls[i];
- el.innerHTML=i+1 + ' blank';
- el.target='_blank';
- document.documentElement.appendChild(el);
- }
- */
-
- })(window);