@@ -18,6 +18,7 @@ var truncate = utils.truncate;
18
18
var urlencode = utils . urlencode ;
19
19
var uuid4 = utils . uuid4 ;
20
20
var htmlElementAsString = utils . htmlElementAsString ;
21
+ var parseUrl = utils . parseUrl ;
21
22
22
23
var dsnKeys = 'source protocol user pass host port path' . split ( ' ' ) ,
23
24
dsnPattern = / ^ (?: ( \w + ) : ) ? \/ \/ (?: ( \w + ) ( : \w + ) ? @ ) ? ( [ \w \. - ] + ) (?: : ( \d + ) ) ? ( \/ .* ) / ;
@@ -63,7 +64,8 @@ function Raven() {
63
64
this . _breadcrumbs = [ ] ;
64
65
this . _breadcrumbLimit = 20 ;
65
66
this . _lastCapturedEvent = null ;
66
- this . _lastHref = window . location && location . href ;
67
+ this . _location = window . location ;
68
+ this . _lastHref = this . _location && this . _location . href ;
67
69
68
70
for ( var method in this . _originalConsole ) { // eslint-disable-line guard-for-in
69
71
this . _originalConsoleMethods [ method ] = this . _originalConsole [ method ] ;
@@ -642,6 +644,35 @@ Raven.prototype = {
642
644
} ;
643
645
} ,
644
646
647
+ /**
648
+ * Captures a breadcrumb of type "navigation", normalizing input URLs
649
+ * @param to the originating URL
650
+ * @param from the target URL
651
+ * @private
652
+ */
653
+ _captureUrlChange : function ( from , to ) {
654
+ var parsedLoc = parseUrl ( this . _location . href ) ;
655
+ var parsedTo = parseUrl ( to ) ;
656
+ var parsedFrom = parseUrl ( from ) ;
657
+
658
+ // because onpopstate only tells you the "new" (to) value of location.href, and
659
+ // not the previous (from) value, we need to track the value of the current URL
660
+ // state ourselves
661
+ this . _lastHref = to ;
662
+
663
+ // Use only the path component of the URL if the URL matches the current
664
+ // document (almost all the time when using pushState)
665
+ if ( parsedLoc . protocol === parsedTo . protocol && parsedLoc . host === parsedTo . host )
666
+ to = parsedTo . path ;
667
+ if ( parsedLoc . protocol === parsedFrom . protocol && parsedLoc . host === parsedFrom . host )
668
+ from = parsedFrom . path ;
669
+
670
+ this . captureBreadcrumb ( 'navigation' , {
671
+ to : to ,
672
+ from : from
673
+ } ) ;
674
+ } ,
675
+
645
676
/**
646
677
* Install any queued plugins
647
678
*/
@@ -795,15 +826,9 @@ Raven.prototype = {
795
826
// TODO: remove onpopstate handler on uninstall()
796
827
var oldOnPopState = window . onpopstate ;
797
828
window . onpopstate = function ( ) {
798
- self . captureBreadcrumb ( 'navigation' , {
799
- from : self . _lastHref ,
800
- to : location . href
801
- } ) ;
829
+ var currentHref = self . _location . href ;
830
+ self . _captureUrlChange ( self . _lastHref , currentHref ) ;
802
831
803
- // because onpopstate only tells you the "new" (to) value of location.href, and
804
- // not the previous (from) value, we need to track the value of location.href
805
- // ourselves
806
- self . _lastHref = location . href ;
807
832
if ( oldOnPopState ) {
808
833
return oldOnPopState . apply ( this , arguments ) ;
809
834
}
@@ -814,13 +839,14 @@ Raven.prototype = {
814
839
// params to preserve 0 arity
815
840
return function ( /* state, title, url */ ) {
816
841
var url = arguments . length > 2 ? arguments [ 2 ] : undefined ;
817
- self . captureBreadcrumb ( 'navigation' , {
818
- to : url ,
819
- from : location . href
820
- } ) ;
821
- if ( url ) self . _lastHref = url ;
842
+
843
+ // url argument is optional
844
+ if ( url ) {
845
+ self . _captureUrlChange ( self . _lastHref , url ) ;
846
+ }
847
+
822
848
return origPushState . apply ( this , arguments ) ;
823
- }
849
+ } ;
824
850
} ) ;
825
851
}
826
852
0 commit comments