@@ -18,6 +18,7 @@ var truncate = utils.truncate;
1818var urlencode = utils . urlencode ;
1919var uuid4 = utils . uuid4 ;
2020var htmlElementAsString = utils . htmlElementAsString ;
21+ var parseUrl = utils . parseUrl ;
2122
2223var dsnKeys = 'source protocol user pass host port path' . split ( ' ' ) ,
2324 dsnPattern = / ^ (?: ( \w + ) : ) ? \/ \/ (?: ( \w + ) ( : \w + ) ? @ ) ? ( [ \w \. - ] + ) (?: : ( \d + ) ) ? ( \/ .* ) / ;
@@ -63,7 +64,8 @@ function Raven() {
6364 this . _breadcrumbs = [ ] ;
6465 this . _breadcrumbLimit = 20 ;
6566 this . _lastCapturedEvent = null ;
66- this . _lastHref = window . location && location . href ;
67+ this . _location = window . location ;
68+ this . _lastHref = this . _location && this . _location . href ;
6769
6870 for ( var method in this . _originalConsole ) { // eslint-disable-line guard-for-in
6971 this . _originalConsoleMethods [ method ] = this . _originalConsole [ method ] ;
@@ -642,6 +644,35 @@ Raven.prototype = {
642644 } ;
643645 } ,
644646
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+
645676 /**
646677 * Install any queued plugins
647678 */
@@ -795,15 +826,9 @@ Raven.prototype = {
795826 // TODO: remove onpopstate handler on uninstall()
796827 var oldOnPopState = window . onpopstate ;
797828 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 ) ;
802831
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 ;
807832 if ( oldOnPopState ) {
808833 return oldOnPopState . apply ( this , arguments ) ;
809834 }
@@ -814,13 +839,14 @@ Raven.prototype = {
814839 // params to preserve 0 arity
815840 return function ( /* state, title, url */ ) {
816841 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+
822848 return origPushState . apply ( this , arguments ) ;
823- }
849+ } ;
824850 } ) ;
825851 }
826852
0 commit comments