From 3ccd9c846920e48bbd6edc2772c713230c0f7bcf Mon Sep 17 00:00:00 2001 From: Stephen Judkins Date: Tue, 13 May 2014 12:42:17 -0700 Subject: [PATCH 1/2] fix($compile): call `normalize` on nodes for cases when browser creates multiple text nodes when parsing HTML --- src/ng/compile.js | 4 ++++ test/ng/compileSpec.js | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/ng/compile.js b/src/ng/compile.js index cfa72d972e67..de786f7089b1 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -843,7 +843,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } // 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){ + node.normalize(); + 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 b3af196f3bb7..b8475917d55b 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -2317,6 +2317,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) { From 53c8989f67ce92430ce162720770d567f1086630 Mon Sep 17 00:00:00 2001 From: Stephen Judkins Date: Tue, 20 May 2014 10:49:28 -0700 Subject: [PATCH 2/2] fix($compile): new node-normalization functionality that works reliably in IE11 --- src/ng/compile.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index a54c996b8524..08385c72f202 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -841,12 +841,36 @@ 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){ - node.normalize(); + normalizeNode(node); if (node.nodeType == 3 /* text node */ && node.nodeValue.match(/\S+/) /* non-empty */ ) { $compileNodes[index] = node = jqLite(node).wrap('').parent()[0];