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

Commit 22c34ba

Browse files
fix(dialog): improve support for template and templateUrl options
Using $mdDialog to show html content without a mdDialog parent node will throw an error: ```js $mdDialog.show({ targetEvent: ev, controller : DialogCtrl, parent : angular.element(document.body), template : '<div ng-click="answer(\'string\')">click here</div>' } ``` If a mdDialog template does not contain a wrapper `md-dialog` node, then auto-wrap. If a `$mdUtil.extractElementByName` does not find the target element, warn the user. Fixes #3191. Fixes #4206.
1 parent e26a275 commit 22c34ba

File tree

6 files changed

+91
-81
lines changed

6 files changed

+91
-81
lines changed

src/components/dialog/dialog.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,15 @@ function MdDialogProvider($$interimElementProvider) {
447447
focusOnOpen: true,
448448
disableParentScroll: true,
449449
transformTemplate: function(template) {
450-
return '<div class="md-dialog-container">' + template + '</div>';
450+
return '<div class="md-dialog-container">' + validatedTemplate(template) + '</div>';
451+
452+
/**
453+
* The specified template should contain a <md-dialog> wrapper element....
454+
*/
455+
function validatedTemplate(template) {
456+
template || ""
457+
return /<\/md-dialog>/g.test(template) ? template : "<md-dialog>" + template + "</md-dialog>";
458+
}
451459
}
452460
};
453461

src/components/dialog/dialog.spec.js

+40-7
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,39 @@ describe('$mdDialog', function() {
348348
expect(closing).toBe(true);
349349
}));
350350

