Skip to content

Commit dfe4fea

Browse files
committed
Add support for allowing comments or doctypes
Closes GH-11.
1 parent e2c2424 commit dfe4fea

File tree

3 files changed

+81
-11
lines changed

3 files changed

+81
-11
lines changed

lib/index.js

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ var own = {}.hasOwnProperty
1212
/* Schema. */
1313
var NODES = {
1414
root: {children: all},
15+
doctype: handleDoctype,
16+
comment: handleComment,
1517
element: {
1618
tagName: handleTagName,
1719
properties: handleProperties,
@@ -57,25 +59,36 @@ function one(schema, node, stack) {
5759
var type = node && node.type
5860
var replacement = {type: node.type}
5961
var replace = true
62+
var definition
6063
var allowed
6164
var result
6265
var key
6366

6467
if (!own.call(NODES, type)) {
6568
replace = false
6669
} else {
67-
allowed = xtend(NODES[type], NODES['*'])
70+
definition = NODES[type]
6871

69-
for (key in allowed) {
70-
result = allowed[key](schema, node[key], node, stack)
72+
if (typeof definition === 'function') {
73+
definition = definition(schema, node)
74+
}
75+
76+
if (!definition) {
77+
replace = false
78+
} else {
79+
allowed = xtend(definition, NODES['*'])
7180

72-
if (result === false) {
73-
replace = false
81+
for (key in allowed) {
82+
result = allowed[key](schema, node[key], node, stack)
7483

75-
/* Set the non-safe value. */
76-
replacement[key] = node[key]
77-
} else if (result !== null && result !== undefined) {
78-
replacement[key] = result
84+
if (result === false) {
85+
replace = false
86+
87+
/* Set the non-safe value. */
88+
replacement[key] = node[key]
89+
} else if (result !== null && result !== undefined) {
90+
replacement[key] = result
91+
}
7992
}
8093
}
8194
}
@@ -253,6 +266,11 @@ function handleProtocol(schema, value, prop) {
253266
return false
254267
}
255268

269+
/* Always return a valid HTML5 doctype. */
270+
function handleDoctypeName() {
271+
return 'html'
272+
}
273+
256274
/* Sanitize `tagName`. */
257275
function handleTagName(schema, tagName, node, stack) {
258276
var name = typeof tagName === 'string' ? tagName : null
@@ -286,6 +304,14 @@ function handleTagName(schema, tagName, node, stack) {
286304
return name
287305
}
288306

307+
function handleDoctype(schema) {
308+
return schema.allowDoctypes ? {name: handleDoctypeName} : null
309+
}
310+
311+
function handleComment(schema) {
312+
return schema.allowComments ? {value: handleValue} : null
313+
}
314+
289315
/* Sanitize `value`. */
290316
function handleValue(schema, value) {
291317
return typeof value === 'string' ? value : ''

readme.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ var gh = require('hast-util-sanitize/lib/github');
9393

9494
var schema = merge(gh, {attributes: {'*': ['className']}});
9595

96-
var tree = sanitize(h('div', {className: ['foo']}));
96+
var tree = sanitize(h('div', {className: ['foo']}), schema);
9797
// `tree` still has `className`.
9898
```
9999

@@ -213,6 +213,22 @@ should however be entirely stripped from the tree.
213213
]
214214
```
215215

216+
###### `allowComments`
217+
218+
Whether to allow comment nodes (`boolean`, default: `false`).
219+
220+
```js
221+
"allowComments": true
222+
```
223+
224+
###### `allowDoctypes`
225+
226+
Whether to allow doctype nodes (`boolean`, default: `false`).
227+
228+
```js
229+
"allowDoctypes": true
230+
```
231+
216232
## Contribute
217233

218234
See [`contributing.md` in `syntax-tree/hast`][contributing] for ways to get

test.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,38 @@ test('sanitize()', function(t) {
5353
'should ignore `characterData`s'
5454
)
5555

56+
st.end()
57+
})
58+
59+
t.test('`comment`', function(st) {
5660
st.equal(
5761
html(sanitize(u('comment', 'alpha'))),
5862
'',
59-
'should ignore `comment`s'
63+
'should ignore `comment`s by default'
64+
)
65+
66+
st.equal(
67+
html(sanitize(u('comment', 'alpha'), {allowComments: true})),
68+
'<!--alpha-->',
69+
'should allow `comment`s with `allowComments: true`'
70+
)
71+
72+
st.end()
73+
})
74+
75+
t.test('`doctype`', function(st) {
76+
st.equal(
77+
html(sanitize(u('doctype', {name: 'html'}, 'alpha'))),
78+
'',
79+
'should ignore `doctype`s by default'
80+
)
81+
82+
st.equal(
83+
html(
84+
sanitize(u('doctype', {name: 'html'}, 'alpha'), {allowDoctypes: true})
85+
),
86+
'<!DOCTYPE html>',
87+
'should allow `doctype`s with `allowDoctypes: true`'
6088
)
6189

6290
st.end()

0 commit comments

Comments
 (0)