@@ -353,6 +353,47 @@ angular
353
353
* @param {!MdPanelPosition } position
354
354
*/
355
355
356
+ /**
357
+ * @ngdoc method
358
+ * @name MdPanelRef#registerInterceptor
359
+ * @description
360
+ *
361
+ * Registers an interceptor with the panel. The callback should return a promise,
362
+ * which will allow the action to continue when it gets resolved, or will
363
+ * prevent an action if it is rejected. The interceptors are called sequentially
364
+ * and it reverse order. `type` must be one of the following
365
+ * values available on `$mdPanel.interceptorTypes`:
366
+ * * `CLOSE` - Gets called before the panel begins closing.
367
+ *
368
+ * @param {string } type Type of interceptor.
369
+ * @param {!angular.$q.Promise<any> } callback Callback to be registered.
370
+ * @returns {!MdPanelRef }
371
+ */
372
+
373
+ /**
374
+ * @ngdoc method
375
+ * @name MdPanelRef#removeInterceptor
376
+ * @description
377
+ *
378
+ * Removes a registered interceptor.
379
+ *
380
+ * @param {string } type Type of interceptor to be removed.
381
+ * @param {function(): !angular.$q.Promise<any> } callback Interceptor to be removed.
382
+ * @returns {!MdPanelRef }
383
+ */
384
+
385
+ /**
386
+ * @ngdoc method
387
+ * @name MdPanelRef#removeAllInterceptors
388
+ * @description
389
+ *
390
+ * Removes all interceptors. If a type is supplied, only the
391
+ * interceptors of that type will be cleared.
392
+ *
393
+ * @param {string= } type Type of interceptors to be removed.
394
+ * @returns {!MdPanelRef }
395
+ */
396
+
356
397
357
398
/*****************************************************************************
358
399
* MdPanelPosition *
@@ -743,6 +784,12 @@ function MdPanelService($rootElement, $rootScope, $injector, $window) {
743
784
* @type {enum }
744
785
*/
745
786
this . yPosition = MdPanelPosition . yPosition ;
787
+
788
+ /**
789
+ * Possible values for the interceptors that can be registered on a panel.
790
+ * @type {enum }
791
+ */
792
+ this . interceptorTypes = MdPanelRef . interceptorTypes ;
746
793
}
747
794
748
795
@@ -912,9 +959,20 @@ function MdPanelRef(config, $injector) {
912
959
913
960
/** @private {Function?} */
914
961
this . _restoreScroll = null ;
962
+
963
+ /**
964
+ * Keeps track of all the panel interceptors.
965
+ * @private {!Object}
966
+ */
967
+ this . _interceptors = Object . create ( null ) ;
915
968
}
916
969
917
970
971
+ MdPanelRef . interceptorTypes = {
972
+ CLOSE : 'onClose'
973
+ } ;
974
+
975
+
918
976
/**
919
977
* Opens an already created and configured panel. If the panel is already
920
978
* visible, does nothing.
@@ -944,13 +1002,15 @@ MdPanelRef.prototype.close = function() {
944
1002
var self = this ;
945
1003
946
1004
return this . _$q ( function ( resolve , reject ) {
947
- var done = self . _done ( resolve , self ) ;
948
- var detach = self . _simpleBind ( self . detach , self ) ;
949
-
950
- self . hide ( )
951
- . then ( detach )
952
- . then ( done )
953
- . catch ( reject ) ;
1005
+ self . _callInterceptors ( MdPanelRef . interceptorTypes . CLOSE ) . then ( function ( ) {
1006
+ var done = self . _done ( resolve , self ) ;
1007
+ var detach = self . _simpleBind ( self . detach , self ) ;
1008
+
1009
+ self . hide ( )
1010
+ . then ( detach )
1011
+ . then ( done )
1012
+ . catch ( reject ) ;
1013
+ } , reject ) ;
954
1014
} ) ;
955
1015
} ;
956
1016
@@ -1042,6 +1102,7 @@ MdPanelRef.prototype.detach = function() {
1042
1102
MdPanelRef . prototype . destroy = function ( ) {
1043
1103
this . config . scope . $destroy ( ) ;
1044
1104
this . config . locals = null ;
1105
+ this . _interceptors = null ;
1045
1106
} ;
1046
1107
1047
1108
@@ -1641,6 +1702,106 @@ MdPanelRef.prototype._animateClose = function() {
1641
1702
} ) ;
1642
1703
} ;
1643
1704
1705
+ /**
1706
+ * Registers a interceptor with the panel. The callback should return a promise,
1707
+ * which will allow the action to continue when it gets resolved, or will
1708
+ * prevent an action if it is rejected.
1709
+ * @param {string } type Type of interceptor.
1710
+ * @param {!angular.$q.Promise<!any> } callback Callback to be registered.
1711
+ * @returns {!MdPanelRef }
1712
+ */
1713
+ MdPanelRef . prototype . registerInterceptor = function ( type , callback ) {
1714
+ var error = null ;
1715
+
1716
+ if ( ! angular . isString ( type ) ) {
1717
+ error = 'Interceptor type must be a string, instead got ' + typeof type ;
1718
+ } else if ( ! angular . isFunction ( callback ) ) {
1719
+ error = 'Interceptor callback must be a function, instead got ' + typeof callback ;
1720
+ }
1721
+
1722
+ if ( error ) {
1723
+ throw new Error ( 'MdPanel: ' + error ) ;
1724
+ }
1725
+
1726
+ var interceptors = this . _interceptors [ type ] = this . _interceptors [ type ] || [ ] ;
1727
+
1728
+ if ( interceptors . indexOf ( callback ) === - 1 ) {
1729
+ interceptors . push ( callback ) ;
1730
+ }
1731
+
1732
+ return this ;
1733
+ } ;
1734
+
1735
+ /**
1736
+ * Removes a registered interceptor.
1737
+ * @param {string } type Type of interceptor to be removed.
1738
+ * @param {Function } callback Interceptor to be removed.
1739
+ * @returns {!MdPanelRef }
1740
+ */
1741
+ MdPanelRef . prototype . removeInterceptor = function ( type , callback ) {
1742
+ var index = this . _interceptors [ type ] ?
1743
+ this . _interceptors [ type ] . indexOf ( callback ) : - 1 ;
1744
+
1745
+ if ( index > - 1 ) {
1746
+ this . _interceptors [ type ] . splice ( index , 1 ) ;
1747
+ }
1748
+
1749
+ return this ;
1750
+ } ;
1751
+
1752
+
1753
+ /**
1754
+ * Removes all interceptors.
1755
+ * @param {string= } type Type of interceptors to be removed.
1756
+ * If ommited, all interceptors types will be removed.
1757
+ * @returns {!MdPanelRef }
1758
+ */
1759
+ MdPanelRef . prototype . removeAllInterceptors = function ( type ) {
1760
+ if ( type ) {
1761
+ this . _interceptors [ type ] = [ ] ;
1762
+ } else {
1763
+ this . _interceptors = Object . create ( null ) ;
1764
+ }
1765
+
1766
+ return this ;
1767
+ } ;
1768
+
1769
+
1770
+ /**
1771
+ * Invokes all the interceptors of a certain type sequantially in
1772
+ * reverse order. Works in a similar way to `$q.all`, except it
1773
+ * respects the order of the functions.
1774
+ * @param {string } type Type of interceptors to be invoked.
1775
+ * @returns {!angular.$q.Promise<!MdPanelRef> }
1776
+ * @private
1777
+ */
1778
+ MdPanelRef . prototype . _callInterceptors = function ( type ) {
1779
+ var self = this ;
1780
+ var $q = self . _$q ;
1781
+ var interceptors = self . _interceptors && self . _interceptors [ type ] || [ ] ;
1782
+
1783
+ return interceptors . reduceRight ( function ( promise , interceptor ) {
1784
+ var isPromiseLike = interceptor && angular . isFunction ( interceptor . then ) ;
1785
+ var response = isPromiseLike ? interceptor : null ;
1786
+
1787
+ /**
1788
+ * For interceptors to reject/cancel subsequent portions of the chain, simply
1789
+ * return a `$q.reject(<value>)`
1790
+ */
1791
+ return promise . then ( function ( ) {
1792
+ if ( ! response ) {
1793
+ try {
1794
+ response = interceptor ( self ) ;
1795
+ } catch ( e ) {
1796
+ response = $q . reject ( e ) ;
1797
+ }
1798
+ }
1799
+
1800
+ return response ;
1801
+ } ) ;
1802
+ } , $q . resolve ( self ) ) ;
1803
+ } ;
1804
+
1644
1805
1645
1806
/**
1646
1807
* Faster, more basic than angular.bind
0 commit comments