Skip to content

Commit ae5c87e

Browse files
committed
Ensure isBlank checks for significant elements within the given node.
DRY up the is/has functions and always use uppercase to prevent excessive toLowerCase calls
1 parent 46fc45b commit ae5c87e

File tree

3 files changed

+52
-16
lines changed

3 files changed

+52
-16
lines changed

src/node.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isBlock, isVoid, hasVoid } from './utilities'
1+
import { isBlock, isVoid, hasVoid, isMeaningfulWhenBlank, hasMeaningfulWhenBlank } from './utilities'
22

33
export default function Node (node) {
44
node.isBlock = isBlock(node)
@@ -10,10 +10,11 @@ export default function Node (node) {
1010

1111
function isBlank (node) {
1212
return (
13-
['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&
14-
/^\s*$/i.test(node.textContent) &&
1513
!isVoid(node) &&
16-
!hasVoid(node)
14+
!isMeaningfulWhenBlank(node) &&
15+
/^\s*$/i.test(node.textContent) &&
16+
!hasVoid(node) &&
17+
!hasMeaningfulWhenBlank(node)
1718
)
1819
}
1920

src/utilities.js

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,53 @@ export function repeat (character, count) {
1313
}
1414

1515
export var blockElements = [
16-
'address', 'article', 'aside', 'audio', 'blockquote', 'body', 'canvas',
17-
'center', 'dd', 'dir', 'div', 'dl', 'dt', 'fieldset', 'figcaption',
18-
'figure', 'footer', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
19-
'header', 'hgroup', 'hr', 'html', 'isindex', 'li', 'main', 'menu', 'nav',
20-
'noframes', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table',
21-
'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'ul'
16+
'ADDRESS', 'ARTICLE', 'ASIDE', 'AUDIO', 'BLOCKQUOTE', 'BODY', 'CANVAS',
17+
'CENTER', 'DD', 'DIR', 'DIV', 'DL', 'DT', 'FIELDSET', 'FIGCAPTION', 'FIGURE',
18+
'FOOTER', 'FORM', 'FRAMESET', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER',
19+
'HGROUP', 'HR', 'HTML', 'ISINDEX', 'LI', 'MAIN', 'MENU', 'NAV', 'NOFRAMES',
20+
'NOSCRIPT', 'OL', 'OUTPUT', 'P', 'PRE', 'SECTION', 'TABLE', 'TBODY', 'TD',
21+
'TFOOT', 'TH', 'THEAD', 'TR', 'UL'
2222
]
2323

2424
export function isBlock (node) {
25-
return blockElements.indexOf(node.nodeName.toLowerCase()) !== -1
25+
return is(node, blockElements)
2626
}
2727

2828
export var voidElements = [
29-
'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input',
30-
'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'
29+
'AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT',
30+
'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR'
3131
]
3232

3333
export function isVoid (node) {
34-
return voidElements.indexOf(node.nodeName.toLowerCase()) !== -1
34+
return is(node, voidElements)
3535
}
3636

37-
var voidSelector = voidElements.join()
3837
export function hasVoid (node) {
39-
return node.querySelector && node.querySelector(voidSelector)
38+
return has(node, voidElements)
39+
}
40+
41+
var meaningfulWhenBlankElements = [
42+
'A', 'TABLE', 'THEAD', 'TBODY', 'TFOOT', 'TH', 'TD', 'IFRAME', 'SCRIPT',
43+
'AUDIO', 'VIDEO'
44+
]
45+
46+
export function isMeaningfulWhenBlank (node) {
47+
return is(node, meaningfulWhenBlankElements)
48+
}
49+
50+
export function hasMeaningfulWhenBlank (node) {
51+
return has(node, meaningfulWhenBlankElements)
52+
}
53+
54+
function is (node, tagNames) {
55+
return tagNames.indexOf(node.nodeName) >= 0
56+
}
57+
58+
function has (node, tagNames) {
59+
return (
60+
node.getElementsByTagName &&
61+
tagNames.some(function (tagName) {
62+
return node.getElementsByTagName(tagName).length
63+
})
64+
)
4065
}

test/turndown-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ test('keep rules are overridden by the standard rules', function (t) {
118118
t.equal(turndownService.turndown('<p>Hello world</p>'), 'Hello world')
119119
})
120120

121+
test('keeping elements that have a blank textContent but contain significant elements', function (t) {
122+
t.plan(1)
123+
var turndownService = new TurndownService()
124+
turndownService.keep('figure')
125+
t.equal(
126+
turndownService.turndown('<figure><iframe src="http://example.com"></iframe></figure>'),
127+
'<figure><iframe src="http://example.com"></iframe></figure>'
128+
)
129+
})
130+
121131
test('keepReplacement can be customised', function (t) {
122132
t.plan(1)
123133
var turndownService = new TurndownService({

0 commit comments

Comments
 (0)