sjehuda / Clean URL Improved

// ==UserScript== 
// @name        Clean URL Improved 
// @namespace   org.openuserjs.cleanurlinterface 
// @description Remove tracking parameters and redirect to original URL. This Userscript uses the URL Interface instread of RegEx.
// @homepageURL https://openuserjs.org/scripts/sjehuda/Clean_URL_Improved
// @supportURL  https://openuserjs.org/scripts/sjehuda/Clean_URL_Improved/issues
// @updateURL   https://openuserjs.org/meta/sjehuda/Clean_URL_Improved.meta.js
// @copyright   2023, Schimon Jehudah (http://schimon.i2p)
// @license     MIT; https://opensource.org/licenses/MIT
// @grant       none
// @run-at      document-end
// @include     *
// @version     23.03-1
// @noframes
// @icon        data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48dGV4dCB5PSIuOWVtIiBmb250LXNpemU9IjkwIj7wn6e5PC90ZXh0Pjwvc3ZnPgo= 

// ==/UserScript==

// NOTE
//
// Flying broom (Halloween pack) created by cah nggunung
// https://www.flaticon.com/premium-icon/flying-broom_5443441
// https://www.flaticon.com/authors/cah-nggunung
//
// Simple version of this Userscript
// let url = new URL(location.href);
// if (url.hash || url.search) {
//   location.href = url.origin + url.pathname
// };
//
// Check whether single parameter 
// url.search.split('&').length
//

let check = [], point = [];

// List of Hash
const hash = [
  'back-url',
  'niche-',
  'src'];

// List of Parameters
const para = [
  //'__cf_chl_rt_tk',
  '___SID',
  '_t',
  'ad_sub',
  'ad_pvid',
  //'ad_tags',
  //'aem_p4p_detail',
  'af',
  'aff_fcid',
  'aff_fsk',
  'aff_platform',
  'aff_trace_key',
  'affparams',
  'afSmartRedirect',
  //'aid',
  'algo_exp_id',
  'algo_pvid',
  //'ascsubtag',
  //'asc_contentid',
  'asgtbndr',
  //'b64e', // breaks yandex
  'bizType',
  //'block',
  'bta',
  'businessType',
  'campaign',
  'campaignId',
  'cid',
  'ck',
  //'clickid',
  //'client_id',
  //'cm_ven',
  'crid',
  'cst',
  'cts',
  'curPageLogUid',
  //'data', // breaks yandex
  //'dchild',
  //'dclid',
  'deals-widget',
  'dicbo',
  //'dt',
  'edd',
  'edm_click_module',
  //'ei',
  //'embed',
  //'etext', // breaks yandex
  'fbclid',
  'feature',
  'format',
  //'fr',
  'frs',
  //'from', // breaks yandex
  'ga_order',
  'ga_search_query',
  'ga_search_type',
  'ga_view_type',
  'gatewayAdapt',
  //'gclid',
  //'gclsrc',
  'gps-id',
  //'gs_lcp',
  'gt',
  'guccounter',
  'hdtime',
  'ICID',
  //'idzone',
  //'iflsig',
  //'irgwc',
  //'irpid',
  //'katds_labels',
  //'keywords',
  'keyno',
  'l10n',
  'linkCode',
  'mc',
  'mp',
  'nats',
  'nci',
  'obOrigUrl',
  'oq',
  'organic_search_click',
  'partner',
  'pk_campaign',
  'partner_id',
  'pd_rd_i',
  'pd_rd_r',
  'pd_rd_w',
  'pd_rd_wg',
  'pdp_npi',
  'pf_rd_i',
  'pf_rd_m',
  'pf_rd_p',
  'pf_rd_r',
  'pf_rd_s',
  'pf_rd_t',
  'pdp_ext_f',
  'pkey',
  'platform',
  'plkey',
  'pqr',
  'pro',
  'promo',
  'promocode',
  'promoid',
  'psc',
  'psprogram',
  'pvid',
  'qid',
  //'r',
  'realDomain',
  'ref',
  'ref_',
  'refcode',
  'referrer',
  'refinements',
  'rowan_id1',
  'rowan_msg_id',
  //'s',
  //'sCh',
  'sclient',
  'scm',
  'scm_id',
  'scm-url',
  'shareId',
  'showVariations',
  'sid',
  //'sign', // breaks yandex
  //'site_id',
  'sk',
  'smid',
  'social_params',
  'source',
  'sourceId',
  'spLa',
  'spm',
  'spreadType',
  //'sprefix',
  'sr',
  'srcSns',
  //'state', // breaks yandex
  'tag',
  'tcampaign',
  'td',
  'terminal_id',
  //'text',
  'th', // Sometimes restored after page load
  //'title',
  'tracelog',
  'traffic_id',
  'traffic_type',
  'tt',
  'uact',
  'ug_edm_item_id',
  //'utm1',
  //'utm2',
  //'utm3',
  //'utm4',
  //'utm5',
  //'utm6',
  //'utm7',
  //'utm8',
  //'utm9',
  'utm_campaign',
  'utm_content',
  'utm_medium',
  'utm_source',
  'utm_term',
  'uuid',
  //'utype',
  //'ve',
  //'ved',
  //'zone'
  ];

