Skip to content

Commit

Permalink
support for cdata elements like <script> and <xmp>
Browse files Browse the repository at this point in the history
  • Loading branch information
tmont committed Jun 6, 2012
1 parent 00ad88c commit a83f8a5
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 5 deletions.
11 changes: 11 additions & 0 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ function parseOpenElement(context) {
var name = context.readRegex(nameRegex);
context.callbacks.openElement(name);
readAttributes(context, false);

if (name !== 'script' && name !== 'xmp') {
return;
}

//just read until the closing tags for elements that allow cdata
var regex = new RegExp('^([\\s\\S]*?)(?:$|</' + name + '>)', 'i');
var match = regex.exec(context.substring);
context.read(match[0].length);
context.callbacks.cdata(match[1]);
context.callbacks.closeElement(name);
}

function parseEndElement(context) {
Expand Down
49 changes: 49 additions & 0 deletions tests/cdata-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,53 @@ describe('CDATA', function() {
cdataCount.should.equal(1);
textCount.should.equal(1);
});

it('script tags do not require CDATA', function() {
var closeCount = 0, cdataCount = 0, openCount = 0;
helpers.parseString('<script><foo></script>', {
openElement: function(name) {
name.should.equal('script');
openCount++;
},

closeElement: function(name) {
name.should.equal('script');
closeCount++;
},

cdata: function(value) {
value.should.equal('<foo>');
cdataCount++;
}
});

cdataCount.should.equal(1);
closeCount.should.equal(1);
openCount.should.equal(1);
});

it('xmp tags do not require CDATA', function() {
var closeCount = 0, cdataCount = 0, openCount = 0;
helpers.parseString('<xmp><foo></xmp>', {
openElement: function(name) {
name.should.equal('xmp');
openCount++;
},

closeElement: function(name) {
name.should.equal('xmp');
closeCount++;
},

cdata: function(value) {
value.should.equal('<foo>');
cdataCount++;
}
});

cdataCount.should.equal(1);
closeCount.should.equal(1);
openCount.should.equal(1);
});

});
12 changes: 10 additions & 2 deletions tests/files/good-expected.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<html>
<head>
<title>tommy montgomery </title>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<meta foo="bar" http-equiv="content-type" content="text/html;charset=utf-8"/>
<link rel="stylesheet" href="/media/css/global.css"/>
<link rel="shortcut icon" type="image/png" href="/favicon.ico"/>
</head>
Expand All @@ -19,6 +19,14 @@ <h1><a href="/"><span>t</span>ommy <span>mont</span>gomery</a></h1>
</div>
</div>

<script src="/media/js/d3.min.js"></script>
<!-- this is a comment -->
<footer>
<![CDATA[ I don't need to escape <script> ]]>
</footer>

<script type="text/javascript">
var foo = '<foo>';
document.write(foo);
</script>
</body>
</html>
17 changes: 14 additions & 3 deletions tests/files/good.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
<html>
<head>
<title>tommy montgomery </title>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<meta foo=bar http-equiv="content-type" content="text/html;charset=utf-8"/>
<link rel="stylesheet" href="/media/css/global.css"/>
<link rel="shortcut icon" type="image/png" href="/favicon.ico"/>
<link
rel="shortcut icon"
type="image/png"
href="/favicon.ico"/>
</head>

<body>
Expand All @@ -18,6 +21,14 @@ <h1><a href="/"><span>t</span>ommy <span>mont</span>gomery</a></h1>
</div>
</div>

<script src="/media/js/d3.min.js"></script>
<!-- this is a comment -->
<footer>
<![CDATA[ I don't need to escape <script> ]]>
</footer>

<script type="text/javascript">
var foo = '<foo>';
document.write(foo);
</script>
</body>
</html>
19 changes: 19 additions & 0 deletions tests/integration-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ var helpers = require('./helpers');
describe('Integration', function() {
it('real life HTML document', function(done) {
var content = '';
var inScriptTag = false;
helpers.parser.parseFile(__dirname + '/files/good.html', 'utf8', {
docType: function(value) {
content += '<!doctype ' + value + '>\n';
},

openElement: function(name) {
content += '<' + name;
if (name === 'script') {
inScriptTag = true;
}
},

closeOpenedElement: function(token) {
Expand All @@ -19,6 +23,9 @@ describe('Integration', function() {

closeElement: function(name) {
content += '</' + name + '>';
if (name === 'script') {
inScriptTag = false;
}
},

attribute: function(name, value) {
Expand All @@ -27,6 +34,18 @@ describe('Integration', function() {

text: function(value) {
content += value;
},

comment: function(value) {
content += '<!--' + value + '-->';
},

cdata: function(value) {
if (inScriptTag) {
content += value;
} else {
content += '<![CDATA[' + value + ']]>';
}
}
}, function(err) {
should.not.exist(err);
Expand Down

0 comments on commit a83f8a5

Please sign in to comment.