Skip to content

Commit fee7bac

Browse files
revert: fix($compile): do not add <span> elements to root text nodes
This commit reverts 7617c08 which was accidentally merged into 1.5.x (by @petebacondarwin in a moment of rebase madness) despite it containing a breaking change.
1 parent dbb3b0f commit fee7bac

File tree

3 files changed

+34
-53
lines changed

3 files changed

+34
-53
lines changed

src/ng/compile.js

+13
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15291529
// modify it.
15301530
$compileNodes = jqLite($compileNodes);
15311531
}
1532+
1533+
var NOT_EMPTY = /\S+/;
1534+
1535+
// We can not compile top level text elements since text nodes can be merged and we will
1536+
// not be able to attach scope data to them, so we will wrap them in <span>
1537+
for (var i = 0, len = $compileNodes.length; i < len; i++) {
1538+
var domNode = $compileNodes[i];
1539+
1540+
if (domNode.nodeType === NODE_TYPE_TEXT && domNode.nodeValue.match(NOT_EMPTY) /* non-empty */) {
1541+
jqLiteWrapNode(domNode, $compileNodes[i] = document.createElement('span'));
1542+
}
1543+
}
1544+
15321545
var compositeLinkFn =
15331546
compileNodes($compileNodes, transcludeFn, $compileNodes,
15341547
maxPriority, ignoreDirective, previousCompileContext);

src/ng/directive/ngTransclude.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
* <div ng-controller="ExampleController">
4848
* <input ng-model="title" aria-label="title"> <br/>
4949
* <textarea ng-model="text" aria-label="text"></textarea> <br/>
50-
* <pane title="{{title}}"><span>{{text}}</span></pane>
50+
* <pane title="{{title}}">{{text}}</pane>
5151
* </div>
5252
* </file>
5353
* <file name="protractor.js" type="protractor">

test/ng/compileSpec.js

+20-52
Original file line numberDiff line numberDiff line change
@@ -371,28 +371,27 @@ describe('$compile', function() {
371371
expect($document.scope()).toBe($rootScope);
372372
}));
373373

374+
it('should wrap root text nodes in spans', inject(function($compile, $rootScope) {
375+
element = jqLite('<div>A&lt;a&gt;B&lt;/a&gt;C</div>');
376+
var text = element.contents();
377+
expect(text[0].nodeName).toEqual('#text');
378+
text = $compile(text)($rootScope);
379+
expect(text[0].nodeName).toEqual('SPAN');
380+
expect(element.find('span').text()).toEqual('A<a>B</a>C');
381+
}));
382+
374383

375-
it('should not wrap root text nodes in spans', function() {
384+
it('should not wrap root whitespace text nodes in spans', function() {
376385
element = jqLite(
377-
'<div> <div>A</div>\n ' +
378-
'<div>B</div>C\t\n ' +
386+
'<div> <div>A</div>\n ' + // The spaces and newlines here should not get wrapped
387+
'<div>B</div>C\t\n ' + // The "C", tabs and spaces here will be wrapped
379388
'</div>');
380389
$compile(element.contents())($rootScope);
381390
var spans = element.find('span');
382-
expect(spans.length).toEqual(0);
391+
expect(spans.length).toEqual(1);
392+
expect(spans.text().indexOf('C')).toEqual(0);
383393
});
384394

385-
386-
it('should be able to compile text nodes at the root', inject(function($rootScope) {
387-
element = jqLite('<div>Name: {{name}}<br />\nColor: {{color}}</div>');
388-
$rootScope.name = 'Lucas';
389-
$rootScope.color = 'blue';
390-
$compile(element.contents())($rootScope);
391-
$rootScope.$digest();
392-
expect(element.text()).toEqual('Name: Lucas\nColor: blue');
393-
}));
394-
395-
396395
it('should not leak memory when there are top level empty text nodes', function() {
397396
// We compile the contents of element (i.e. not element itself)
398397
// Then delete these contents and check the cache has been reset to zero
@@ -6595,8 +6594,8 @@ describe('$compile', function() {
65956594
$rootScope.x = 'root';
65966595
$rootScope.$apply();
65976596
expect(element.text()).toEqual('W:iso-1-2;T:root-2-3;');
6598-
expect(jqLite(jqLite(element.find('li')[1]).contents()[0]).text()).toEqual('T:root-2-3');
6599-
expect(jqLite(element.find('span')[0]).text()).toEqual(';');
6597+
expect(jqLite(element.find('span')[0]).text()).toEqual('T:root-2-3');
6598+
expect(jqLite(element.find('span')[1]).text()).toEqual(';');
66006599
});
66016600
});
66026601

@@ -6634,37 +6633,6 @@ describe('$compile', function() {
66346633
});
66356634

66366635

6637-
it('should not merge text elements from transcluded content', function() {
6638-
module(function() {
6639-
directive('foo', valueFn({
6640-
transclude: 'content',
6641-
template: '<div>This is before {{before}}. </div>',
6642-
link: function(scope, element, attr, ctrls, $transclude) {
6643-
var futureParent = element.children().eq(0);
6644-
$transclude(function(clone) {
6645-
futureParent.append(clone);
6646-
}, futureParent);
6647-
},
6648-
scope: true
6649-
}));
6650-
});
6651-
inject(function($rootScope, $compile) {
6652-
element = $compile('<div><div foo>This is after {{after}}</div></div>')($rootScope);
6653-
$rootScope.before = "BEFORE";
6654-
$rootScope.after = "AFTER";
6655-
$rootScope.$apply();
6656-
expect(element.text()).toEqual('This is before BEFORE. This is after AFTER');
6657-
6658-
$rootScope.before = "Not-Before";
6659-
$rootScope.after = "AfTeR";
6660-
$rootScope.$$childHead.before = "BeFoRe";
6661-
$rootScope.$$childHead.after = "Not-After";
6662-
$rootScope.$apply();
6663-
expect(element.text()).toEqual('This is before BeFoRe. This is after AfTeR');
6664-
});
6665-
});
6666-
6667-
66686636
it('should only allow one content transclusion per element', function() {
66696637
module(function() {
66706638
directive('first', valueFn({
@@ -6963,11 +6931,11 @@ describe('$compile', function() {
69636931
transclude: true,
69646932
replace: true,
69656933
scope: true,
6966-
template: '<div><span>I:{{$$transcluded}}</span><span ng-transclude></span></div>'
6934+
template: '<div><span>I:{{$$transcluded}}</span><div ng-transclude></div></div>'
69676935
};
69686936
});
69696937
});
6970-
inject(function($rootScope, $compile) {
6938+
inject(function(log, $rootScope, $compile) {
69716939
element = $compile('<div><div trans>T:{{$$transcluded}}</div></div>')($rootScope);
69726940
$rootScope.$apply();
69736941
expect(jqLite(element.find('span')[0]).text()).toEqual('I:');
@@ -6986,10 +6954,10 @@ describe('$compile', function() {
69866954
};
69876955
});
69886956
});
6989-
inject(function($rootScope, $compile) {
6957+
inject(function(log, $rootScope, $compile) {
69906958
element = $compile('<div trans>unicorn!</div>')($rootScope);
69916959
$rootScope.$apply();
6992-
expect(sortedHtml(element.html())).toEqual('<div ng-transclude="">unicorn!</div>');
6960+
expect(sortedHtml(element.html())).toEqual('<div ng-transclude=""><span>unicorn!</span></div>');
69936961
});
69946962
});
69956963

0 commit comments

Comments
 (0)