1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- /**
- * Copyright (c) 2013-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @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;
|