diff options
| -rw-r--r-- | src/ng/compile.js | 31 | ||||
| -rwxr-xr-x | test/ng/compileSpec.js | 97 | 
2 files changed, 123 insertions, 5 deletions
| diff --git a/src/ng/compile.js b/src/ng/compile.js index de65c83e..e4bf230e 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -502,7 +502,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {    var hasDirectives = {},        Suffix = 'Directive',        COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/, -      CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/; +      CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/, +      TABLE_CONTENT_REGEXP = /^<\s*(tr|th|td|tbody)(\s+[^>]*)?>/i;    // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes    // The assumption is that future DOM event attribute names will begin with @@ -1243,9 +1244,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {            if (directive.replace) {              replaceDirective = directive; -            $template = jqLite('<div>' + -                                 trim(directiveValue) + -                               '</div>').contents(); +            $template = directiveTemplateContents(directiveValue);              compileNode = $template[0];              if ($template.length != 1 || compileNode.nodeType !== 1) { @@ -1644,6 +1643,28 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {      } +    function directiveTemplateContents(template) { +      var type; +      template = trim(template); +      if ((type = TABLE_CONTENT_REGEXP.exec(template))) { +        type = type[1].toLowerCase(); +        var table = jqLite('<table>' + template + '</table>'), +            tbody = table.children('tbody'), +            leaf = /(td|th)/.test(type) && table.find('tr'); +        if (tbody.length && type !== 'tbody') { +          table = tbody; +        } +        if (leaf && leaf.length) { +          table = leaf; +        } +        return table.contents(); +      } +      return jqLite('<div>' + +                      template + +                    '</div>').contents(); +    } + +      function compileTemplateUrl(directives, $compileNode, tAttrs,          $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {        var linkQueue = [], @@ -1668,7 +1689,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {            content = denormalizeTemplate(content);            if (origAsyncDirective.replace) { -            $template = jqLite('<div>' + trim(content) + '</div>').contents(); +            $template = directiveTemplateContents(content);              compileNode = $template[0];              if ($template.length != 1 || compileNode.nodeType !== 1) { diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 60b1024b..e9ab15e4 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -517,6 +517,22 @@ describe('$compile', function() {                expect(element).toBe(attr.$$element);              }            })); +          directive('replaceWithTr', valueFn({ +            replace: true, +            template: '<tr><td>TR</td></tr>' +          })); +          directive('replaceWithTd', valueFn({ +            replace: true, +            template: '<td>TD</td>' +          })); +          directive('replaceWithTh', valueFn({ +            replace: true, +            template: '<th>TH</th>' +          })); +          directive('replaceWithTbody', valueFn({ +            replace: true, +            template: '<tbody><tr><td>TD</td></tr></tbody>' +          }));          })); @@ -680,6 +696,34 @@ describe('$compile', function() {              }).not.toThrow();            });          }); + +        it('should support templates with root <tr> tags', inject(function($compile, $rootScope) { +          expect(function() { +            element = $compile('<div replace-with-tr></div>')($rootScope); +          }).not.toThrow(); +          expect(nodeName_(element)).toMatch(/tr/i); +        })); + +        it('should support templates with root <td> tags', inject(function($compile, $rootScope) { +          expect(function() { +            element = $compile('<div replace-with-td></div>')($rootScope); +          }).not.toThrow(); +          expect(nodeName_(element)).toMatch(/td/i); +        })); + +        it('should support templates with root <th> tags', inject(function($compile, $rootScope) { +          expect(function() { +            element = $compile('<div replace-with-th></div>')($rootScope); +          }).not.toThrow(); +          expect(nodeName_(element)).toMatch(/th/i); +        })); + +        it('should support templates with root <tbody> tags', inject(function($compile, $rootScope) { +          expect(function() { +            element = $compile('<div replace-with-tbody></div>')($rootScope); +          }).not.toThrow(); +          expect(nodeName_(element)).toMatch(/tbody/i); +        }));        }); @@ -776,6 +820,23 @@ describe('$compile', function() {                replace: true,                template: '<span>Hello, {{name}}!</span>'              })); + +            directive('replaceWithTr', valueFn({ +              replace: true, +              templateUrl: 'tr.html' +            })); +            directive('replaceWithTd', valueFn({ +              replace: true, +              templateUrl: 'td.html' +            })); +            directive('replaceWithTh', valueFn({ +              replace: true, +              templateUrl: 'th.html' +            })); +            directive('replaceWithTbody', valueFn({ +              replace: true, +              templateUrl: 'tbody.html' +            }));            }          )); @@ -1411,6 +1472,42 @@ describe('$compile', function() {              expect(element.html()).toContain('i = 1');            });          }); + +        it('should support templates with root <tr> tags', inject(function($compile, $rootScope, $templateCache) { +          $templateCache.put('tr.html', '<tr><td>TR</td></tr>'); +          expect(function() { +            element = $compile('<div replace-with-tr></div>')($rootScope); +          }).not.toThrow(); +          $rootScope.$digest(); +          expect(nodeName_(element)).toMatch(/tr/i); +        })); + +        it('should support templates with root <td> tags', inject(function($compile, $rootScope, $templateCache) { +          $templateCache.put('td.html', '<td>TD</td>'); +          expect(function() { +            element = $compile('<div replace-with-td></div>')($rootScope); +          }).not.toThrow(); +          $rootScope.$digest(); +          expect(nodeName_(element)).toMatch(/td/i); +        })); + +        it('should support templates with root <th> tags', inject(function($compile, $rootScope, $templateCache) { +          $templateCache.put('th.html', '<th>TH</th>'); +          expect(function() { +            element = $compile('<div replace-with-th></div>')($rootScope); +          }).not.toThrow(); +          $rootScope.$digest(); +          expect(nodeName_(element)).toMatch(/th/i); +        })); + +        it('should support templates with root <tbody> tags', inject(function($compile, $rootScope, $templateCache) { +          $templateCache.put('tbody.html', '<tbody><tr><td>TD</td></tr></tbody>'); +          expect(function() { +            element = $compile('<div replace-with-tbody></div>')($rootScope); +          }).not.toThrow(); +          $rootScope.$digest(); +          expect(nodeName_(element)).toMatch(/tbody/i); +        }));        }); | 
