getMarkupWrap.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. "use strict";
  2. /**
  3. * Copyright (c) 2013-present, Facebook, Inc.
  4. *
  5. * This source code is licensed under the MIT license found in the
  6. * LICENSE file in the root directory of this source tree.
  7. *
  8. */
  9. /*eslint-disable fb-www/unsafe-html */
  10. var ExecutionEnvironment = require("./ExecutionEnvironment");
  11. var invariant = require("./invariant");
  12. /**
  13. * Dummy container used to detect which wraps are necessary.
  14. */
  15. var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
  16. /**
  17. * Some browsers cannot use `innerHTML` to render certain elements standalone,
  18. * so we wrap them, render the wrapped nodes, then extract the desired node.
  19. *
  20. * In IE8, certain elements cannot render alone, so wrap all elements ('*').
  21. */
  22. var shouldWrap = {};
  23. var selectWrap = [1, '<select multiple="true">', '</select>'];
  24. var tableWrap = [1, '<table>', '</table>'];
  25. var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
  26. var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>'];
  27. var markupWrap = {
  28. '*': [1, '?<div>', '</div>'],
  29. 'area': [1, '<map>', '</map>'],
  30. 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
  31. 'legend': [1, '<fieldset>', '</fieldset>'],
  32. 'param': [1, '<object>', '</object>'],
  33. 'tr': [2, '<table><tbody>', '</tbody></table>'],
  34. 'optgroup': selectWrap,
  35. 'option': selectWrap,
  36. 'caption': tableWrap,
  37. 'colgroup': tableWrap,
  38. 'tbody': tableWrap,
  39. 'tfoot': tableWrap,
  40. 'thead': tableWrap,
  41. 'td': trWrap,
  42. 'th': trWrap
  43. }; // Initialize the SVG elements since we know they'll always need to be wrapped
  44. // consistently. If they are created inside a <div> they will be initialized in
  45. // the wrong namespace (and will not display).
  46. var svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan'];
  47. svgElements.forEach(function (nodeName) {
  48. markupWrap[nodeName] = svgWrap;
  49. shouldWrap[nodeName] = true;
  50. });
  51. /**
  52. * Gets the markup wrap configuration for the supplied `nodeName`.
  53. *
  54. * NOTE: This lazily detects which wraps are necessary for the current browser.
  55. *
  56. * @param {string} nodeName Lowercase `nodeName`.
  57. * @return {?array} Markup wrap configuration, if applicable.
  58. */
  59. function getMarkupWrap(nodeName) {
  60. !!!dummyNode ? process.env.NODE_ENV !== "production" ? invariant(false, 'Markup wrapping node not initialized') : invariant(false) : void 0;
  61. if (!markupWrap.hasOwnProperty(nodeName)) {
  62. nodeName = '*';
  63. }
  64. if (!shouldWrap.hasOwnProperty(nodeName)) {
  65. if (nodeName === '*') {
  66. dummyNode.innerHTML = '<link />';
  67. } else {
  68. dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>';
  69. }
  70. shouldWrap[nodeName] = !dummyNode.firstChild;
  71. }
  72. return shouldWrap[nodeName] ? markupWrap[nodeName] : null;
  73. }
  74. module.exports = getMarkupWrap;