CleanURLs

Remove tracking parameters and redirect to original URL. This Userscript uses the URL Interface instead of RegEx.

目前为 2023-06-10 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name CleanURLs
  3. // @namespace i2p.schimon.cleanurl
  4. // @description Remove tracking parameters and redirect to original URL. This Userscript uses the URL Interface instead of RegEx.
  5. // @homepageURL https://greasyfork.org/en/scripts/465933-clean-url-improved
  6. // @supportURL https://greasyfork.org/en/scripts/465933-clean-url-improved/feedback
  7. // @copyright 2023, Schimon Jehudah (http://schimon.i2p)
  8. // @license MIT; https://opensource.org/licenses/MIT
  9. // @grant none
  10. // @run-at document-end
  11. // @match *://*/*
  12. // @version 23.06.10
  13. // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48dGV4dCB5PSIuOWVtIiBmb250LXNpemU9IjkwIj7wn5qlPC90ZXh0Pjwvc3ZnPgo=
  14.  
  15. // ==/UserScript==
  16.  
  17. /*
  18.  
  19. FIXME
  20. fix comparison of safe and unsafe
  21.  
  22. safe and unsafe are the same
  23. https://addons.palemoon.org/addon/bamboo-feed-reader/
  24. https://addons.palemoon.org/?component=download&id=%7Bb2e69492-2358-071a-7056-24ad0c3defb1%7D&version=2.3.2
  25.  
  26. safe and unsafe are the same (encoding difference @ vs %40)
  27. https://addons.palemoon.org/addon/inforss-reloaded/
  28. https://addons.palemoon.org/?component=download&id=inforss-reloaded@addons.palemoon.org&version=2.3.1.0
  29. https://addons.palemoon.org/?component=download&id=inforss-reloaded%40addons.palemoon.org&version=2.3.1.0
  30.  
  31. */
  32.  
  33. /*
  34.  
  35. Simple version of this Userscript
  36. let url = new URL(location.href);
  37. if (url.hash || url.search) {
  38. location.href = url.origin + url.pathname
  39. };
  40.  
  41. */
  42.  
  43. // https://openuserjs.org/scripts/tfr/YouTube_Link_Cleaner
  44.  
  45. // Check whether HTML; otherwise, exit.
  46. //if (!document.contentType == 'text/html')
  47. if (document.doctype == null) return;
  48.  
  49. //let point = [];
  50. const namespace = 'i2p.schimon.cleanurl';
  51.  
  52. // List of url parameters
  53. const urls = [
  54. 'redirect',
  55. 'ref',
  56. 'source',
  57. 'src',
  58. 'url',
  59. 'utm_source'];
  60.  
  61. // List of reserved parameters
  62. const whitelist = [
  63. 'art', // article
  64. 'action', // wiki
  65. 'bill', // law
  66. 'c', // cdn
  67. 'category', // id
  68. 'code', // code
  69. 'component', // addons.palemoon.org
  70. 'content', // id
  71. 'dark', // yorik.uncreated.net
  72. 'date', // date
  73. 'days', // wiki
  74. 'district', // house.mo.gov
  75. 'exp_time', // cdn
  76. 'expires', // cdn
  77. 'ezimgfmt', // cdn image processor
  78. 'feedformat', // wiki
  79. 'fid', // mybb
  80. 'file_host', // cdn
  81. 'filename', // filename
  82. 'for', // cdn
  83. 'format', // file type
  84. 'guid', // guid
  85. 'hash', // cdn
  86. 'hidebots', // wiki
  87. 'hl', // language
  88. 'id', // id
  89. 'ie', // character encoding
  90. 'ip', // ip address
  91. 'item_class', // greasyfork
  92. 'item_id', // greasyfork
  93. 'jid', // jabber id (xmpp)
  94. 'key', // cdn
  95. 'limit', // wiki
  96. 'lang', // language
  97. 'language', // language
  98. 'library', // oujs
  99. 'locale', // locale
  100. 'lr', // cdn
  101. 'lra', // cdn
  102. 'mobileaction', // wiki
  103. 'news_id', // post
  104. 'order', // bugzilla
  105. 'orderBy', // oujs
  106. 'orderDir', // oujs
  107. 'p', // search query / page number
  108. 'page', // mybb
  109. 'preferencesReturnUrl', // return url
  110. 'product', // bugzilla
  111. 'q', // search query
  112. 'query', // search query
  113. 'query_format', // bugzilla
  114. //'referer', // signin <-- provided pathname contains login (log-in) or signin (sign-in)
  115. 'resolution', // bugzilla
  116. 'return_to', // signin
  117. 's', // search query
  118. 'search', // search query
  119. 'show_all_versions', // greasyfork
  120. 'sign', // cdn
  121. 'signature', // cdn
  122. 'sort', // greasyfork
  123. 'speed', // cdn
  124. 'start_time', // media playback
  125. 'state', // cdn
  126. '__switch_theme', // theme (theanarchistlibrary.org)
  127. 'tag', // id
  128. 'tid', // mybb
  129. 'title', // send (share) links and wiki
  130. 'type', // file type
  131. //'url', // url <-- not whitelisted nor blacklisted
  132. 'utf8', // encoding
  133. 'urlversion', // wiki
  134. 'v', // video
  135. 'version', // greasyfork
  136. //'_x_tr_sl', // translate online service
  137. //'_x_tr_tl=', // translate online service
  138. //'_x_tr_hl=', // translate online service
  139. //'_x_tr_pto', // translate online service
  140. //'_x_tr_hist', // translate online service
  141. 'year' // year
  142. ];
  143.  
  144. // List of useless hash
  145. const hash = [
  146. 'back-url',
  147. 'intcid',
  148. 'niche-',
  149. //'searchinput',
  150. 'src'];
  151.  
  152. // List of useless parameters
  153. const blacklist = [
  154. 'ad',
  155. 'ad_medium',
  156. 'ad_name',
  157. 'ad_pvid',
  158. 'ad_sub',
  159. //'ad_tags',
  160. 'advertising-id',
  161. //'aem_p4p_detail',
  162. 'af',
  163. 'aff',
  164. 'aff_fcid',
  165. 'aff_fsk',
  166. 'aff_platform',
  167. 'aff_trace_key',
  168. 'affparams',
  169. 'afSmartRedirect',
  170. 'afftrack',
  171. 'affparams',
  172. //'aid',
  173. 'algo_exp_id',
  174. 'algo_pvid',
  175. 'ar',
  176. //'ascsubtag',
  177. //'asc_contentid',
  178. 'asgtbndr',
  179. 'atc',
  180. 'ats',
  181. 'autostart',
  182. //'b64e', // breaks yandex
  183. 'bizType',
  184. //'block',
  185. 'bta',
  186. 'businessType',
  187. 'campaign',
  188. 'campaignId',
  189. //'__cf_chl_rt_tk',
  190. 'cid',
  191. 'ck',
  192. //'clickid',
  193. //'client_id',
  194. //'cm_ven',
  195. 'content-id',
  196. 'crid',
  197. 'cst',
  198. 'cts',
  199. 'curPageLogUid',
  200. //'data', // breaks yandex
  201. //'dchild',
  202. //'dclid',
  203. 'deals-widget',
  204. 'dicbo',
  205. //'dt',
  206. 'edd',
  207. 'edm_click_module',
  208. //'ei',
  209. //'embed',
  210. '_encoding',
  211. //'etext', // breaks yandex
  212. 'eventSource',
  213. 'fbclid',
  214. 'feature',
  215. 'forced_click',
  216. //'fr',
  217. 'frs',
  218. //'from', // breaks yandex
  219. '_ga',
  220. 'ga_order',
  221. 'ga_search_query',
  222. 'ga_search_type',
  223. 'ga_view_type',
  224. 'gatewayAdapt',
  225. //'gclid',
  226. //'gclsrc',
  227. 'gh_jid',
  228. 'gps-id',
  229. //'gs_lcp',
  230. 'gt',
  231. 'guccounter',
  232. 'hdtime',
  233. 'ICID',
  234. 'ico',
  235. 'ig_rid',
  236. //'idzone',
  237. //'iflsig',
  238. //'irgwc',
  239. //'irpid',
  240. 'itid',
  241. //'itok',
  242. //'katds_labels',
  243. //'keywords',
  244. 'keyno',
  245. 'l10n',
  246. 'linkCode',
  247. 'mc',
  248. 'mid',
  249. 'mp',
  250. 'nats',
  251. 'nci',
  252. 'obOrigUrl',
  253. 'optout',
  254. 'oq',
  255. 'organic_search_click',
  256. 'pa',
  257. 'Partner',
  258. 'partner',
  259. 'partner_id',
  260. 'pcampaignid',
  261. 'pd_rd_i',
  262. 'pd_rd_r',
  263. 'pd_rd_w',
  264. 'pd_rd_wg',
  265. 'pdp_npi',
  266. 'pf_rd_i',
  267. 'pf_rd_m',
  268. 'pf_rd_p',
  269. 'pf_rd_r',
  270. 'pf_rd_s',
  271. 'pf_rd_t',
  272. 'pg',
  273. 'PHPSESSID',
  274. 'pk_campaign',
  275. 'pdp_ext_f',
  276. 'pkey',
  277. 'platform',
  278. 'plkey',
  279. 'pqr',
  280. 'pr',
  281. 'pro',
  282. 'prod',
  283. 'promo',
  284. 'promocode',
  285. 'promoid',
  286. 'psc',
  287. 'psprogram',
  288. 'pvid',
  289. 'qid',
  290. //'r',
  291. 'realDomain',
  292. 'recruiter_id',
  293. 'redirect',
  294. 'ref',
  295. 'ref_',
  296. 'ref_src',
  297. 'refcode',
  298. 'referrer',
  299. 'refinements',
  300. 'reftag',
  301. 'rowan_id1',
  302. 'rowan_msg_id',
  303. //'sCh',
  304. 'sclient',
  305. 'scm',
  306. 'scm_id',
  307. 'scm-url',
  308. //'sd',
  309. 'si',
  310. '___SID',
  311. '_src',
  312. 'src_cmp',
  313. 'src_player',
  314. 'src_src',
  315. 'shareId',
  316. 'showVariations',
  317. 'sid',
  318. //'site_id',
  319. 'sk',
  320. 'smid',
  321. 'social_params',
  322. 'source',
  323. 'sourceId',
  324. 'sp_csd',
  325. 'spLa',
  326. 'spm',
  327. 'spreadType',
  328. //'sprefix',
  329. 'sr',
  330. 'src',
  331. 'srcSns',
  332. 'su',
  333. '_t',
  334. //'tag',
  335. 'tcampaign',
  336. 'td',
  337. 'terminal_id',
  338. //'text',
  339. 'th', // Sometimes restored after page load
  340. //'title',
  341. 'tracelog',
  342. 'traffic_id',
  343. 'traffic_type',
  344. 'tt',
  345. 'uact',
  346. 'ug_edm_item_id',
  347. //'utm1',
  348. //'utm2',
  349. //'utm3',
  350. //'utm4',
  351. //'utm5',
  352. //'utm6',
  353. //'utm7',
  354. //'utm8',
  355. //'utm9',
  356. 'utm_campaign',
  357. 'utm_content',
  358. 'utm_medium',
  359. 'utm_source',
  360. 'utm_term',
  361. 'uuid',
  362. //'utype',
  363. //'ve',
  364. //'ved',
  365. //'zone'
  366. ];
  367.  
  368. // URL Indexers
  369. const paraIDX = [
  370. 'algo_exp_id',
  371. 'algo_pvid',
  372. 'b64e',
  373. 'cst',
  374. 'cts',
  375. 'data',
  376. 'ei',
  377. //'etext',
  378. 'from',
  379. 'iflsig',
  380. 'gbv',
  381. 'gs_lcp',
  382. 'hdtime',
  383. 'keyno',
  384. 'l10n',
  385. 'mc',
  386. 'oq',
  387. //'q',
  388. 'sei',
  389. 'sclient',
  390. 'sign',
  391. 'source',
  392. 'state',
  393. //'text',
  394. 'uact',
  395. 'uuid',
  396. 'ved'];
  397.  
  398. // Market Places
  399. const paraMKT = [
  400. '___SID',
  401. '_t',
  402. 'ad_pvid',
  403. 'af',
  404. 'aff_fsk',
  405. 'aff_platform',
  406. 'aff_trace_key',
  407. 'afSmartRedirect',
  408. 'bizType',
  409. 'businessType',
  410. 'ck',
  411. 'content-id',
  412. 'crid',
  413. 'curPageLogUid',
  414. 'deals-widget',
  415. 'edm_click_module',
  416. 'gatewayAdapt',
  417. 'gps-id',
  418. 'keywords',
  419. 'pd_rd_i',
  420. 'pd_rd_r',
  421. 'pd_rd_w',
  422. 'pd_rd_wg',
  423. 'pdp_npi',
  424. 'pf_rd_i',
  425. 'pf_rd_m',
  426. 'pf_rd_p',
  427. 'pf_rd_r',
  428. 'pf_rd_s',
  429. 'pf_rd_t',
  430. 'platform',
  431. 'pdp_ext_f',
  432. 'ref_',
  433. 'refinements',
  434. 'rowan_id1',
  435. 'rowan_msg_id',
  436. 'scm',
  437. 'scm_id',
  438. 'scm-url',
  439. 'shareId',
  440. //'showVariations',
  441. 'sk',
  442. 'smid',
  443. 'social_params',
  444. 'spLa',
  445. 'spm',
  446. 'spreadType',
  447. 'sr',
  448. 'srcSns',
  449. 'terminal_id',
  450. 'th', // Sometimes restored after page load
  451. 'tracelog',
  452. 'tt',
  453. 'ug_edm_item_id'];
  454.  
  455. // IL
  456. const paraIL = [
  457. 'dicbo',
  458. 'obOrigUrl'];
  459.  
  460. // General
  461. const paraWWW = [
  462. 'aff',
  463. 'promo',
  464. 'promoid',
  465. 'ref',
  466. 'utm_campaign',
  467. 'utm_content',
  468. 'utm_medium',
  469. 'utm_source',
  470. 'utm_term'];
  471.  
  472. // For URL of the Address bar
  473. // Check and modify page address
  474. // TODO Add bar and ask to clean address bar
  475. (function modifyURL() {
  476.  
  477. let
  478. check = [],
  479. url = new URL(location.href);
  480.  
  481. // TODO turn into boolean function
  482. for (let i = 0; i < blacklist.length; i++) {
  483. if (url.searchParams.get(blacklist[i])) {
  484. check.push(blacklist[i]);
  485. url.searchParams.delete(blacklist[i]);
  486. //newURL = url.origin + url.pathname + url.search + url.hash;
  487. }
  488. }
  489.  
  490. // TODO turn into boolean function
  491. for (let i = 0; i < hash.length; i++) {
  492. if (url.hash.startsWith('#' + hash[i])) {
  493. check.push(hash[i]);
  494. //newURL = url.origin + url.pathname + url.search;
  495. }
  496. }
  497.  
  498. if (check.length > 0) {
  499. let newURL = url.origin + url.pathname + url.search;
  500. window.history.pushState(null, null, newURL);
  501. //location.href = newURL;
  502. }
  503.  
  504. })();
  505.  
  506. (function scanAllURLs() {
  507. for (let i = 0; i < document.links.length; i++) {
  508. let url = new URL(document.links[i].href);
  509. // NOTE Consider BitTorrent Magnet links
  510. // removing trackers would need a warning about
  511. // private torrents, if torrent is not public (dht-enabled)
  512. const allowedProtocols = [
  513. 'finger:', 'freenet:', 'gemini:', 'gopher:',
  514. 'wap:', 'ipfs:', 'https:', 'ftps:', 'http:', 'ftp:'];
  515. if (url.search && allowedProtocols.includes(url.protocol)) {
  516. //if (url.search || url.hash) {
  517. document.links[i].setAttribute('href-data', document.links[i].href);
  518. }
  519. }
  520. })();
  521.  
  522. (function scanBadURLs() {
  523. for (let i = 0; i < document.links.length; i++) {
  524. // TODO callback, Mutation Observer, and Event Listener
  525. hash.forEach(j => cleanLink(document.links[i], j, 'hash'));
  526. blacklist.forEach(j => cleanLink(document.links[i], j, 'para'));
  527. }
  528. })();
  529.  
  530. // TODO Add an Event Listener
  531. function cleanLink(link, target, type) {
  532. let url = new URL(link.href);
  533. switch (type) {
  534. case 'hash':
  535. //console.log('hash ' + i)
  536. if (url.hash.startsWith('#' + target)) {
  537. //link.setAttribute('href-data', link.href);
  538. link.href = url.origin + url.pathname + url.search;
  539. }
  540. break;
  541. case 'para':
  542. //console.log('para ' + i)
  543. if (url.searchParams.get(target)) {
  544. url.searchParams.delete(target);
  545. //link.setAttribute('href-data', link.href);
  546. link.href = url.origin + url.pathname + url.search;
  547. }
  548. break;
  549. }
  550.  
  551. /*
  552. // EXTRA
  553. // For URL of hyperlinks
  554. for (const a of document.querySelectorAll('a')) {
  555. try{
  556. let url = new URL(a.href);
  557. for (let i = 0; i < blacklist.length; i++) {
  558. if (url.searchParams.get(blacklist[i])) {
  559. url.searchParams.delete(blacklist[i]);
  560. }
  561. }
  562. a.href = url;
  563. } catch (err) {
  564. //console.warn('Found no href for element: ' + a);
  565. //console.error(err);
  566. }
  567. } */
  568.  
  569. }
  570.  
  571. // TODO Hunt (for any) links within attributes using getAttributeNames()[i]
  572.  
  573. // Event Listener
  574. // TODO Scan 'e.target.childNodes' until 'href-data' (link) is found
  575. document.body.addEventListener("mouseover", function(e) { // mouseover works with keyboard too
  576. //if (e.target && e.target.nodeName == "A") {
  577. hrefData = e.target.getAttribute('href-data');
  578. //if (e.target && hrefData && !document.getElementById(namespace)) {
  579. if (e.target && hrefData && hrefData != document.getElementById('url-original')) {
  580. if (document.getElementById(namespace)) {
  581. document.getElementById(namespace).remove();
  582. }
  583. selectionItem = createButton(e.pageX, e.pageY, hrefData);
  584. hrefData = new URL(hrefData);
  585. selectionItem.append(purgeURL(hrefData));
  586. let types = ['whitelist', 'blacklist', 'original']
  587. for (let i = 0; i < types.length; i++) {
  588. let button = purgeURL(hrefData, types[i]);
  589. let exist;
  590. selectionItem.childNodes.forEach(
  591. node => {
  592. if (button.href == node.href) {
  593. exist = true;
  594. }
  595. }
  596. )
  597. if (!exist) {
  598. selectionItem.append(button);
  599. }
  600. }
  601.  
  602. // Check for URLs
  603. for (let i = 0; i < urls.length; i++) {
  604. if (hrefData.searchParams.get(urls[i])) { // hrefData.includes('url=')
  605. urlParameter = hrefData.searchParams.get(urls[i]);
  606. try {
  607. urlParameter = new URL (urlParameter);
  608. } catch {
  609. if (urlParameter.includes('.')) { // NOTE It is a guess
  610. try {
  611. urlParameter = new URL ('http:' + urlParameter);
  612. } catch {}
  613. }
  614. }
  615. if (typeof urlParameter == 'object') {
  616. newURLItem = extractURL(urlParameter);
  617. selectionItem.prepend(newURLItem);
  618. }
  619. }
  620. }
  621.  
  622. // compare original against purged
  623. if (selectionItem.querySelector(`#url-purged`)) {
  624. //let urlOrigin = new URL (selectionItem.querySelector(`#url-original`).href);
  625. let urlPurge = new URL (selectionItem.querySelector(`#url-purged`).href);
  626. console.log(urlPurge.searchParams.sort())
  627. console.log(hrefData.searchParams.sort())
  628. if (hrefData.search == urlPurge.search) {
  629. selectionItem.querySelector(`#url-original`).remove();
  630. }
  631. }
  632.  
  633. // do not add element, if url has only whitelisted parameters and no potential url
  634. // add element, only if a potential url or non-whitelisted parameter was found
  635. let urlTypes = ['url-extracted', 'url-original', 'url-purged'];
  636. for (let i = 0; i < urlTypes.length; i++) {
  637. if (selectionItem.querySelector(`#${urlTypes[i]}`)) {
  638. document.body.append(selectionItem);
  639. return;
  640. }
  641. }
  642.  
  643. // NOTE in case return did not reach
  644. e.target.removeAttribute('href-data')
  645.  
  646. }
  647. });
  648.  
  649. function createButton(x, y, url) {
  650. // create element
  651. let item = document.createElement(namespace);
  652. // set content
  653. item.id = namespace;
  654. // set position
  655. item.style.all = 'unset';
  656. item.style.position = 'absolute';
  657. item.style.left = x+5 + 'px';
  658. item.style.top = y-3 + 'px';
  659. // set appearance
  660. item.style.fontFamily = 'none'; // emoji
  661. item.style.background = '#333';
  662. item.style.borderRadius = '5%';
  663. item.style.padding = '3px';
  664. item.style.zIndex = 10000;
  665. //item.style.opacity = 0.7;
  666. item.style.filter = 'brightness(0.7)'
  667. // center character
  668. item.style.justifyContent = 'center';
  669. item.style.alignItems = 'center';
  670. item.style.display = 'flex';
  671. // disable selection marks
  672. item.style.userSelect = 'none';
  673. item.style.cursor = 'default';
  674. // set button behaviour
  675. item.onmouseover = () => {
  676. //item.style.opacity = 1;
  677. item.style.filter = 'unset';
  678. };
  679. item.onmouseleave = () => { // onmouseout
  680. // TODO Wait a few seconds
  681. item.remove();
  682. };
  683. return item;
  684. }
  685.  
  686. function extractURL(url) {
  687. let item = document.createElement('a');
  688. item.textContent = '🔗'; // 🧧 🏷️ 🔖
  689. item.title = 'Extracted URL';
  690. item.id = 'url-extracted';
  691. item.style.all = 'unset';
  692. item.style.outline = 'none';
  693. item.style.height = '15px';
  694. item.style.width = '15px';
  695. item.style.padding = '3px';
  696. item.style.margin = '3px';
  697. //item.style.fontSize = '0.9rem' // 90%
  698. item.style.lineHeight = 'normal'; // initial
  699. //item.style.height = 'fit-content';
  700. item.href = url;
  701. return item;
  702. }
  703.  
  704. // TODO Use icons (with shapes) for cases when color is not optimal
  705. function purgeURL(url, listType) {
  706. let itemTitle, itemId, resUrl;
  707. let item = document.createElement('a');
  708. item.style.all = 'unset';
  709. switch (listType) {
  710. case 'blacklist':
  711. itemColor = 'yellow';
  712. //itemTextContent = '🟡';
  713. itemTitle = 'Clean link'; // Purged URL
  714. itemId = 'url-purged';
  715. resUrl = hrefDataHandler(url, blacklist);
  716. break;
  717. case 'original': // TODO dbclick (double-click)
  718. itemColor = 'orangered';
  719. //itemTextContent = '🔴';
  720. itemTitle = 'Unsafe link'; // Original URL
  721. itemId = 'url-original';
  722. resUrl = url;
  723. item.style.cursor = `not-allowed`; // no-drop
  724. item.onmouseenter = () => {
  725. item.style.filter = `drop-shadow(2px 4px 6px ${itemColor})`;
  726. };
  727. item.onmouseout = () => {
  728. item.style.filter = 'unset';
  729. };
  730. break;
  731. case 'whitelist':
  732. itemColor = 'lawngreen';
  733. //itemTextContent = '🟢';
  734. itemTitle = 'Safe link'; // Link with whitelisted parameters
  735. itemId = 'url-known';
  736. resUrl = hrefDataHandler(url, whitelist);
  737. break;
  738. default:
  739. itemColor = 'antiquewhite';
  740. //itemTextContent = '⚪';
  741. itemTitle = 'Base link'; // Link without parameters
  742. itemId = 'url-base';
  743. resUrl = url.origin + url.pathname;
  744. break;
  745. }
  746. item.id = itemId;
  747. item.title = itemTitle;
  748. item.style.background = itemColor;
  749. //item.textContent = itemTextContent;
  750. item.style.borderRadius = '50%';
  751. item.style.outline = 'none';
  752. item.style.height = '15px';
  753. item.style.width = '15px';
  754. item.style.padding = '3px';
  755. item.style.margin = '3px';
  756. item.href = resUrl;
  757. return item;
  758. }
  759.  
  760. function hrefDataHandler(url, listType) {
  761. url = new URL(url.href);
  762. url.searchParams.sort();
  763. switch (listType) {
  764. case whitelist:
  765. let newURL = new URL (url.origin + url.pathname);
  766. for (let i = 0; i < whitelist.length; i++) {
  767. if (url.searchParams.get(whitelist[i])) {
  768. newURL.searchParams.set(
  769. whitelist[i],
  770. url.searchParams.get(whitelist[i]) // catchedValue
  771. );
  772. }
  773. }
  774. url = newURL;
  775. break;
  776. case blacklist:
  777. for (let i = 0; i < blacklist.length; i++) {
  778. if (url.searchParams.get(blacklist[i])) {
  779. url.searchParams.delete(blacklist[i]);
  780. }
  781. }
  782. break;
  783. }
  784. return url;
  785. }