Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 4fb1767

Browse files
crisbetokara
authored andcommitted
fix(docs, dialog, interim, panel): compatibility with latest angular snapshot (#9787)
* Fixes the docs site not working against the latest snapshot. * Fixes the `dialog` throwing an error about `ngSanitize` not being present and then compiling the contents anyway. * Makes the `interimElement` compatible both with the latest changes to promises from Angular PR #15213 and the current promise handling in Angular <= 1.5. * Reintroduces the panel changes from #9688 which were overwritten accidentally. * Fixes an error that was being swallowed during unit tests, but was still showing up in the `$exceptionHandler`.
1 parent b14fa93 commit 4fb1767

File tree

5 files changed

+88
-77
lines changed

5 files changed

+88
-77
lines changed

docs/app/js/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ function(SERVICES, COMPONENTS, DEMOS, PAGES, $location, $rootScope, $http, $wind
338338
$rootScope.$on('$locationChangeSuccess', onLocationChange);
339339

340340
$http.get("/docs.json")
341-
.success(function(response) {
341+
.then(function(response) {
342342
var versionId = getVersionIdFromPath();
343343
var head = { type: 'version', url: '/HEAD', id: 'head', name: 'HEAD (master)', github: '' };
344344
var commonVersions = versionId === 'head' ? [] : [ head ];

src/components/dialog/dialog.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -686,17 +686,21 @@ function MdDialogProvider($$interimElementProvider) {
686686
function beforeShow(scope, element, options, controller) {
687687

688688
if (controller) {
689-
controller.mdHtmlContent = controller.htmlContent || options.htmlContent || '';
690-
controller.mdTextContent = controller.textContent || options.textContent ||
689+
var mdHtmlContent = controller.htmlContent || options.htmlContent || '';
690+
var mdTextContent = controller.textContent || options.textContent ||
691691
controller.content || options.content || '';
692692

693-
if (controller.mdHtmlContent && !$injector.has('$sanitize')) {
693+
if (mdHtmlContent && !$injector.has('$sanitize')) {
694694
throw Error('The ngSanitize module must be loaded in order to use htmlContent.');
695695
}
696696

697-
if (controller.mdHtmlContent && controller.mdTextContent) {
697+
if (mdHtmlContent && mdTextContent) {
698698
throw Error('md-dialog cannot have both `htmlContent` and `textContent`');
699699
}
700+
701+
// Only assign the content if nothing throws, otherwise it'll still be compiled.
702+
controller.mdHtmlContent = mdHtmlContent;
703+
controller.mdTextContent = mdTextContent;
700704
}
701705
}
702706

@@ -709,7 +713,7 @@ function MdDialogProvider($$interimElementProvider) {
709713
// Once a dialog has `ng-cloak` applied on his template the dialog animation will not work properly.
710714
// This is a very common problem, so we have to notify the developer about this.
711715
if (dialogElement.hasClass('ng-cloak')) {
712-
var message = '$mdDialog: using `<md-dialog ng-cloak >` will affect the dialog opening animations.';
716+
var message = '$mdDialog: using `<md-dialog ng-cloak>` will affect the dialog opening animations.';
713717
$log.warn( message, element[0] );
714718
}
715719

@@ -1004,7 +1008,7 @@ function MdDialogProvider($$interimElementProvider) {
10041008

10051009

10061010
if (options.disableParentScroll) {
1007-
options.restoreScroll();
1011+
options.restoreScroll && options.restoreScroll();
10081012
delete options.restoreScroll;
10091013
}
10101014

src/components/dialog/dialog.spec.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,14 +1768,21 @@ describe('$mdDialog with custom interpolation symbols', function() {
17681768
});
17691769

17701770
describe('$mdDialog without ngSanitize loaded', function() {
1771-
var $mdDialog, $rootScope;
1771+
var $mdDialog, $rootScope, $exceptionHandler;
17721772

1773-
beforeEach(module('material.components.dialog'));
1773+
beforeEach(function() {
1774+
module('material.components.dialog');
17741775

1775-
beforeEach(inject(function($injector) {
1776-
$mdDialog = $injector.get('$mdDialog');
1777-
$rootScope = $injector.get('$rootScope');
1778-
}));
1776+
module(function($exceptionHandlerProvider) {
1777+
$exceptionHandlerProvider.mode('log');
1778+
});
1779+
1780+
inject(function($injector) {
1781+
$mdDialog = $injector.get('$mdDialog');
1782+
$rootScope = $injector.get('$rootScope');
1783+
$exceptionHandler = $injector.get('$exceptionHandler');
1784+
});
1785+
});
17791786

17801787
it('should throw an error when trying to use htmlContent', function() {
17811788
var parent = angular.element('<div>');
@@ -1785,9 +1792,13 @@ describe('$mdDialog without ngSanitize loaded', function() {
17851792
htmlContent('Hello, world !').
17861793
ok('OK');
17871794

1788-
expect(function() {
1789-
$mdDialog.show(dialog);
1790-
$rootScope.$digest();
1791-
}).toThrowError(/ngSanitize/);
1795+
$mdDialog.show(dialog);
1796+
$rootScope.$digest();
1797+
1798+
// Make sure that only our custom error was logged.
1799+
expect($exceptionHandler.errors.length).toBe(1);
1800+
expect($exceptionHandler.errors[0].message).toBe(
1801+
'The ngSanitize module must be loaded in order to use htmlContent.'
1802+
);
17921803
});
17931804
});

src/components/panel/panel.spec.js

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,7 +2468,8 @@ describe('$mdPanel', function() {
24682468
spyOn(obj, 'callback');
24692469

24702470
panelRef.registerInterceptor(interceptorTypes.CLOSE, obj.callback);
2471-
callInterceptors('CLOSE');
2471+
panelRef._callInterceptors(interceptorTypes.CLOSE);
2472+
flushPanel();
24722473

24732474
expect(obj.callback).toHaveBeenCalledWith(panelRef);
24742475
});
@@ -2482,8 +2483,9 @@ describe('$mdPanel', function() {
24822483
panelRef.registerInterceptor(interceptorTypes.CLOSE, makePromise(1));
24832484
panelRef.registerInterceptor(interceptorTypes.CLOSE, makePromise(2));
24842485
panelRef.registerInterceptor(interceptorTypes.CLOSE, makePromise(3));
2485-
callInterceptors('CLOSE').then(obj.callback);
2486-
$rootScope.$apply();
2486+
2487+
panelRef._callInterceptors(interceptorTypes.CLOSE).then(obj.callback);
2488+
flushPanel();
24872489

24882490
expect(results).toEqual([3, 2, 1]);
24892491
expect(obj.callback).toHaveBeenCalled();
@@ -2507,8 +2509,8 @@ describe('$mdPanel', function() {
25072509
panelRef.registerInterceptor(interceptorTypes.CLOSE, makePromise(2));
25082510
panelRef.registerInterceptor(interceptorTypes.CLOSE, makePromise(3));
25092511

2510-
callInterceptors('CLOSE').catch(obj.callback);
2511-
$rootScope.$apply();
2512+
panelRef._callInterceptors(interceptorTypes.CLOSE).catch(obj.callback);
2513+
flushPanel();
25122514

25132515
expect(results).toEqual([3, 2]);
25142516
expect(obj.callback).toHaveBeenCalled();
@@ -2535,8 +2537,8 @@ describe('$mdPanel', function() {
25352537
return $q.resolve();
25362538
});
25372539

2538-
callInterceptors('CLOSE').catch(obj.callback);
2539-
$rootScope.$apply();
2540+
panelRef._callInterceptors(interceptorTypes.CLOSE).catch(obj.callback);
2541+
flushPanel();
25402542

25412543
expect(obj.callback).toHaveBeenCalled();
25422544
});
@@ -2546,8 +2548,8 @@ describe('$mdPanel', function() {
25462548

25472549
spyOn(obj, 'callback');
25482550

2549-
callInterceptors('CLOSE').then(obj.callback);
2550-
$rootScope.$apply();
2551+
panelRef._callInterceptors(interceptorTypes.CLOSE).then(obj.callback);
2552+
flushPanel();
25512553

25522554
expect(obj.callback).toHaveBeenCalled();
25532555
});
@@ -2558,8 +2560,8 @@ describe('$mdPanel', function() {
25582560
spyOn(obj, 'callback');
25592561

25602562
panelRef.registerInterceptor(interceptorTypes.CLOSE, obj.callback);
2561-
2562-
callInterceptors('CLOSE');
2563+
panelRef._callInterceptors(interceptorTypes.CLOSE)
2564+
flushPanel();
25632565

25642566
expect(obj.callback).toHaveBeenCalledTimes(1);
25652567

@@ -2582,16 +2584,17 @@ describe('$mdPanel', function() {
25822584
panelRef.registerInterceptor(interceptorTypes.CLOSE, obj.callback);
25832585
panelRef.registerInterceptor('onOpen', obj.otherCallback);
25842586

2585-
callInterceptors('CLOSE');
2586-
callInterceptors('onOpen');
2587+
panelRef._callInterceptors(interceptorTypes.CLOSE);
2588+
panelRef._callInterceptors('onOpen');
2589+
flushPanel();
25872590

25882591
expect(obj.callback).toHaveBeenCalledTimes(1);
25892592
expect(obj.otherCallback).toHaveBeenCalledTimes(1);
25902593

25912594
panelRef.removeAllInterceptors();
25922595

2593-
callInterceptors('CLOSE');
2594-
callInterceptors('onOpen');
2596+
panelRef._callInterceptors(interceptorTypes.CLOSE);
2597+
panelRef._callInterceptors('onOpen');
25952598

25962599
expect(obj.callback).toHaveBeenCalledTimes(1);
25972600
expect(obj.otherCallback).toHaveBeenCalledTimes(1);
@@ -2609,16 +2612,18 @@ describe('$mdPanel', function() {
26092612
panelRef.registerInterceptor(interceptorTypes.CLOSE, obj.callback);
26102613
panelRef.registerInterceptor('onOpen', obj.otherCallback);
26112614

2612-
callInterceptors('CLOSE');
2613-
callInterceptors('onOpen');
2615+
panelRef._callInterceptors(interceptorTypes.CLOSE);
2616+
panelRef._callInterceptors('onOpen');
2617+
flushPanel();
26142618

26152619
expect(obj.callback).toHaveBeenCalledTimes(1);
26162620
expect(obj.otherCallback).toHaveBeenCalledTimes(1);
26172621

26182622
panelRef.removeAllInterceptors(interceptorTypes.CLOSE);
26192623

2620-
callInterceptors('CLOSE');
2621-
callInterceptors('onOpen');
2624+
panelRef._callInterceptors(interceptorTypes.CLOSE);
2625+
panelRef._callInterceptors('onOpen');
2626+
flushPanel();
26222627

26232628
expect(obj.callback).toHaveBeenCalledTimes(1);
26242629
expect(obj.otherCallback).toHaveBeenCalledTimes(2);
@@ -2746,17 +2751,6 @@ describe('$mdPanel', function() {
27462751
$material.flushOutstandingAnimations();
27472752
}
27482753

2749-
function callInterceptors(type) {
2750-
if (panelRef) {
2751-
var promise = panelRef._callInterceptors(
2752-
$mdPanel.interceptorTypes[type] || type
2753-
);
2754-
2755-
flushPanel();
2756-
return promise;
2757-
}
2758-
}
2759-
27602754
function getNumberOfGroups() {
27612755
return Object.keys($mdPanel._groups).length;
27622756
}

src/core/services/interimElement/interimElement.js

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ function InterimElementProvider() {
244244
}
245245

246246
/* @ngInject */
247-
function InterimElementFactory($document, $q, $$q, $rootScope, $timeout, $rootElement, $animate,
248-
$mdUtil, $mdCompiler, $mdTheming, $injector ) {
247+
function InterimElementFactory($document, $q, $rootScope, $timeout, $rootElement, $animate,
248+
$mdUtil, $mdCompiler, $mdTheming, $injector, $exceptionHandler) {
249249
return function createInterimElementService() {
250250
var SHOW_CANCELLED = false;
251251

@@ -320,9 +320,18 @@ function InterimElementProvider() {
320320

321321
showPromises.push(showAction);
322322

323+
// In Angular 1.6+, exceptions inside promises will cause a rejection. We need to handle
324+
// the rejection and only log it if it's an error.
325+
interimElement.deferred.promise.catch(function(fault) {
326+
if (fault instanceof Error) {
327+
$exceptionHandler(fault);
328+
}
329+
330+
return fault;
331+
});
332+
323333
// Return a promise that will be resolved when the interim
324334
// element is hidden or cancelled...
325-
326335
return interimElement.deferred.promise;
327336
}
328337

@@ -488,8 +497,7 @@ function InterimElementProvider() {
488497

489498
showAction = showElement(element, options, compiledData.controller)
490499
.then(resolve, rejectAll);
491-
492-
}, rejectAll);
500+
}).catch(rejectAll);
493501

494502
function rejectAll(fault) {
495503
// Force the '$md<xxx>.show()' promise to reject
@@ -523,15 +531,11 @@ function InterimElementProvider() {
523531
});
524532

525533
} else {
526-
527-
$q.when(showAction)
528-
.finally(function() {
529-
hideElement(options.element, options).then(function() {
530-
531-
(isCancelled && rejectAll(response)) || resolveAll(response);
532-
533-
}, rejectAll);
534-
});
534+
$q.when(showAction).finally(function() {
535+
hideElement(options.element, options).then(function() {
536+
isCancelled ? rejectAll(response) : resolveAll(response);
537+
}, rejectAll);
538+
});
535539

536540
return self.deferred.promise;
537541
}
@@ -682,7 +686,12 @@ function InterimElementProvider() {
682686
// Trigger onComplete callback when the `show()` finishes
683687
var notifyComplete = options.onComplete || angular.noop;
684688

685-
notifyShowing(options.scope, element, options, controller);
689+
// Necessary for consistency between Angular 1.5 and 1.6.
690+
try {
691+
notifyShowing(options.scope, element, options, controller);
692+
} catch (e) {
693+
return $q.reject(e);
694+
}
686695

687696
return $q(function (resolve, reject) {
688697
try {
@@ -693,10 +702,9 @@ function InterimElementProvider() {
693702
startAutoHide();
694703

695704
resolve(element);
705+
}, reject);
696706

697-
}, reject );
698-
699-
} catch(e) {
707+
} catch (e) {
700708
reject(e.message);
701709
}
702710
});
@@ -705,35 +713,29 @@ function InterimElementProvider() {
705713
function hideElement(element, options) {
706714
var announceRemoving = options.onRemoving || angular.noop;
707715

708-
return $$q(function (resolve, reject) {
716+
return $q(function (resolve, reject) {
709717
try {
710718
// Start transitionIn
711-
var action = $$q.when( options.onRemove(options.scope, element, options) || true );
719+
var action = $q.when( options.onRemove(options.scope, element, options) || true );
712720

713721
// Trigger callback *before* the remove operation starts
714722
announceRemoving(element, action);
715723

716-
if ( options.$destroy ) {
717-
724+
if (options.$destroy) {
718725
// For $destroy, onRemove should be synchronous
719726
resolve(element);
720-
721727
} else {
722-
723728
// Wait until transition-out is done
724729
action.then(function () {
725-
726730
if (!options.preserveScope && options.scope ) {
727731
options.scope.$destroy();
728732
}
729733

730734
resolve(element);
731-
732-
}, reject );
735+
}, reject);
733736
}
734-
735-
} catch(e) {
736-
reject(e);
737+
} catch (e) {
738+
reject(e.message);
737739
}
738740
});
739741
}

0 commit comments

Comments
 (0)