351+
352+
it('should not wrap content with existing md-dialog', inject(function($mdDialog, $rootScope) {
353+
354+
var template = '<md-dialog><div id="rawContent">Hello</div></md-dialog>';
355+
var parent = angular.element('<div>');
356+
357+
$mdDialog.show({
358+
template: template,
359+
parent: parent
360+
});
361+
362+
$rootScope.$apply();
363+
364+
var container = parent[0].querySelectorAll('md-dialog');
365+
expect(container.length).toBe(1);
366+
}));
367+
368+
it('should wrap raw content with md-dialog', inject(function($mdDialog, $rootScope) {
369+
370+
var template = '<div id="rawContent">Hello</div>';
371+
var parent = angular.element('<div>');
372+
373+
$mdDialog.show({
374+
template: template,
375+
parent: parent
376+
});
377+
378+
$rootScope.$apply();
379+
380+
var container = parent[0].querySelectorAll('md-dialog');
381+
expect(container.length).toBe(1);
382+
}));
383+
351384
it('should append dialog with container', inject(function($mdDialog, $rootScope) {
352385

353386
var template = '<md-dialog>Hello</md-dialog>';
@@ -367,7 +400,7 @@ describe('$mdDialog', function() {
367400
it('should escapeToClose == true', inject(function($mdDialog, $rootScope, $rootElement, $timeout, $animate, $mdConstant) {
368401
var parent = angular.element('<div>');
369402
$mdDialog.show({
370-
template: '<md-dialog>',
403+
template: '<md-dialog></md-dialog>',
371404
parent: parent,
372405
escapeToClose: true
373406
});
@@ -391,7 +424,7 @@ describe('$mdDialog', function() {
391424
it('should escapeToClose == false', inject(function($mdDialog, $rootScope, $rootElement, $timeout, $animate, $mdConstant) {
392425
var parent = angular.element('<div>');
393426
$mdDialog.show({
394-
template: '<md-dialog>',
427+
template: '',
395428
parent: parent,
396429
escapeToClose: false
397430
});
@@ -411,7 +444,7 @@ describe('$mdDialog', function() {
411444

412445
var parent = angular.element('<div>');
413446
$mdDialog.show({
414-
template: '<md-dialog>',
447+
template: '',
415448
parent: parent,
416449
clickOutsideToClose: true
417450
});
@@ -434,7 +467,7 @@ describe('$mdDialog', function() {
434467

435468
var parent = angular.element('<div>');
436469
$mdDialog.show({
437-
template: '<md-dialog>',
470+
template: '',
438471
parent: parent,
439472
clickOutsideToClose: false
440473
});
@@ -458,7 +491,7 @@ describe('$mdDialog', function() {
458491
spyOn($mdUtil, 'disableScrollAround');
459492
var parent = angular.element('<div>');
460493
$mdDialog.show({
461-
template: '<md-dialog>',
494+
template: '',
462495
parent: parent,
463496
disableParentScroll: true
464497
});
@@ -469,7 +502,7 @@ describe('$mdDialog', function() {
469502
it('should hasBackdrop == true', inject(function($mdDialog, $animate, $rootScope) {
470503
var parent = angular.element('<div>');
471504
$mdDialog.show({
472-
template: '<md-dialog>',
505+
template: '',
473506
parent: parent,
474507
hasBackdrop: true
475508
});
@@ -482,7 +515,7 @@ describe('$mdDialog', function() {
482515
it('should hasBackdrop == false', inject(function($mdDialog, $rootScope) {
483516
var parent = angular.element('<div>');
484517
$mdDialog.show({
485-
template: '<md-dialog>',
518+
template: '',
486519
parent: parent,
487520
hasBackdrop: false
488521
});

src/components/sidenav/sidenav.scss

+20-71
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,53 @@
11
$sidenav-default-width: 304px !default;
22
$sidenav-min-space: 56px !default;
33

4+
.md-sidenav-left {
5+
transform: translate3d(-100%, 0, 0);
6+
}
7+
48
md-sidenav {
59
box-sizing: border-box;
6-
position: absolute;
10+
position: relative;
711
flex-direction: column;
812
z-index: $z-index-sidenav;
913

14+
top:0;
15+
bottom: 0;
16+
left:0;
1017
width: $sidenav-default-width;
1118
min-width: $sidenav-default-width;
1219
max-width: $sidenav-default-width;
13-
bottom: 0;
20+
21+
display:none;
22+
transition: 0s ease-out transform;
23+
1424
background-color: white;
1525
overflow: auto;
1626

1727
ul {
1828
list-style: none;
1929
}
2030

21-
&.md-closed {
22-
display: none;
23-
}
24-
&.md-closed-add,
25-
&.md-closed-remove {
26-
display: flex;
27-
transition: 0.2s ease-in all;
28-
}
29-
30-
&.md-closed-add.md-closed-add-active,
31-
&.md-closed-remove.md-closed-remove-active {
32-
transition: $swift-ease-out;
33-
}
3431

3532
&.md-locked-open-add,
3633
&.md-locked-open-remove {
37-
position: static;
38-
display: flex;
39-
transform: translate3d(0, 0, 0);
34+
display: block;
4035
}
4136
&.md-locked-open {
42-
width: $sidenav-default-width;
43-
min-width: $sidenav-default-width;
44-
max-width: $sidenav-default-width;
45-
}
37+
display: block;
38+
transition-duration: 0.2s;
4639

47-
&.md-locked-open,
48-
&.md-locked-open.md-closed,
49-
&.md-locked-open.md-closed.md-sidenav-left,
50-
&.md-locked-open.md-closed.md-sidenav-right,
51-
&.md-locked-open-remove.md-closed {
52-
position: static;
53-
display: flex;
54-
transform: translate3d(0, 0, 0);
55-
}
56-
&.md-locked-open-remove-active {
57-
transition: width $swift-ease-in-duration $swift-ease-in-timing-function,
58-
min-width $swift-ease-in-duration $swift-ease-in-timing-function;
59-
width: 0;
60-
min-width: 0;
61-
}
62-
63-
&.md-closed.md-locked-open-add {
64-
width: 0;
65-
min-width: 0;
66-
transform: translate3d(0%, 0, 0);
67-
}
68-
69-
&.md-closed.md-locked-open-add-active {
70-
transition: width $swift-ease-in-duration $swift-ease-in-timing-function,
71-
min-width $swift-ease-in-duration $swift-ease-in-timing-function;
72-
width: $sidenav-default-width;
73-
min-width: $sidenav-default-width;
74-
transform: translate3d(0%, 0, 0);
40+
&.md-sidenav-left {
41+
transform: translate3d(0, 0, 0);
42+
}
7543
}
7644

7745
@extend .md-sidenav-left;
7846
}
79-
.md-sidenav-backdrop.md-locked-open {
80-
display: none;
81-
}
8247

83-
.md-sidenav-left {
84-
left: 0;
85-
top: 0;
86-
transform: translate3d(0%, 0, 0);
87-
&.md-closed {
88-
transform: translate3d(-100%, 0, 0);
89-
}
90-
}
9148

92-
.md-sidenav-right {
93-
left: 100%;
94-
top: 0;
95-
transform: translate3d(-100%, 0, 0);
96-
&.md-closed {
97-
transform: translate3d(0%, 0, 0);
98-
}
49+
.md-sidenav-backdrop.md-locked-open {
50+
display: none;
9951
}
10052

10153
@media (max-width: $sidenav-default-width + $sidenav-min-space) {
@@ -108,7 +60,4 @@ md-sidenav {
10860
.md-sidenav-left {
10961
border-right: 1px solid #fff;
11062
}
111-
.md-sidenav-right {
112-
border-left: 1px solid #fff;
113-
}
11463
}

src/core/services/aria/aria.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ function AriaService($$rAF, $log, $window) {
2020
* @param {optional} defaultValue What to set the attr to if no value is found
2121
*/
2222
function expect(element, attrName, defaultValue) {
23-
var node = element[0] || element;
23+
24+
var node = angular.element(element)[0] || element;
2425

2526
// if node exists and neither it nor its children have the attribute
2627
if (node &&

src/core/services/aria/aria.spec.js

+17
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ describe('$mdAria service', function() {
22
beforeEach(module('material.core'));
33

44
describe('expecting attributes', function(){
5+
it('should warn if an invalid element is specified', inject(function($compile, $rootScope, $log, $mdAria) {
6+
spyOn($log, 'warn');
7+
var target = $compile('<div></div>')($rootScope);
8+
9+
$mdAria.expect(null,'aria-label');
10+
expect($log.warn).not.toHaveBeenCalled();
11+
}));
12+
513
it('should warn if element is missing attribute', inject(function($compile, $rootScope, $log, $mdAria) {
614
spyOn($log, 'warn');
715
var button = $compile('<button><md-icon></md-icon></button>')($rootScope);
@@ -20,6 +28,15 @@ describe('$mdAria service', function() {
2028
expect($log.warn).toHaveBeenCalled();
2129
}));
2230

31+
it('should warn if element is emtpry attribute', inject(function($compile, $rootScope, $log, $mdAria) {
32+
spyOn($log, 'warn');
33+
var button = $compile('<button aria-label=""><md-icon></md-icon></button>')($rootScope);
34+
35+
$mdAria.expect(button, 'aria-label');
36+
37+
expect($log.warn).toHaveBeenCalled();
38+
}));
39+
2340
it('should not warn if child element has attribute', inject(function($compile, $rootScope, $log, $mdAria) {
2441
spyOn($log, 'warn');
2542
var button = $compile('<button><md-icon aria-label="text"></md-icon></button>')($rootScope);

src/core/util/util.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ angular
1010
.module('material.core')
1111
.factory('$mdUtil', UtilFactory);
1212

13-
function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $interpolate) {
13+
function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $interpolate, $log) {
1414
// Setup some core variables for the processTemplate method
1515
var startSymbol = $interpolate.startSymbol(),
1616
endSymbol = $interpolate.endSymbol(),
@@ -462,6 +462,8 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
462462
return angular.element(element[i]);
463463
}
464464
}
465+
466+
$log.warn( $mdUtil.supplant("Unable to find node '{0}' in element.",[nodeName]) );
465467
return element;
466468
},
467469

0 commit comments

Comments
 (0)