// URL Indexers
const paraIDX = [
  'algo_exp_id',
  'algo_pvid',
  'b64e',
  'cst',
  'cts',
  'data',
  'ei',
  //'etext',
  'from',
  'iflsig',
  'gbv',
  'gs_lcp',
  'hdtime',
  'keyno',
  'l10n',
  'mc',
  'oq',
  //'q',
  'sei',
  'sclient',
  'sign',
  'source',
  'state',
  //'text',
  'uact',
  'uuid',
  'ved'];

// Market Places 
const paraMKT = [
  '___SID',
  '_t',
  'ad_pvid',
  'af',
  'aff_fsk',
  'aff_platform',
  'aff_trace_key',
  'afSmartRedirect',
  'bizType',
  'businessType',
  'ck',
  'crid',
  'curPageLogUid',
  'deals-widget',
  'edm_click_module',
  'gatewayAdapt',
  'gps-id',
  'keywords',
  'pd_rd_i',
  'pd_rd_r',
  'pd_rd_w',
  'pd_rd_wg',
  'pdp_npi',
  'pf_rd_i',
  'pf_rd_m',
  'pf_rd_p',
  'pf_rd_r',
  'pf_rd_s',
  'pf_rd_t',
  'platform',
  'pdp_ext_f',
  'ref_',
  'refinements',
  'rowan_id1',
  'rowan_msg_id',
  'scm',
  'scm_id',
  'scm-url',
  'shareId',
  //'showVariations',
  'sk',
  'smid',
  'social_params',
  'spLa',
  'spreadType',
  'sr',
  'srcSns',
  'terminal_id',
  'th', // Sometimes restored after page load
  'tracelog',
  'tt',
  'ug_edm_item_id'];

// IL
const paraIL = [
  'dicbo',
  'obOrigUrl'];

// General
const paraWWW = [
  'aff',
  'promo',
  'promoid',
  'ref',
  'utm_campaign',
  'utm_content',
  'utm_medium',
  'utm_source',
  'utm_term'];

// For URL of the Address bar
// Check and modify page address
// TODO Add an Event Listener
let url = new URL(location.href);

// TODO turn into boolean function
for (let i = 0; i < para.length; i++) {
  if (url.searchParams.get(para[i])) {
    check.push(para[i]);
    url.searchParams.delete(para[i]);
    //newURL = url.origin + url.pathname + url.search + url.hash;
  }
}

// TODO turn into boolean function
for (let i = 0; i < hash.length; i++) {
  if (url.hash.startsWith('#' + hash[i])) {
    check.push(hash[i]);
    //newURL = url.origin + url.pathname + url.search;
  }
}

if (check.length > 0) {
  //alert(check)
  var newURL = url.origin + url.pathname + url.search;
  window.history.pushState(null, null, newURL);
  //location.href = newURL;
}

// TODO Add an Event Listener
function cleanLink(target, type) {
  for (let i = 0; i < document.links.length; i++) {
    let url = new URL(document.links[i].href);
    var modify = false;
    switch (type) {

      case 'hash':
      //console.log('hash ' + i)
      if (url.hash.startsWith('#' + target)) {
        //console.log(document.links[i].href + ' (hash) ' + i)
        modify = true;
        document.links[i].href = url.origin + url.pathname + url.search;
      }
      break;

      case 'para':
      //console.log('para ' + i)
      if (url.searchParams.get(target)) { 
        //console.log(document.links[i].href + ' (para) ' + i)
        url.searchParams.delete(target);
        modify = true;
        document.links[i].href = url.origin + url.pathname + url.search;
      }
      break;

    }

    if (modify) {
      document.links[i].href = url.origin + url.pathname + url.search;
      //console.log(document.links[i].href + ' (mod) ' + i)
      //point.push(null);
    }

  }
}

// TODO callback, Mutation Observer, and Event Listener
hash.forEach(i => cleanLink(i, 'hash'));
para.forEach(i => cleanLink(i, 'para'));

// For URL of hyperlinks
for (const a of document.querySelectorAll('a')) {
  try{
    let url = new URL(a.href);
    for (let i = 0; i < para.length; i++) {
      if (url.searchParams.get(para[i])) {
        url.searchParams.delete(para[i]);
      }
    }
    a.href = url;
  } catch (err) {
    err // console.warn('Found no href');
  }
}