@@ -51,12 +51,18 @@ function onBeforeRequest(details) {
5151 type = details . type ,
5252 url = details . url ;
5353
54+ let noUtm = stripUtmParams ( url ) ;
55+
5456 if ( type == "main_frame" ) {
5557 forgetTab ( tab_id ) ;
5658
5759 badger . recordFrame ( tab_id , frame_id , details . parentFrameId , url ) ;
5860
59- return { } ;
61+ if ( noUtm ) {
62+ return { redirectUrl : noUtm } ;
63+ } else {
64+ return { } ;
65+ }
6066 }
6167
6268 if ( type == "sub_frame" ) {
@@ -82,6 +88,9 @@ function onBeforeRequest(details) {
8288 }
8389
8490 var requestAction = checkAction ( tab_id , requestDomain , frame_id ) ;
91+
92+ // if requestAction is false, this is a private domain OR the domain/frame has
93+ // been unblocked
8594 if ( ! requestAction ) {
8695 return { } ;
8796 }
@@ -93,7 +102,11 @@ function onBeforeRequest(details) {
93102 }
94103
95104 if ( requestAction != constants . BLOCK && requestAction != constants . USER_BLOCK ) {
96- return { } ;
105+ if ( noUtm ) {
106+ return { redirectUrl : noUtm } ;
107+ } else {
108+ return { } ;
109+ }
97110 }
98111
99112 if ( type == 'script' ) {
@@ -601,6 +614,44 @@ function unblockSocialWidgetOnTab(tabId, socialWidgetUrls) {
601614 }
602615}
603616
617+ /**
618+ * Strip Urchin Tracking Module (UTM) parameters from a url
619+ * Adapted from au-revoir-utm (https://github.com/rik/au-revoir-utm), 2018-09-06
620+ *
621+ * @param {String } url The URL of the outgoing request
622+ */
623+ function stripUtmParams ( url ) {
624+ const UTM_PREFIX = 'utm_' ;
625+
626+ // short-circuit if this isn't an HTTPS link,
627+ // or if there aren't any utm parameters
628+ if ( ! url . startsWith ( 'https://' ) || ! url . includes ( UTM_PREFIX ) ) {
629+ return ;
630+ }
631+
632+ // remove utm from normal url parameters
633+ let parsedURL = new URL ( url )
634+ for ( let param of [ ...parsedURL . searchParams . keys ( ) ] ) {
635+ if ( param . startsWith ( UTM_PREFIX ) ) {
636+ parsedURL . searchParams . delete ( param ) ;
637+ }
638+ }
639+
640+ // remove utm from parameters after the hash in the url
641+ let parsedFragment = new URLSearchParams ( parsedURL . hash . substring ( 1 ) )
642+ for ( let param of [ ...parsedFragment . keys ( ) ] ) {
643+ if ( param . startsWith ( UTM_PREFIX ) ) {
644+ parsedFragment . delete ( param ) ;
645+ }
646+ }
647+ parsedURL . hash = parsedFragment . toString ( ) ;
648+
649+ // if the url has changed, return it. Otherwise return null.
650+ if ( parsedUrl != url ) {
651+ return parsedURL . toString ( ) ;
652+ }
653+ }
654+
604655/**
605656 * sender.tab is available for content script (not popup) messages only
606657 */
0 commit comments