From 75c4cbf81fcd6d49656d3cb044e59e5fd24e0479 Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Fri, 22 Aug 2014 11:43:58 -0700 Subject: [PATCH] refactor($compile): rename `directive.type` to `directive.templateNamespace` Also corrects the tests for MathML that use `directive.templateNamespace`. BREAKING CHANGE (within 1.3.0-beta): `directive.type` was renamed to `directive.templateNamespace` The property name `type` was too general. --- src/ng/compile.js | 23 +++-- test/ng/compileSpec.js | 187 ++++++++++++++++++++++------------------- 2 files changed, 113 insertions(+), 97 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index a21ade16..3e84c2b0 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -219,18 +219,17 @@ * * `M` - Comment: `` * * - * #### `type` - * String representing the document type used by the markup. This is useful for templates where the root - * node is non-HTML content (such as SVG or MathML). The default value is "html". + * #### `templateNamespace` + * String representing the document type used by the markup in the template. + * AngularJS needs this information as those elements need to be created and cloned + * in a special way when they are defined outside their usual containers like `` and ``. * - * * `html` - All root template nodes are HTML, and don't need to be wrapped. Root nodes may also be + * * `html` - All root nodes in the template are HTML. Root nodes may also be * top-level elements such as `` or ``. - * * `svg` - The template contains only SVG content, and must be wrapped in an `` node prior to - * processing. - * * `math` - The template contains only MathML content, and must be wrapped in an `` node prior to - * processing. + * * `svg` - The root nodes in the template are SVG elements (excluding ``). + * * `math` - The root nodes in the template are MathML elements (excluding ``). * - * If no `type` is specified, then the type is considered to be html. + * If no `templateNamespace` is specified, then the namespace is considered to be `html`. * * #### `template` * HTML markup that may: @@ -1339,7 +1338,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (jqLiteIsTextNode(directiveValue)) { $template = []; } else { - $template = jqLite(wrapTemplate(directive.type, trim(directiveValue))); + $template = jqLite(wrapTemplate(directive.templateNamespace, trim(directiveValue))); } compileNode = $template[0]; @@ -1786,7 +1785,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { templateUrl = (isFunction(origAsyncDirective.templateUrl)) ? origAsyncDirective.templateUrl($compileNode, tAttrs) : origAsyncDirective.templateUrl, - type = origAsyncDirective.type; + templateNamespace = origAsyncDirective.templateNamespace; $compileNode.empty(); @@ -1800,7 +1799,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (jqLiteIsTextNode(content)) { $template = []; } else { - $template = jqLite(wrapTemplate(type, trim(content))); + $template = jqLite(wrapTemplate(templateNamespace, trim(content))); } compileNode = $template[0]; diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index f4fdf186..7701dd32 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -7,8 +7,25 @@ function calcCacheSize() { return size; } - describe('$compile', function() { + function isUnknownElement(el) { + return !!el.toString().match(/Unknown/); + } + + function isSVGElement(el) { + return !!el.toString().match(/SVG/); + } + + function isHTMLElement(el) { + return !!el.toString().match(/HTML/); + } + + function supportsMathML() { + var d = document.createElement('div'); + d.innerHTML = ''; + return !isUnknownElement(d.firstChild); + } + var element, directive, $compile, $rootScope; beforeEach(module(provideLog, function($provide, $compileProvider){ @@ -838,58 +855,58 @@ describe('$compile', function() { expect(nodeName_(element)).toMatch(/optgroup/i); })); - if (window.SVGAElement) { - it('should support SVG templates using directive.type=svg', function() { - module(function() { - directive('svgAnchor', valueFn({ - replace: true, - template: '{{text}}', - type: 'SVG', - scope: { - linkurl: '@svgAnchor', - text: '@?' - } - })); - }); - inject(function($compile, $rootScope) { - element = $compile('')($rootScope); - var child = element.children().eq(0); - $rootScope.$digest(); - expect(nodeName_(child)).toMatch(/a/i); - expect(child[0].constructor).toBe(window.SVGAElement); - expect(child[0].href.baseVal).toBe("/foo/bar"); - }); - }); - } - - // MathML is only natively supported in Firefox at the time of this test's writing, - // and even there, the browser does not export MathML element constructors globally. - // So the test is slightly limited in what it does. But as browsers begin to - // implement MathML natively, this can be tightened up to be more meaningful. - it('should support MathML templates using directive.type=math', function() { + it('should support SVG templates using directive.templateNamespace=svg', function() { module(function() { - directive('pow', valueFn({ + directive('svgAnchor', valueFn({ replace: true, - transclude: true, - template: '{{pow}}', - type: 'MATH', + template: '{{text}}', + templateNamespace: 'SVG', scope: { - pow: '@pow', - }, - link: function(scope, elm, attr, ctrl, transclude) { - transclude(function(node) { - elm.prepend(node[0]); - }); + linkurl: '@svgAnchor', + text: '@?' } })); }); inject(function($compile, $rootScope) { - element = $compile('8')($rootScope); - $rootScope.$digest(); + element = $compile('')($rootScope); var child = element.children().eq(0); - expect(nodeName_(child)).toMatch(/msup/i); + $rootScope.$digest(); + expect(nodeName_(child)).toMatch(/a/i); + expect(isSVGElement(child[0])).toBe(true); + expect(child[0].href.baseVal).toBe("/foo/bar"); }); }); + + if (supportsMathML()) { + // MathML is only natively supported in Firefox at the time of this test's writing, + // and even there, the browser does not export MathML element constructors globally. + it('should support MathML templates using directive.templateNamespace=math', function() { + module(function() { + directive('pow', valueFn({ + replace: true, + transclude: true, + template: '{{pow}}', + templateNamespace: 'MATH', + scope: { + pow: '@pow', + }, + link: function(scope, elm, attr, ctrl, transclude) { + transclude(function(node) { + elm.prepend(node[0]); + }); + } + })); + }); + inject(function($compile, $rootScope) { + element = $compile('8')($rootScope); + $rootScope.$digest(); + var child = element.children().eq(0); + expect(nodeName_(child)).toMatch(/msup/i); + expect(isUnknownElement(child[0])).toBe(false); + expect(isHTMLElement(child[0])).toBe(false); + }); + }); + } }); @@ -1735,60 +1752,60 @@ describe('$compile', function() { expect(nodeName_(element)).toMatch(/optgroup/i); })); - if (window.SVGAElement) { - it('should support SVG templates using directive.type=svg', function() { - module(function() { - directive('svgAnchor', valueFn({ - replace: true, - templateUrl: 'template.html', - type: 'SVG', - scope: { - linkurl: '@svgAnchor', - text: '@?' - } - })); - }); - inject(function($compile, $rootScope, $templateCache) { - $templateCache.put('template.html', '{{text}}'); - element = $compile('')($rootScope); - $rootScope.$digest(); - var child = element.children().eq(0); - expect(nodeName_(child)).toMatch(/a/i); - expect(child[0].constructor).toBe(window.SVGAElement); - expect(child[0].href.baseVal).toBe("/foo/bar"); - }); - }); - } - - // MathML is only natively supported in Firefox at the time of this test's writing, - // and even there, the browser does not export MathML element constructors globally. - // So the test is slightly limited in what it does. But as browsers begin to - // implement MathML natively, this can be tightened up to be more meaningful. - it('should support MathML templates using directive.type=math', function() { + it('should support SVG templates using directive.templateNamespace=svg', function() { module(function() { - directive('pow', valueFn({ + directive('svgAnchor', valueFn({ replace: true, - transclude: true, templateUrl: 'template.html', - type: 'MATH', + templateNamespace: 'SVG', scope: { - pow: '@pow', - }, - link: function(scope, elm, attr, ctrl, transclude) { - transclude(function(node) { - elm.prepend(node[0]); - }); + linkurl: '@svgAnchor', + text: '@?' } })); }); inject(function($compile, $rootScope, $templateCache) { - $templateCache.put('template.html', '{{pow}}'); - element = $compile('8')($rootScope); + $templateCache.put('template.html', '{{text}}'); + element = $compile('')($rootScope); $rootScope.$digest(); var child = element.children().eq(0); - expect(nodeName_(child)).toMatch(/msup/i); + expect(nodeName_(child)).toMatch(/a/i); + expect(isSVGElement(child[0])).toBe(true); + expect(child[0].href.baseVal).toBe("/foo/bar"); }); }); + + if (supportsMathML()) { + // MathML is only natively supported in Firefox at the time of this test's writing, + // and even there, the browser does not export MathML element constructors globally. + it('should support MathML templates using directive.templateNamespace=math', function() { + module(function() { + directive('pow', valueFn({ + replace: true, + transclude: true, + templateUrl: 'template.html', + templateNamespace: 'math', + scope: { + pow: '@pow', + }, + link: function(scope, elm, attr, ctrl, transclude) { + transclude(function(node) { + elm.prepend(node[0]); + }); + } + })); + }); + inject(function($compile, $rootScope, $templateCache) { + $templateCache.put('template.html', '{{pow}}'); + element = $compile('8')($rootScope); + $rootScope.$digest(); + var child = element.children().eq(0); + expect(nodeName_(child)).toMatch(/msup/i); + expect(isUnknownElement(child[0])).toBe(false); + expect(isHTMLElement(child[0])).toBe(false); + }); + }); + } });