From 852cb3f3be48b87745f25963027ba9857abc3f72 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Sat, 21 Dec 2013 15:20:16 -0500 Subject: [PATCH] fix($compile): support DOM nodes as template values Special content types, such as SVG content or table content, can not be used in many cases due to generating a document fragment which does not support the particular template content type being used. This patch enables special content such as SVG or table content to be used by making the template a DOM node or collection of DOM nodes, rather than strings. The test demonstrates how this can be used to replace the directive node with SVG elements, or similar. --- src/ng/compile.js | 22 +++++++++++++++++----- test/ng/compileSpec.js | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index 9285b253d0b3..e3fe900701cc 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -1234,14 +1234,22 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { directiveValue = (isFunction(directive.template)) ? directive.template($compileNode, templateAttrs) : directive.template; + var elementTemplate = isElement(directiveValue); - directiveValue = denormalizeTemplate(directiveValue); + if (!elementTemplate) { + directiveValue = denormalizeTemplate(directiveValue); + } if (directive.replace) { replaceDirective = directive; - $template = jqLite('
' + - trim(directiveValue) + - '
').contents(); + if (elementTemplate) { + $template = jqLite(directiveValue).clone(); + } else { + $template = jqLite('
' + + trim(directiveValue) + + '
').contents(); + } + compileNode = $template[0]; if ($template.length != 1 || compileNode.nodeType !== 1) { @@ -1270,7 +1278,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { ii = directives.length; } else { - $compileNode.html(directiveValue); + if (elementTemplate) { + $compileNode.html('').append(jqLite(directiveValue).clone()); + } else { + $compileNode.html(directiveValue); + } } } diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 39e236959635..a69c6f5f3488 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -512,6 +512,14 @@ describe('$compile', function() { expect(element).toBe(attr.$$element); } })); + + directive('svgCircle', valueFn({ + replace: true, + template: jqLite('').children() + })); + directive('domNodeTemplate', valueFn({ + template: jqLite('

Hello!

world!

') + })); })); @@ -675,6 +683,17 @@ describe('$compile', function() { }).not.toThrow(); }); }); + + + it('should accept DOM nodes as a template', inject(function($compile, $rootScope) { + if (!(msie < 9)) { + element = $compile('')($rootScope); + expect(element.find('g').length).toBe(0); + expect(element.find('circle').length).toBe(1); + } + element = $compile('
')($rootScope); + expect(element.find('p').length).toBe(2); + })); }); @@ -693,6 +712,17 @@ describe('$compile', function() { expect($attrs.id).toBe('templateContent'); } })); + directive('svgCircle', valueFn({ + replace: true, + template: function() { + return jqLite('').children(); + } + })); + directive('domNodeTemplate', valueFn({ + template: function() { + return jqLite('

Hello!

world!

'); + } + })); })); @@ -701,6 +731,17 @@ describe('$compile', function() { element = $compile('
original content
')($rootScope); expect(element.text()).toEqual('template content'); })); + + + it('should accept DOM nodes as a template', inject(function($compile, $rootScope) { + if (!(msie < 9)) { + element = $compile('')($rootScope); + expect(element.find('g').length).toBe(0); + expect(element.find('circle').length).toBe(1); + } + element = $compile('
')($rootScope); + expect(element.find('p').length).toBe(2); + })); });