"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /** * Copyright (c) 2017-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. */ exports.default = function (ast, strictCode, env, realm) { (0, _invariant2.default)(realm.react.enabled, "JSXElements can only be evaluated with the reactEnabled option"); var openingElement = ast.openingElement; var type = evaluateJSXIdentifier(openingElement.name, strictCode, env, realm); var _evaluateJSXAttribute = evaluateJSXAttributes(openingElement.name, openingElement.attributes, ast.children, strictCode, env, realm), attributes = _evaluateJSXAttribute.attributes, children = _evaluateJSXAttribute.children; var key = attributes.get("key") || realm.intrinsics.null; var ref = attributes.get("ref") || realm.intrinsics.null; if (key === realm.intrinsics.undefined) { key = realm.intrinsics.null; } if (ref === realm.intrinsics.undefined) { ref = realm.intrinsics.null; } // React uses keys to identify nodes as they get updated through the reconcilation // phase. Keys are used in a map and thus need to be converted to strings if (key !== realm.intrinsics.null) { key = (0, _BinaryExpression.computeBinary)(realm, "+", realm.intrinsics.emptyString, key); } var props = createReactProps(realm, type, attributes, children, env); return createReactElement(realm, type, key, ref, props); }; var _errors = require("../errors.js"); var _index = require("../values/index.js"); var _utils = require("../react/utils.js"); var _jsx = require("../react/jsx.js"); var _babelTypes = require("babel-types"); var t = _interopRequireWildcard(_babelTypes); var _index2 = require("../methods/index.js"); var _singletons = require("../singletons.js"); var _invariant = require("../invariant.js"); var _invariant2 = _interopRequireDefault(_invariant); var _BinaryExpression = require("./BinaryExpression.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } var RESERVED_PROPS = { key: true, ref: true, __self: true, __source: true }; // taken from Babel function cleanJSXElementLiteralChild(child) { var lines = child.split(/\r\n|\n|\r/); var lastNonEmptyLine = 0; for (var i = 0; i < lines.length; i++) { if (lines[i].match(/[^ \t]/)) { lastNonEmptyLine = i; } } var str = ""; for (var _i = 0; _i < lines.length; _i++) { var line = lines[_i]; var isFirstLine = _i === 0; var isLastLine = _i === lines.length - 1; var isLastNonEmptyLine = _i === lastNonEmptyLine; // replace rendered whitespace tabs with spaces var trimmedLine = line.replace(/\t/g, " "); // trim whitespace touching a newline if (!isFirstLine) { trimmedLine = trimmedLine.replace(/^[ ]+/, ""); } // trim whitespace touching an endline if (!isLastLine) { trimmedLine = trimmedLine.replace(/[ ]+$/, ""); } if (trimmedLine) { if (!isLastNonEmptyLine) { trimmedLine += " "; } str += trimmedLine; } } if (str) { return str; } return null; } function evaluateJSXMemberExpression(ast, strictCode, env, realm) { switch (ast.type) { case "JSXIdentifier": return _singletons.Environment.GetValue(realm, _singletons.Environment.ResolveBinding(realm, ast.name, strictCode, env)); case "JSXMemberExpression": return _singletons.Environment.GetValue(realm, env.evaluate((0, _jsx.convertJSXExpressionToIdentifier)(ast), strictCode)); default: (0, _invariant2.default)(false, "Unknown JSX Identifier"); } } function evaluateJSXIdentifier(ast, strictCode, env, realm) { if (isTagName(ast)) { // special cased lower-case and custom elements return new _index.StringValue(realm, ast.name); } return evaluateJSXMemberExpression(ast, strictCode, env, realm); } function evaluateJSXValue(value, strictCode, env, realm) { if (value != null) { switch (value.type) { case "JSXText": return new _index.StringValue(realm, value.value); case "StringLiteral": return new _index.StringValue(realm, value.value); case "JSXExpressionContainer": return _singletons.Environment.GetValue(realm, env.evaluate(value.expression, strictCode)); case "JSXElement": return _singletons.Environment.GetValue(realm, env.evaluate(value, strictCode)); default: (0, _invariant2.default)(false, "Unknown JSX value type: " + value.type); } } (0, _invariant2.default)(false, "Null or undefined value passed when trying to evaluate JSX node value"); } function isTagName(ast) { return ast.type === "JSXIdentifier" && /^[a-z]|\-/.test(ast.name); } function getDefaultProps(elementType, env, realm) { var name = void 0; if (elementType.type === "JSXIdentifier") { name = elementType.name; } if (!isTagName(elementType) && typeof name === "string") { // find the value of "ComponentXXX.defaultProps" var defaultProps = _singletons.Environment.GetValue(realm, env.evaluate(t.memberExpression(t.identifier(name), t.identifier("defaultProps")), false)); if (defaultProps instanceof _index.ObjectValue) { return defaultProps; } } return null; } function evaluateJSXChildren(children, strictCode, env, realm) { if (children.length === 0) { return null; } if (children.length === 1) { var singleChild = evaluateJSXValue(children[0], strictCode, env, realm); if (singleChild instanceof _index.StringValue) { var text = cleanJSXElementLiteralChild(singleChild.value); if (text !== null) { singleChild.value = text; } } return singleChild; } var array = _singletons.Create.ArrayCreate(realm, 0); var dynamicChildrenLength = children.length; var dynamicIterator = 0; var lastChildValue = null; for (var i = 0; i < children.length; i++) { var value = evaluateJSXValue(children[i], strictCode, env, realm); if (value instanceof _index.StringValue) { var _text = cleanJSXElementLiteralChild(value.value); if (_text === null) { dynamicChildrenLength--; // this is a space full of whitespace, so let's proceed continue; } else { value.value = _text; } } lastChildValue = value; _singletons.Create.CreateDataPropertyOrThrow(realm, array, "" + dynamicIterator, value); dynamicIterator++; } if (dynamicChildrenLength === 1) { return lastChildValue; } _singletons.Properties.Set(realm, array, "length", new _index.NumberValue(realm, dynamicChildrenLength), false); return array; } function evaluateJSXAttributes(elementType, astAttributes, astChildren, strictCode, env, realm) { var attributes = new Map(); var children = evaluateJSXChildren(astChildren, strictCode, env, realm); var defaultProps = getDefaultProps(elementType, env, realm); // defaultProps are a bit like default function arguments // if an actual value exists, it should overwrite the default value if (defaultProps !== null) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = defaultProps.properties[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _ref = _step.value; var _ref2 = _slicedToArray(_ref, 1); var key = _ref2[0]; var defaultPropValue = (0, _index2.Get)(realm, defaultProps, key); if (defaultPropValue instanceof _index.Value) { if (key === "children") { if (children === null) { children = defaultPropValue; } } else { attributes.set(key, defaultPropValue); } } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = astAttributes[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var astAttribute = _step2.value; switch (astAttribute.type) { case "JSXAttribute": var name = astAttribute.name, value = astAttribute.value; (0, _invariant2.default)(name.type === "JSXIdentifier", "JSX attribute name type not supported: " + astAttribute.type); attributes.set(name.name, evaluateJSXValue(value, strictCode, env, realm)); break; case "JSXSpreadAttribute": var spreadValue = _singletons.Environment.GetValue(realm, env.evaluate(astAttribute.argument, strictCode)); if (spreadValue instanceof _index.ObjectValue) { var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = spreadValue.properties[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _ref3 = _step3.value; var _ref4 = _slicedToArray(_ref3, 2); var _key = _ref4[0]; var spreadProp = _ref4[1]; if (spreadProp !== undefined && spreadProp.descriptor !== undefined) { var spreadPropValue = spreadProp.descriptor.value; if (spreadPropValue instanceof _index.Value) { if (_key === "children") { children = spreadPropValue; } else { attributes.set(_key, spreadPropValue); } } } } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } else { throw new _errors.FatalError("ObjectValues are the only supported value for JSX Spread Attributes"); } break; default: (0, _invariant2.default)(false, "Unknown JSX attribute type:: " + astAttribute.type); } } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } return { attributes: attributes, children: children }; } function createReactProps(realm, type, attributes, children, env) { var obj = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype); var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = attributes[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var _ref5 = _step4.value; var _ref6 = _slicedToArray(_ref5, 2); var key = _ref6[0]; var value = _ref6[1]; if (typeof key === "string") { if (RESERVED_PROPS.hasOwnProperty(key)) { continue; } _singletons.Create.CreateDataPropertyOrThrow(realm, obj, key, value); } } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } if (children !== null) { _singletons.Create.CreateDataPropertyOrThrow(realm, obj, "children", children); } return obj; } function createReactElement(realm, type, key, ref, props) { var obj = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype); _singletons.Create.CreateDataPropertyOrThrow(realm, obj, "$$typeof", (0, _utils.getReactSymbol)("react.element", realm)); _singletons.Create.CreateDataPropertyOrThrow(realm, obj, "type", type); _singletons.Create.CreateDataPropertyOrThrow(realm, obj, "key", key); _singletons.Create.CreateDataPropertyOrThrow(realm, obj, "ref", ref); _singletons.Create.CreateDataPropertyOrThrow(realm, obj, "props", props); _singletons.Create.CreateDataPropertyOrThrow(realm, obj, "_owner", realm.intrinsics.null); return obj; } //# sourceMappingURL=JSXElement.js.map