fix(ngSanitize): prefer textContent to innerText to avoid layout trashing

innerText depends on styling as it doesn't display hidden elements.
Therefore, it's better to use textContent not to cause unnecessary
reflows. However, IE<9 don't support textContent so the innerText
fallback is necessary.
This commit is contained in:
Michał Gołębiowski 2013-11-24 21:13:51 +01:00 committed by Tobias Bosch
parent 689dfb1679
commit bf1972dc1e
2 changed files with 58 additions and 1 deletions

View file

@ -378,7 +378,12 @@ function decodeEntities(value) {
var content = parts[2]; var content = parts[2];
if (content) { if (content) {
hiddenPre.innerHTML=content.replace(/</g,"&lt;"); hiddenPre.innerHTML=content.replace(/</g,"&lt;");
content = hiddenPre.innerText || hiddenPre.textContent; // innerText depends on styling as it doesn't display hidden elements.
// Therefore, it's better to use textContent not to cause unnecessary
// reflows. However, IE<9 don't support textContent so the innerText
// fallback is necessary.
content = 'textContent' in hiddenPre ?
hiddenPre.textContent : hiddenPre.innerText;
} }
return spaceBefore + content + spaceAfter; return spaceBefore + content + spaceAfter;
} }

View file

@ -411,3 +411,55 @@ describe('HTML', function() {
}); });
}); });
}); });
describe('decodeEntities', function() {
var handler, text,
origHiddenPre = window.hiddenPre;
beforeEach(function() {
text = '';
handler = {
start: function() {},
chars: function(text_){
text = text_;
},
end: function() {},
comment: function() {}
};
module('ngSanitize');
});
afterEach(function() {
window.hiddenPre = origHiddenPre;
});
it('should use innerText if textContent is not available (IE<9)', function() {
window.hiddenPre = {
innerText: 'INNER_TEXT'
};
inject(function($sanitize) {
htmlParser('<tag>text</tag>', handler);
expect(text).toEqual('INNER_TEXT');
});
});
it('should use textContent if available', function() {
window.hiddenPre = {
textContent: 'TEXT_CONTENT',
innerText: 'INNER_TEXT'
};
inject(function($sanitize) {
htmlParser('<tag>text</tag>', handler);
expect(text).toEqual('TEXT_CONTENT');
});
});
it('should use textContent even if empty', function() {
window.hiddenPre = {
textContent: '',
innerText: 'INNER_TEXT'
};
inject(function($sanitize) {
htmlParser('<tag>text</tag>', handler);
expect(text).toEqual('');
});
});
});