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

Commit

Permalink
fix(dialog): Provide option to not autowrap templates.
Browse files Browse the repository at this point in the history
For convenience, we automatically wrap templates that do not
contain a `<md-dialog>` tag within them. However, some users
would like the ability to create their own dialog directives
(like `<my-fancy-dialog>`) that internally use the `<md-dialog>`
tag within their template. This causes two `<md-dialog>` tags
to be created.

Provide a new `autoWrap` option which can be set to false to
disable autowrapping when providing a custom directive.

Fixes #4898. Closes #5237.
  • Loading branch information
topherfangio authored and ThomasBurleson committed Oct 18, 2015
1 parent 7251684 commit 87d6230
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 27 deletions.
15 changes: 11 additions & 4 deletions src/components/dialog/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ function MdDialogDirective($$rAF, $mdTheming, $mdDialog) {
* - `templateUrl` - `{string=}`: The url of a template that will be used as the content
* of the dialog.
* - `template` - `{string=}`: Same as templateUrl, except this is an actual template string.
* - `autoWrap` - `{boolean=}`: Whether or not to automatically wrap the template with a
* `<md-dialog>` tag if one is not provided. Defaults to true. Can be disabled if you provide a
* custom dialog directive.
* - `targetEvent` - `{DOMClickEvent=}`: A click's event object. When passed in as an option,
* the location of the click will be used as the starting point for the opening animation
* of the the dialog.
Expand Down Expand Up @@ -374,7 +377,7 @@ function MdDialogDirective($$rAF, $mdTheming, $mdDialog) {
* starting.
* - `onComplete` `{function=}`: Callback function used to announce when the show() action is
* finished.
* - `onRemoving` `{function=} Callback function used to announce the close/hide() action is
* - `onRemoving` `{function=}`: Callback function used to announce the close/hide() action is
* starting. This allows developers to run custom animations in parallel the close animations.
*
* @returns {promise} A promise that can be resolved with `$mdDialog.hide()` or
Expand Down Expand Up @@ -469,15 +472,19 @@ function MdDialogProvider($$interimElementProvider) {
openFrom: null,
focusOnOpen: true,
disableParentScroll: true,
transformTemplate: function(template) {
autoWrap: true,
transformTemplate: function(template, options) {
return '<div class="md-dialog-container">' + validatedTemplate(template) + '</div>';

/**
* The specified template should contain a <md-dialog> wrapper element....
*/
function validatedTemplate(template) {
template || ""
return /<\/md-dialog>/g.test(template) ? template : "<md-dialog>" + template + "</md-dialog>";
if (options.autoWrap && !/<\/md-dialog>/g.test(template)) {
return '<md-dialog>' + (template || '') + '</md-dialog>';
} else {
return template || '';
}
}
}
};
Expand Down
68 changes: 46 additions & 22 deletions src/components/dialog/dialog.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -545,37 +545,61 @@ describe('$mdDialog', function() {
nodes.remove();
}));

it('should not wrap content with existing md-dialog', inject(function($mdDialog, $rootScope) {
describe('when autoWrap parameter is true (default)', function() {

var template = '<md-dialog><div id="rawContent">Hello</div></md-dialog>';
var parent = angular.element('<div>');
it('should not wrap content with existing md-dialog', inject(function($mdDialog, $rootScope) {

$mdDialog.show({
template: template,
parent: parent
});
var template = '<md-dialog><div id="rawContent">Hello</div></md-dialog>';
var parent = angular.element('<div>');

$rootScope.$apply();
$mdDialog.show({
template: template,
parent: parent
});

var container = parent[0].querySelectorAll('md-dialog');
expect(container.length).toBe(1);
}));
$rootScope.$apply();

it('should wrap raw content with md-dialog', inject(function($mdDialog, $rootScope) {
var container = parent[0].querySelectorAll('md-dialog');
expect(container.length).toBe(1);
}));

var template = '<div id="rawContent">Hello</div>';
var parent = angular.element('<div>');
it('should wrap raw content with md-dialog', inject(function($mdDialog, $rootScope) {

$mdDialog.show({
template: template,
parent: parent
});
var template = '<div id="rawContent">Hello</div>';
var parent = angular.element('<div>');

$rootScope.$apply();
$mdDialog.show({
template: template,
parent: parent
});

var container = parent[0].querySelectorAll('md-dialog');
expect(container.length).toBe(1);
}));
$rootScope.$apply();

var container = parent[0].querySelectorAll('md-dialog');
expect(container.length).toBe(1);
}));
});


describe('when autoWrap parameter is false', function() {

it('should not wrap raw content with md-dialog', inject(function($mdDialog, $rootScope) {

var template = '<div id="rawContent">Hello</div>';
var parent = angular.element('<div>');

$mdDialog.show({
template: template,
parent: parent,
autoWrap: false
});

$rootScope.$apply();

var container = parent[0].querySelectorAll('md-dialog');
expect(container.length).toBe(0);
}));
});

it('should append dialog within a md-dialog-container', inject(function($mdDialog, $rootScope) {

Expand Down
2 changes: 1 addition & 1 deletion src/core/services/compiler/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function mdCompilerService($q, $http, $injector, $compile, $controller, $templat
return $q.all(resolve).then(function(locals) {

var compiledData;
var template = transformTemplate(locals.$template);
var template = transformTemplate(locals.$template, options);
var element = options.element || angular.element('<div>').html(template.trim()).contents();
var linkFn = $compile(element);

Expand Down
9 changes: 9 additions & 0 deletions src/core/services/compiler/compiler.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ describe('$mdCompiler service', function() {
expect(data.element.html()).toBe('hello world');
});

it('transformTemplate receives the options', function() {
var data = compile({
template: 'world',
someArg: 'foo',
transformTemplate: function(tpl, options) { return 'hello ' + tpl + ': ' + options.someArg; }
});
expect(data.element.html()).toBe('hello world: foo');
});

describe('with resolve and locals options', function() {
var options;

Expand Down

0 comments on commit 87d6230

Please sign in to comment.