diff --git a/src/ng/compile.js b/src/ng/compile.js index abe856122e81..08385c72f202 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -841,9 +841,37 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // modify it. $compileNodes = jqLite($compileNodes); } + + var isText = function(node) { + return node && node.nodeType === Node.TEXT_NODE; + }; + + var normalizeNode = function(node) { + var child, combined, lastSibling, _i, _len, _ref, _results; + lastSibling = null; + _ref = (node != null ? node.childNodes : void 0) || []; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (isText(child) && isText(lastSibling)) { + combined = lastSibling.nodeValue + child.nodeValue; + child.nodeValue = combined; + node.removeChild(lastSibling); + } else { + normalizeNode(child); + } + _results.push(lastSibling = child); + } + return _results; + }; + // We can not compile top level text elements since text nodes can be merged and we will // not be able to attach scope data to them, so we will wrap them in + // We also need to call `normalize` on the nodes, because in some cases + // browsers (like IE11) allocate multiple text nodes when parsing a single block of HTML. forEach($compileNodes, function(node, index){ + normalizeNode(node); + if (node.nodeType == 3 /* text node */ && node.nodeValue.match(/\S+/) /* non-empty */ ) { $compileNodes[index] = node = jqLite(node).wrap('').parent()[0]; } diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index df45976229fb..4da8535c26d6 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -2389,6 +2389,20 @@ describe('$compile', function() { })); + it('should support interpolating text spread across multiple text nodes', inject(function($rootScope, $compile) { + var rawElement = document.createElement("div"); + var textNode1 = document.createTextNode("{{foo"); + var textNode2 = document.createTextNode("bar}}"); + rawElement.appendChild(textNode1); + rawElement.appendChild(textNode2); + + var element = $compile(rawElement)($rootScope); + $rootScope.foobar = "spam eggs"; + $rootScope.$digest(); + expect(element.text()).toBe("spam eggs"); + })); + + it('should support custom start/end interpolation symbols in template and directive template', function() { module(function($interpolateProvider, $compileProvider) {