wallet-core/node_modules/fbjs/lib/createNodesFromMarkup.js.flow
2017-05-03 15:35:00 +02:00

82 lines
2.5 KiB
Plaintext

/**
* Copyright (c) 2013-present, 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.
*
* @providesModule createNodesFromMarkup
* @typechecks
*/
/*eslint-disable fb-www/unsafe-html*/
const ExecutionEnvironment = require('./ExecutionEnvironment');
const createArrayFromMixed = require('./createArrayFromMixed');
const getMarkupWrap = require('./getMarkupWrap');
const invariant = require('./invariant');
/**
* Dummy container used to render all markup.
*/
const dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
/**
* Pattern used by `getNodeName`.
*/
const nodeNamePattern = /^\s*<(\w+)/;
/**
* Extracts the `nodeName` of the first element in a string of markup.
*
* @param {string} markup String of markup.
* @return {?string} Node name of the supplied markup.
*/
function getNodeName(markup) {
const nodeNameMatch = markup.match(nodeNamePattern);
return nodeNameMatch && nodeNameMatch[1].toLowerCase();
}
/**
* Creates an array containing the nodes rendered from the supplied markup. The
* optionally supplied `handleScript` function will be invoked once for each
* <script> element that is rendered. If no `handleScript` function is supplied,
* an exception is thrown if any <script> elements are rendered.
*
* @param {string} markup A string of valid HTML markup.
* @param {?function} handleScript Invoked once for each rendered <script>.
* @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.
*/
function createNodesFromMarkup(markup, handleScript) {
let node = dummyNode;
invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized');
const nodeName = getNodeName(markup);
const wrap = nodeName && getMarkupWrap(nodeName);
if (wrap) {
node.innerHTML = wrap[1] + markup + wrap[2];
let wrapDepth = wrap[0];
while (wrapDepth--) {
node = node.lastChild;
}
} else {
node.innerHTML = markup;
}
const scripts = node.getElementsByTagName('script');
if (scripts.length) {
invariant(handleScript, 'createNodesFromMarkup(...): Unexpected <script> element rendered.');
createArrayFromMixed(scripts).forEach(handleScript);
}
const nodes = Array.from(node.childNodes);
while (node.lastChild) {
node.removeChild(node.lastChild);
}
return nodes;
}
module.exports = createNodesFromMarkup;