Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81158 views
1
/**
2
* Copyright 2013-2014, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @providesModule createNodesFromMarkup
10
* @typechecks
11
*/
12
13
/*jslint evil: true, sub: true */
14
15
var ExecutionEnvironment = require('ExecutionEnvironment');
16
17
var createArrayFrom = require('createArrayFrom');
18
var getMarkupWrap = require('getMarkupWrap');
19
var invariant = require('invariant');
20
21
/**
22
* Dummy container used to render all markup.
23
*/
24
var dummyNode =
25
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
26
27
/**
28
* Pattern used by `getNodeName`.
29
*/
30
var nodeNamePattern = /^\s*<(\w+)/;
31
32
/**
33
* Extracts the `nodeName` of the first element in a string of markup.
34
*
35
* @param {string} markup String of markup.
36
* @return {?string} Node name of the supplied markup.
37
*/
38
function getNodeName(markup) {
39
var nodeNameMatch = markup.match(nodeNamePattern);
40
return nodeNameMatch && nodeNameMatch[1].toLowerCase();
41
}
42
43
/**
44
* Creates an array containing the nodes rendered from the supplied markup. The
45
* optionally supplied `handleScript` function will be invoked once for each
46
* <script> element that is rendered. If no `handleScript` function is supplied,
47
* an exception is thrown if any <script> elements are rendered.
48
*
49
* @param {string} markup A string of valid HTML markup.
50
* @param {?function} handleScript Invoked once for each rendered <script>.
51
* @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.
52
*/
53
function createNodesFromMarkup(markup, handleScript) {
54
var node = dummyNode;
55
invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized');
56
var nodeName = getNodeName(markup);
57
58
var wrap = nodeName && getMarkupWrap(nodeName);
59
if (wrap) {
60
node.innerHTML = wrap[1] + markup + wrap[2];
61
62
var wrapDepth = wrap[0];
63
while (wrapDepth--) {
64
node = node.lastChild;
65
}
66
} else {
67
node.innerHTML = markup;
68
}
69
70
var scripts = node.getElementsByTagName('script');
71
if (scripts.length) {
72
invariant(
73
handleScript,
74
'createNodesFromMarkup(...): Unexpected <script> element rendered.'
75
);
76
createArrayFrom(scripts).forEach(handleScript);
77
}
78
79
var nodes = createArrayFrom(node.childNodes);
80
while (node.lastChild) {
81
node.removeChild(node.lastChild);
82
}
83
return nodes;
84
}
85
86
module.exports = createNodesFromMarkup;
87
88