forked from facebook/react
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvalidateDOMNesting-test.js
More file actions
78 lines (67 loc) · 2.95 KB
/
validateDOMNesting-test.js
File metadata and controls
78 lines (67 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* Copyright 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @emails react-core
*/
'use strict';
var isTagValidInContext;
// https://html.spec.whatwg.org/multipage/syntax.html#special
var specialTags = [
'address', 'applet', 'area', 'article', 'aside', 'base', 'basefont',
'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col',
'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset',
'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2',
'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe',
'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu',
'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol',
'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source',
'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot',
'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp'
];
// https://html.spec.whatwg.org/multipage/syntax.html#formatting
var formattingTags = [
'a', 'b', 'big', 'code', 'em', 'font', 'i', 'nobr', 's', 'small', 'strike',
'strong', 'tt', 'u'
];
function isTagStackValid(stack) {
for (var i = 0; i < stack.length; i++) {
if (!isTagValidInContext(stack[i], stack.slice(0, i))) {
return false;
}
}
return true;
}
describe('ReactContextValidator', function() {
beforeEach(function() {
require('mock-modules').dumpCache();
isTagValidInContext = require('validateDOMNesting').isTagValidInContext;
});
it('allows any tag with no context', function() {
// With renderToString (for example), we don't know where we're mounting the
// tag so we must err on the side of leniency.
specialTags.concat(formattingTags, ['mysterytag']).forEach(function(tag) {
expect(isTagValidInContext(tag, [])).toBe(true);
});
});
it('allows valid nestings', function() {
expect(isTagStackValid(['table', 'tbody', 'tr', 'td', 'b'])).toBe(true);
expect(isTagStackValid(['body', 'datalist', 'option'])).toBe(true);
expect(isTagStackValid(['div', 'a', 'object', 'a'])).toBe(true);
expect(isTagStackValid(['div', 'p', 'button', 'p'])).toBe(true);
expect(isTagStackValid(['p', 'svg', 'foreignObject', 'p'])).toBe(true);
// Invalid, but not changed by browser parsing so we allow them
expect(isTagStackValid(['div', 'ul', 'ul', 'li'])).toBe(true);
expect(isTagStackValid(['div', 'label', 'div'])).toBe(true);
});
it('prevents problematic nestings', function() {
expect(isTagStackValid(['a', 'a'])).toBe(false);
expect(isTagStackValid(['form', 'form'])).toBe(false);
expect(isTagStackValid(['p', 'p'])).toBe(false);
expect(isTagStackValid(['table', 'tr'])).toBe(false);
});
});