@@ -303,9 +303,7 @@ function LocationHashbangInHtml5Url(appBase, hashPrefix) {
303
303
}
304
304
305
305
306
- LocationHashbangInHtml5Url . prototype =
307
- LocationHashbangUrl . prototype =
308
- LocationHtml5Url . prototype = {
306
+ var locationPrototype = {
309
307
310
308
/**
311
309
* Are we in html5 mode?
@@ -314,7 +312,7 @@ LocationHashbangInHtml5Url.prototype =
314
312
$$html5 : false ,
315
313
316
314
/**
317
- * Has any change been replacing ?
315
+ * Has any change been replacing?
318
316
* @private
319
317
*/
320
318
$$replace : false ,
@@ -530,6 +528,43 @@ LocationHashbangInHtml5Url.prototype =
530
528
}
531
529
} ;
532
530
531
+ forEach ( [ LocationHashbangInHtml5Url , LocationHashbangUrl , LocationHtml5Url ] , function ( Location ) {
532
+ Location . prototype = Object . create ( locationPrototype ) ;
533
+
534
+ /**
535
+ * @ngdoc method
536
+ * @name $location#state
537
+ *
538
+ * @description
539
+ * This method is getter / setter.
540
+ *
541
+ * Return the history state object when called without any parameter.
542
+ *
543
+ * Change the history state object when called with one parameter and return `$location`.
544
+ * The state object is later passed to `pushState` or `replaceState`.
545
+ *
546
+ * NOTE: This method is supported only in HTML5 mode and only in browsers supporting
547
+ * the HTML5 History API (i.e. methods `pushState` and `replaceState`). If you need to support
548
+ * older browsers (like IE9 or Android < 4.0), don't use this method.
549
+ *
550
+ * @param {object= } state State object for pushState or replaceState
551
+ * @return {object } state
552
+ */
553
+ Location . prototype . state = function ( state ) {
554
+ if ( ! arguments . length )
555
+ return this . $$state ;
556
+
557
+ if ( Location !== LocationHtml5Url || ! this . $$html5 ) {
558
+ throw $locationMinErr ( 'nostate' , 'History API state support is available only ' +
559
+ 'in HTML5 mode and only in browsers supporting HTML5 History API' ) ;
560
+ }
561
+ this . $$state = copy ( state ) ;
562
+
563
+ return this ;
564
+ } ;
565
+ } ) ;
566
+
567
+
533
568
function locationGetter ( property ) {
534
569
return function ( ) {
535
570
return this [ property ] ;
@@ -649,9 +684,14 @@ function $LocationProvider(){
649
684
* details about event object. Upon successful change
650
685
* {@link ng.$location#events_$locationChangeSuccess $locationChangeSuccess} is fired.
651
686
*
687
+ * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when
688
+ * the browser supports the HTML5 History API.
689
+ *
652
690
* @param {Object } angularEvent Synthetic event object.
653
691
* @param {string } newUrl New URL
654
692
* @param {string= } oldUrl URL that was before it was changed.
693
+ * @param {string= } newState New history state object
694
+ * @param {string= } oldState History state object that was before it was changed.
655
695
*/
656
696
657
697
/**
@@ -661,9 +701,14 @@ function $LocationProvider(){
661
701
* @description
662
702
* Broadcasted after a URL was changed.
663
703
*
704
+ * The `newState` and `oldState` parameters may be defined only in HTML5 mode and when
705
+ * the browser supports the HTML5 History API.
706
+ *
664
707
* @param {Object } angularEvent Synthetic event object.
665
708
* @param {string } newUrl New URL
666
709
* @param {string= } oldUrl URL that was before it was changed.
710
+ * @param {string= } newState New history state object
711
+ * @param {string= } oldState History state object that was before it was changed.
667
712
*/
668
713
669
714
this . $get = [ '$rootScope' , '$browser' , '$sniffer' , '$rootElement' ,
@@ -741,18 +786,20 @@ function $LocationProvider(){
741
786
}
742
787
743
788
// update $location when $browser url changes
744
- $browser . onUrlChange ( function ( newUrl ) {
745
- if ( $location . absUrl ( ) != newUrl ) {
789
+ $browser . onUrlChange ( function ( newUrl , newState ) {
790
+ if ( $location . absUrl ( ) !== newUrl ||
791
+ ( $location . $$html5 && $location . state ( ) != newState && ! equals ( $location . state ( ) , newState ) ) ) {
746
792
$rootScope . $evalAsync ( function ( ) {
747
793
var oldUrl = $location . absUrl ( ) ;
794
+ var oldState = $location . state ( ) ;
748
795
749
796
$location . $$parse ( newUrl ) ;
750
- if ( $rootScope . $broadcast ( '$locationChangeStart' , newUrl ,
751
- oldUrl ) . defaultPrevented ) {
797
+ if ( $rootScope . $broadcast ( '$locationChangeStart' , newUrl , oldUrl ,
798
+ newState , oldState ) . defaultPrevented ) {
752
799
$location . $$parse ( oldUrl ) ;
753
- $browser . url ( oldUrl ) ;
800
+ $browser . url ( $location . absUrl ( ) , false , newState ) ;
754
801
} else {
755
- afterLocationChange ( oldUrl ) ;
802
+ afterLocationChange ( oldUrl , oldState ) ;
756
803
}
757
804
} ) ;
758
805
if ( ! $rootScope . $$phase ) $rootScope . $digest ( ) ;
@@ -763,17 +810,19 @@ function $LocationProvider(){
763
810
var changeCounter = 0 ;
764
811
$rootScope . $watch ( function $locationWatch ( ) {
765
812
var oldUrl = $browser . url ( ) ;
813
+ var oldState = $browser . state ( ) ;
766
814
var currentReplace = $location . $$replace ;
767
815
768
- if ( ! changeCounter || oldUrl != $location . absUrl ( ) ) {
816
+ if ( ! changeCounter || oldUrl !== $location . absUrl ( ) ||
817
+ ( $location . $$html5 && oldState != $location . state ( ) && ! equals ( oldState , $location . state ( ) ) ) ) {
769
818
changeCounter ++ ;
770
819
$rootScope . $evalAsync ( function ( ) {
771
- if ( $rootScope . $broadcast ( '$locationChangeStart' , $location . absUrl ( ) , oldUrl ) .
772
- defaultPrevented ) {
820
+ if ( $rootScope . $broadcast ( '$locationChangeStart' , $location . absUrl ( ) , oldUrl ,
821
+ $location . state ( ) , oldState ) . defaultPrevented ) {
773
822
$location . $$parse ( oldUrl ) ;
774
823
} else {
775
- $browser . url ( $location . absUrl ( ) , currentReplace ) ;
776
- afterLocationChange ( oldUrl ) ;
824
+ $browser . url ( $location . absUrl ( ) , currentReplace , $location . state ( ) ) ;
825
+ afterLocationChange ( oldUrl , oldState ) ;
777
826
}
778
827
} ) ;
779
828
}
@@ -784,8 +833,8 @@ function $LocationProvider(){
784
833
785
834
return $location ;
786
835
787
- function afterLocationChange ( oldUrl ) {
788
- $rootScope . $broadcast ( '$locationChangeSuccess' , $location . absUrl ( ) , oldUrl ) ;
836
+ function afterLocationChange ( oldUrl , oldState ) {
837
+ $rootScope . $broadcast ( '$locationChangeSuccess' , $location . absUrl ( ) , oldUrl , $location . state ( ) , oldState ) ;
789
838
}
790
839
} ] ;
791
840
}
0 commit comments