mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-05 13:44:42 +00:00
fix($compile): ignore ws when checking if template has single root
Also add the same error checking for sync templates. Closes #910
This commit is contained in:
parent
1564b82b49
commit
9c0418cf1a
2 changed files with 91 additions and 18 deletions
|
|
@ -145,7 +145,7 @@ function $CompileProvider($provide) {
|
||||||
Suffix = 'Directive',
|
Suffix = 'Directive',
|
||||||
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
|
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
|
||||||
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
|
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
|
||||||
HAS_ROOT_ELEMENT = /^\<[\s\S]*\>$/;
|
MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: ';
|
||||||
|
|
||||||
|
|
||||||
this.directive = function registerDirective(name, directiveFactory) {
|
this.directive = function registerDirective(name, directiveFactory) {
|
||||||
|
|
@ -587,8 +587,14 @@ function $CompileProvider($provide) {
|
||||||
assertNoDuplicate('template', templateDirective, directive, $compileNode);
|
assertNoDuplicate('template', templateDirective, directive, $compileNode);
|
||||||
templateDirective = directive;
|
templateDirective = directive;
|
||||||
|
|
||||||
compileNode = jqLite(directiveValue)[0];
|
$template = jqLite('<div>' + trim(directiveValue) + '</div>').contents();
|
||||||
|
compileNode = $template[0];
|
||||||
|
|
||||||
if (directive.replace) {
|
if (directive.replace) {
|
||||||
|
if ($template.length != 1 || compileNode.nodeType !== 1) {
|
||||||
|
throw new Error(MULTI_ROOT_TEMPLATE_ERROR + directiveValue);
|
||||||
|
}
|
||||||
|
|
||||||
replaceWith($rootElement, $compileNode, compileNode);
|
replaceWith($rootElement, $compileNode, compileNode);
|
||||||
|
|
||||||
var newTemplateAttrs = {$attr: {}};
|
var newTemplateAttrs = {$attr: {}};
|
||||||
|
|
@ -840,15 +846,17 @@ function $CompileProvider($provide) {
|
||||||
|
|
||||||
$http.get(origAsyncDirective.templateUrl, {cache: $templateCache}).
|
$http.get(origAsyncDirective.templateUrl, {cache: $templateCache}).
|
||||||
success(function(content) {
|
success(function(content) {
|
||||||
if (replace && !content.match(HAS_ROOT_ELEMENT)) {
|
var compileNode, tempTemplateAttrs, $template;
|
||||||
throw Error('Template must have exactly one root element: ' + content);
|
|
||||||
}
|
|
||||||
|
|
||||||
var compileNode, tempTemplateAttrs;
|
|
||||||
|
|
||||||
if (replace) {
|
if (replace) {
|
||||||
|
$template = jqLite('<div>' + trim(content) + '</div>').contents();
|
||||||
|
compileNode = $template[0];
|
||||||
|
|
||||||
|
if ($template.length != 1 || compileNode.nodeType !== 1) {
|
||||||
|
throw new Error(MULTI_ROOT_TEMPLATE_ERROR + content);
|
||||||
|
}
|
||||||
|
|
||||||
tempTemplateAttrs = {$attr: {}};
|
tempTemplateAttrs = {$attr: {}};
|
||||||
compileNode = jqLite(content)[0];
|
|
||||||
replaceWith($rootElement, $compileNode, compileNode);
|
replaceWith($rootElement, $compileNode, compileNode);
|
||||||
collectDirectives(compileNode, directives, tempTemplateAttrs);
|
collectDirectives(compileNode, directives, tempTemplateAttrs);
|
||||||
mergeTemplateAttributes(tAttrs, tempTemplateAttrs);
|
mergeTemplateAttributes(tAttrs, tempTemplateAttrs);
|
||||||
|
|
|
||||||
|
|
@ -487,10 +487,48 @@ describe('$compile', function() {
|
||||||
expect(child).toHaveClass('three');
|
expect(child).toHaveClass('three');
|
||||||
expect(child).toHaveClass('log'); // merged from replace directive template
|
expect(child).toHaveClass('log'); // merged from replace directive template
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it("should fail if replacing and template doesn't have a single root element", function() {
|
||||||
|
module(function($compileProvider) {
|
||||||
|
$compileProvider.directive('noRootElem', function() {
|
||||||
|
return {
|
||||||
|
replace: true,
|
||||||
|
template: 'dada'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$compileProvider.directive('multiRootElem', function() {
|
||||||
|
return {
|
||||||
|
replace: true,
|
||||||
|
template: '<div></div><div></div>'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$compileProvider.directive('singleRootWithWhiteSpace', function() {
|
||||||
|
return {
|
||||||
|
replace: true,
|
||||||
|
template: ' <div></div> \n'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
inject(function($compile) {
|
||||||
|
expect(function() {
|
||||||
|
$compile('<p no-root-elem></p>');
|
||||||
|
}).toThrow('Template must have exactly one root element. was: dada');
|
||||||
|
|
||||||
|
expect(function() {
|
||||||
|
$compile('<p multi-root-elem></p>');
|
||||||
|
}).toThrow('Template must have exactly one root element. was: <div></div><div></div>');
|
||||||
|
|
||||||
|
// ws is ok
|
||||||
|
expect(function() {
|
||||||
|
$compile('<p single-root-with-white-space></p>');
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('async templates', function() {
|
describe('templateUrl', function() {
|
||||||
|
|
||||||
beforeEach(module(
|
beforeEach(module(
|
||||||
function($compileProvider) {
|
function($compileProvider) {
|
||||||
|
|
@ -916,15 +954,6 @@ describe('$compile', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should check that template has root element', inject(function($compile, $httpBackend) {
|
|
||||||
$httpBackend.expect('GET', 'hello.html').respond('before <b>mid</b> after');
|
|
||||||
$compile('<div i-hello></div>');
|
|
||||||
expect(function(){
|
|
||||||
$httpBackend.flush();
|
|
||||||
}).toThrow('Template must have exactly one root element: before <b>mid</b> after');
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should allow multiple elements in template', inject(function($compile, $httpBackend) {
|
it('should allow multiple elements in template', inject(function($compile, $httpBackend) {
|
||||||
$httpBackend.expect('GET', 'hello.html').respond('before <b>mid</b> after');
|
$httpBackend.expect('GET', 'hello.html').respond('before <b>mid</b> after');
|
||||||
element = jqLite('<div hello></div>');
|
element = jqLite('<div hello></div>');
|
||||||
|
|
@ -958,6 +987,42 @@ describe('$compile', function() {
|
||||||
expect(element.text()).toEqual('i=1;i=2;');
|
expect(element.text()).toEqual('i=1;i=2;');
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
it("should fail if replacing and template doesn't have a single root element", function() {
|
||||||
|
module(function($exceptionHandlerProvider, $compileProvider) {
|
||||||
|
$exceptionHandlerProvider.mode('log');
|
||||||
|
|
||||||
|
$compileProvider.directive('template', function() {
|
||||||
|
return {
|
||||||
|
replace: true,
|
||||||
|
templateUrl: 'template.html'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
inject(function($compile, $templateCache, $rootScope, $exceptionHandler) {
|
||||||
|
// no root element
|
||||||
|
$templateCache.put('template.html', 'dada');
|
||||||
|
$compile('<p template></p>');
|
||||||
|
$rootScope.$digest();
|
||||||
|
expect($exceptionHandler.errors.pop().message).
|
||||||
|
toBe('Template must have exactly one root element. was: dada');
|
||||||
|
|
||||||
|
// multi root
|
||||||
|
$templateCache.put('template.html', '<div></div><div></div>');
|
||||||
|
$compile('<p template></p>');
|
||||||
|
$rootScope.$digest();
|
||||||
|
expect($exceptionHandler.errors.pop().message).
|
||||||
|
toBe('Template must have exactly one root element. was: <div></div><div></div>');
|
||||||
|
|
||||||
|
// ws is ok
|
||||||
|
$templateCache.put('template.html', ' <div></div> \n');
|
||||||
|
$compile('<p template></p>');
|
||||||
|
$rootScope.$apply();
|
||||||
|
expect($exceptionHandler.errors).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue