UNPKG

idyll-ast

Version:
1,025 lines (844 loc) 38.7 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _typeof = require('@babel/runtime/helpers/typeof'); var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties'); var _defineProperty = require('@babel/runtime/helpers/defineProperty'); var _createClass = require('@babel/runtime/helpers/createClass'); var _classCallCheck = require('@babel/runtime/helpers/classCallCheck'); var _inherits = require('@babel/runtime/helpers/inherits'); var _possibleConstructorReturn = require('@babel/runtime/helpers/possibleConstructorReturn'); var _getPrototypeOf = require('@babel/runtime/helpers/getPrototypeOf'); var _wrapNativeSuper = require('@babel/runtime/helpers/wrapNativeSuper'); var Ajv = require('ajv'); var htmlTags = require('html-tags'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof); var _objectWithoutProperties__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutProperties); var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty); var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass); var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck); var _inherits__default = /*#__PURE__*/_interopDefaultLegacy(_inherits); var _possibleConstructorReturn__default = /*#__PURE__*/_interopDefaultLegacy(_possibleConstructorReturn); var _getPrototypeOf__default = /*#__PURE__*/_interopDefaultLegacy(_getPrototypeOf); var _wrapNativeSuper__default = /*#__PURE__*/_interopDefaultLegacy(_wrapNativeSuper); var Ajv__default = /*#__PURE__*/_interopDefaultLegacy(Ajv); var htmlTags__default = /*#__PURE__*/_interopDefaultLegacy(htmlTags); function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof__default["default"](key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof__default["default"](input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof__default["default"](res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$1(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } // -- Constants ---- /** * Property type string for value-typed properties. */ var VALUE = 'value'; /** * Property type string for variable-typed properties. */ var VARIABLE = 'variable'; /** * Property type string for expression-typed properties. */ var EXPRESSION = 'expression'; /** * Node type string for component nodes. */ var COMPONENT = 'component'; /** * Node type string for text nodes. */ var TEXTNODE = 'textnode'; /** * Node type string for var nodes. */ var VAR = 'var'; /** * Node type string for derived nodes. */ var DERIVED = 'derived'; /** * Node type string for data nodes. */ var DATA = 'data'; /** * Node type string for meta nodes. */ var META = 'meta'; // -- AST Nodes ---- /** * Create a new AST node. * @param {string} name Name of the node. * @param {string} type Type of the node. * @param {object} props Properties of the node. * @param {object[]} children Children of the node. * @return {object} A new AST node. */ function createNode(name, type) { var props = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var children = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; var node = { type: type, name: name }; if (props) { node.properties = _objectSpread$1({}, props); } if (children) { node.children = Array.from(children); } return node; } /** * Create a new component-typed node. * @param {string} name Name of the node. * @param {object[]} props Properties of the node. * @param {object[]} children Children of the node. * @return {object} A new component node. */ function createComponentNode(name) { var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var children = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; return createNode(name, COMPONENT, props, children); } /** * Create a new text node. * @param {string} value Text content on the node. * @return {object} A new text node. */ function createTextNode(value) { // typeCheckString(value, 'value'); return { type: TEXTNODE, value: value }; } /** * Test if a node is a text node. * @param {object} node The AST node. * @return {boolean} True if the node is a text node, false otherwise. */ function isTextNode(node) { return node.type === TEXTNODE; } /** * Test if a node is a component node. * @param {object} node The AST node. * @return {boolean} True if the node is a component node, false otherwise. */ function isComponentNode(node) { return node.type === COMPONENT; } /** * Test if a node is a variable node, one of 'var', 'derived', or 'data'. * @param {object} node The AST node. * @return {boolean} True if the node is a variable node, false otherwise. */ function isVariableNode(node) { return node.type === VAR || node.type === DERIVED || node.type === DATA; } /** * Test if a node is a meta node. * @param {object} node The AST node. * @return {boolean} True if the node is a mate node, false otherwise. */ function isMetaNode(node) { return node.type === META; } /** * Get the name of an AST node. If the node is a component, returns * the component name, otherwise returns the node type. * @param {object} node The AST node. * @return {string} The name of the node, or null if not defined. */ function getNodeName(node) { return isComponentNode(node) ? node.name : node.type; } /** * Get the type of an AST node. * @param {object} node The AST node. * @return {string} The type of the node, or null if not defined. */ function getNodeType(node) { return node.type || null; } // -- AST Node Children ---- /** * Test if an AST node has any child nodes. * @param {*} node An AST node. * @returns {boolean} True if the node has children, false otherwise. */ function hasChildren(node) { return node.children ? node.children.length > 0 : false; } /** * Retrieve the children nodes of a parent node. * This method returns a direct reference to an underlying child * array. Callers should take care not to modify the returned array. * @param {object} node The parent node. * @return {object[]} The children of the node, or an empty array if none. */ function getChildren(node) { return node.children || []; } /** * Sets the child nodes of an AST node. * @param {object} node The parent node. * @param {object[]} children The children nodes to set. * @return {object} The modified AST node. */ function setChildren(node, children) { // typeCheckArray(children, 'children'); node.children = children; return node; } /** * Append a child node to a parent node. * @param {object} node The parent AST node. * @param {object} child The child AST node to append. * @return {object} A modifed AST node. */ function appendChild(node, child) { return appendChildren(node, [child]); } /** * Append multiple child nodes to a parent node. * @param {object} node The parent AST node. * @param {object[]} children The children AST nodes to append. * @return {object} A modified AST node. */ function appendChildren(node, children) { // typeCheckArray(children, 'children'); var base = node.children || []; node.children = base.concat(children); return node; } /** * Prepend a child node to a parent node. * @param {object} node The parent AST node. * @param {object} child The child AST node to prepend. * @return {object} A modifed AST node. */ function prependChild(node, child) { return prependChildren(node, [child]); } /** * Prepend multiple child nodes to a parent node. * @param {object} node The parent AST node. * @param {object[]} children The children AST nodes to prepend. * @return {object} A modified AST node. */ function prependChildren(node, children) { // typeCheckArray(children, 'children'); node.children = children.concat(node.children || []); return node; } /** * Filter child nodes, retaining only node that match the filter predicate. * @param {object} node A parent AST node. * @param {function(object): boolean} predicate Filter function for child nodes. * @return {object} The modified parent node. */ function filterChildren(node, predicate) { if (hasChildren(node)) { node.children = node.children.filter(predicate); } return node; } /** * Modify child nodes by applying a map function to each. The results of the * map function become the new child nodes. * @param {object} node A parent AST node. * @param {function} mapFunc Map function applied to child nodes. * @return {object} The modified parent node. */ function mapChildren(node, mapFunc) { if (hasChildren(node)) { node.children = node.children.map(mapFunc); } return node; } // -- AST Node Properties ---- function hasKeys(object) { for (var key in object) { return true; } return false; } /** * Tests if an AST node has any defined properties. * @param {*} node The AST node. * @returns {boolean} True is the node has properties, false otherwise. */ function hasProperties(node) { return hasKeys(node.properties); } /** * Retrieves the properties object for an AST node. * @param {object} node The AST node. * @returns {object} The properties object, or null if none. */ function getProperties(node) { return node.properties || null; } /** * Add a set of properties to an AST node. Any existing * properties with matching keys will be overwritten. * @param {object} node The AST node. * @param {object} properties A properties object. Object keys are * property names, object values must be property data objects. * @returns {object} The modified AST node. */ function setProperties(node, properties) { for (var key in properties) { setProperty(node, key, properties[key]); } return node; } /** * Remove all properties from an AST node. * @param {object} node The AST node. * @returns {object} The modified AST node. */ function clearProperties(node) { delete node.properties; return node; } /** * Retrieves an array of property keys for a node. * @param {object} node The AST node. * @return {string[]} The property keys, or an empty array if none. */ function getPropertyKeys(node) { return Object.keys(node.properties || {}); } /** * Retrieves the property type for a node property. * @param {object} node The AST node. * @param {string} key The property key. * @return {string} The property type, or null if the property is not defined. */ function getPropertyType(node, key) { var prop = getProperty(node, key); return prop && prop.type || null; } /** * Retrieves the property value for a node property. * @param {object} node The AST node. * @param {string} key The property key. * @return {string} The property value, or null if the property is not defined. */ function getPropertyValue(node, key) { var prop = getProperty(node, key); return prop && prop.value || null; } /** * Test if a property with the given key is defined on a node. * @param {object} node The AST node. * @param {string} key The property key. * @return {boolean} True if the property is defined, else false. */ function hasProperty(node, key) { return node.properties && node.properties.hasOwnProperty(key) || false; } /** * Retrieves a property of a node given its key. * @param {object} node The AST node. * @param {string} key The property key. * @return {object} The property data, or null if the property does not exist. */ function getProperty(node, key) { return hasProperty(node, key) ? node.properties[key] : null; } /** * Set a property of a node. * @param {object} node The AST node. * @param {string} key The property key. * @param {object} data The property data, should * be an object with type and value properties. * @return {object} The modfied AST node. */ function setProperty(node, key, data) { // TODO: type checking of property data? if (!node.properties) { node.properties = {}; } node.properties[key] = data; return node; } /** * Set a value-typed property of a node. * @param {object} node The AST node. * @param {string} key The property key. * @param {*} value The property value. * @return {object} The modfied AST node. */ function setValueProperty(node, key, value) { return setProperty(node, key, { type: VALUE, value: value }); } /** * Set a variable-typed property of a node. * @param {object} node The AST node. * @param {string} key The property key. * @param {string} value A reactive variable name. * @return {object} The modfied AST node. */ function setVariableProperty(node, key, value) { return setProperty(node, key, { type: VARIABLE, value: value }); } /** * Set an expression-typed property of a node. * @param {object} node The AST node. * @param {string} key The property key. * @param {string} value A JavaScript expression string. * @return {object} The modfied AST node. */ function setExpressionProperty(node, key, value) { return setProperty(node, key, { type: EXPRESSION, value: value }); } /** * Remove a property of a node. * @param {object} node The AST node. * @param {string} key The property key. * @return {object} The modified AST node. */ function removeProperty(node, key) { if (hasProperty(node, key)) { var _node$properties = node.properties; _node$properties[key]; var props = _objectWithoutProperties__default["default"](_node$properties, [key].map(_toPropertyKey)); if (hasKeys(props)) { node.properties = props; } else { delete node.properties; } } return node; } // -- AST Traversal ---- /** * Perform a preorder depth-first traversal of the AST. * @param {object} node The AST node at which to begin the traversal. * @param {function} callack Callback function invoked for each visited node. */ function cloneNode(node) { var clone = _objectSpread$1({}, node); if (clone.properties) { clone.properties = _objectSpread$1({}, clone.properties); } if (clone.children) { clone.children = clone.children.map(function (child) { return cloneNode(child); }); } return clone; } /** * Perform a preorder depth-first traversal of the AST. * @param {object} node The AST node at which to begin the traversal. * @param {function} callack Callback function invoked for each visited node. */ function visitNodes(node, callback) { callback(node); getChildren(node).forEach(function (node) { return visitNodes(node, callback); }); } /** * Retrieve all nodes that match a given predicate function. * @param {object} node The AST node at which to begin searching. * Only this node and its descendants are considered. * @param {function(object): boolean} predicate Filter function to test nodes. * If the predicate returns true, the node is included in the result. * @returns {object[]} An array of AST nodes that match the predicate. */ function queryNodes(node, predicate) { var nodes = []; visitNodes(node, function (n) { if (predicate(n)) { nodes.push(n); } }); return nodes; } /** * Extract the text from all text nodes under an AST node. * @param {object} ast The AST node. * @return {string} The extracted text, concatenated into strings. */ function extractText(node) { var texts = []; visitNodes(node, function (n) { if (isTextNode(n)) { texts.push(n.value); } }); return texts.join(' '); } /** * Remove any descendant nodes that match a given predicate function. * @param {object} node The AST node at which to begin searching. * Only descendants of this node are considered for removal. * @param {function(object): boolean} predicate Filter function to test nodes. * If the predicate returns true, the node is removed from the AST. * @returns {object} The AST node width descendants removed. */ function removeNodes(node, predicate) { if (hasChildren(node)) { node.children = node.children.filter(function (child) { if (predicate(child)) { return false; } else { removeNodes(child, predicate); return true; } }); } return node; } var $schema$1="http://json-schema.org/draft-06/schema#";var title$1="AST Schema V1";var description="Structure of an AST object";var type$1="object";var properties$1={id:{description:"A unique identifier for the current element",type:"integer"},type:{description:"The type category of the element (component/var/derived)",type:"string","enum":["component","var","derived","textnode","data","meta"]},name:{description:"The name of the element",type:"string"},properties:{description:"The properties/attributes of the element",type:"object",patternProperties:{"^\\w+":{description:"Object containing data for the particular property",type:"object",properties:{type:{description:"The evaluation type of the property. Can be value/variable/expression",type:"string","enum":["value","variable","expression"]},value:{description:"Property value",type:["string","number","boolean"]}},additionalProperties:false}}},children:{description:"The children of the element.",type:"array",items:{anyof:[{$ref:"#"},{description:"Structure for a textnode",type:"object",properties:{id:{desceription:"A unique identifier for the current element",id:"integer"},type:{description:"The type category of the element",type:"string","enum":["textnode"]},value:{description:"Text value in the textnode",type:"string"}},required:["type","value"],additionalProperties:false},{description:"Structure for var and derived",type:"object",properties:{id:{desceription:"A unique identifier for the current element",id:"integer"},type:{description:"The type category of the element",type:"string","enum":["var","derived"]},properties:{name:{description:"Name of the variable",type:"object",properties:{type:{type:"string","enum":["value","variable","expression"]},value:{type:"string"}},required:["name","value"],additionalProperties:false},value:{description:"Source for the data",type:"object",properties:{properties:{type:{type:"string","enum":["value","variable","expression"]},value:{type:"string"}}},required:["name","value"],additionalProperties:false}},additionalProperties:false,required:["type","properties"]}},{description:"Structure for data",type:"object",properties:{id:{desceription:"A unique identifier for the current element",id:"integer"},type:{description:"The type category of the element",type:"string","enum":["data"]},properties:{name:{description:"Name of the variable",type:"object",properties:{type:{type:"string","enum":["value","variable","expression"]},value:{type:"string"}},required:["type","value"],additionalProperties:false},source:{description:"Source for the data",type:"object",properties:{properties:{type:{type:"string","enum":["value","variable","expression"]},value:{type:"string"}}},required:["type","value"],additionalProperties:false}},required:["type","properties"]}}]}}};var required=["type"];var schema = {$schema:$schema$1,title:title$1,description:description,type:type$1,properties:properties$1,required:required}; var $schema="http://json-schema.org/draft-06/schema#";var $id="http://json-schema.org/draft-06/schema#";var title="Core schema meta-schema";var definitions={schemaArray:{type:"array",minItems:1,items:{$ref:"#"}},nonNegativeInteger:{type:"integer",minimum:0},nonNegativeIntegerDefault0:{allOf:[{$ref:"#/definitions/nonNegativeInteger"},{"default":0}]},simpleTypes:{"enum":["array","boolean","integer","null","number","object","string"]},stringArray:{type:"array",items:{type:"string"},uniqueItems:true,"default":[]}};var type=["object","boolean"];var properties={$id:{type:"string",format:"uri-reference"},$schema:{type:"string",format:"uri"},$ref:{type:"string",format:"uri-reference"},title:{type:"string"},description:{type:"string"},"default":{},examples:{type:"array",items:{}},multipleOf:{type:"number",exclusiveMinimum:0},maximum:{type:"number"},exclusiveMaximum:{type:"number"},minimum:{type:"number"},exclusiveMinimum:{type:"number"},maxLength:{$ref:"#/definitions/nonNegativeInteger"},minLength:{$ref:"#/definitions/nonNegativeIntegerDefault0"},pattern:{type:"string",format:"regex"},additionalItems:{$ref:"#"},items:{anyOf:[{$ref:"#"},{$ref:"#/definitions/schemaArray"}],"default":{}},maxItems:{$ref:"#/definitions/nonNegativeInteger"},minItems:{$ref:"#/definitions/nonNegativeIntegerDefault0"},uniqueItems:{type:"boolean","default":false},contains:{$ref:"#"},maxProperties:{$ref:"#/definitions/nonNegativeInteger"},minProperties:{$ref:"#/definitions/nonNegativeIntegerDefault0"},required:{$ref:"#/definitions/stringArray"},additionalProperties:{$ref:"#"},definitions:{type:"object",additionalProperties:{$ref:"#"},"default":{}},properties:{type:"object",additionalProperties:{$ref:"#"},"default":{}},patternProperties:{type:"object",additionalProperties:{$ref:"#"},"default":{}},dependencies:{type:"object",additionalProperties:{anyOf:[{$ref:"#"},{$ref:"#/definitions/stringArray"}]}},propertyNames:{$ref:"#"},"const":{},"enum":{type:"array",minItems:1,uniqueItems:true},type:{anyOf:[{$ref:"#/definitions/simpleTypes"},{type:"array",items:{$ref:"#/definitions/simpleTypes"},minItems:1,uniqueItems:true}]},format:{type:"string"},allOf:{$ref:"#/definitions/schemaArray"},anyOf:{$ref:"#/definitions/schemaArray"},oneOf:{$ref:"#/definitions/schemaArray"},not:{$ref:"#"}};var metaSchema = {$schema:$schema,$id:$id,title:title,definitions:definitions,type:type,properties:properties,"default":{}}; function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf__default["default"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default["default"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default["default"](this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } var ajv = new Ajv__default["default"](); ajv.addMetaSchema(metaSchema); var astValidator; var propValidator; var MalformedASTError = /*#__PURE__*/function (_Error) { _inherits__default["default"](MalformedASTError, _Error); var _super = _createSuper(MalformedASTError); function MalformedASTError(msg, errors) { var _this; _classCallCheck__default["default"](this, MalformedASTError); _this = _super.call(this, msg); _this.name = _this.constructor.name; _this.message = msg; _this.stack = new Error(msg).stack; return _this; } return _createClass__default["default"](MalformedASTError); }( /*#__PURE__*/_wrapNativeSuper__default["default"](Error)); /** * Validates if an AST node conforms to the JSON schema. * @param {object} node The AST node. * @throws Error if AST validation fails. */ function validateNode(ast) { if (!astValidator) { astValidator = ajv.compile(schema); } if (!astValidator(ast)) { throw new MalformedASTError('AST node does not match schema: ' + astValidator.errors[0].message); } } /** * Validates if AST node properties conform to the JSON schema. * @param {object} properties An AST node properties object. * @throws Error if AST validation fails. */ function validateProperties(properties) { if (!propValidator) { propValidator = ajv.compile(schema.properties.properties); } if (!propValidator(properties)) { throw new MalformedASTError('AST properties do not match schema: ' + propValidator.errors[0].message); } } /* THIS FILE CONTAINS THE CONVERTER FUNCTIONS FOR THE TWO DIFFERENT TYPES OF AST STRUCTURE. */ /** * This function converts the JSON structured AST (ASTV2) to the array structured * AST (OLD AST) * @param {*} jsonAst * @return Array structred AST */ var convertV2ToV1 = function convertV2ToV1(jsonAst) { var arrayAst = []; if (jsonAst.children) { jsonAst.children.forEach(function (element) { arrayAst.push(convertHelper(element)); }); } return arrayAst; }; /** * Helper function for convert * @param {*} jsonElement * @return array representation of the corresponding jsonElement */ function convertHelper(jsonElement) { var elementArray = []; if (jsonElement.type === 'textnode') { return jsonElement.value; } else if (jsonElement.type === 'var' || jsonElement.type === 'derived') { elementArray = [jsonElement.type]; elementArray.push([['name', ['value', jsonElement.name]], ['value', ['value', jsonElement.value]]]); elementArray.push([]); } else if (jsonElement.type === 'data') { elementArray = ['data']; elementArray.push([['name', ['value', jsonElement.name]], ['source', ['value', jsonElement.source]], ['async', ['value', jsonElement.async]], ['initialValue', ['expression', jsonElement.initialValue]]]); elementArray.push([]); } else { elementArray.push(jsonElement.name); var propertiesArray = []; if ('properties' in jsonElement) { Object.keys(jsonElement.properties).forEach(function (key) { var propertyArray = [key]; propertyArray.push([jsonElement.properties[key].type, jsonElement.properties[key].value]); propertiesArray.push(propertyArray); }); } elementArray.push(propertiesArray); if ('children' in jsonElement) { var childArray = []; jsonElement.children.forEach(function (children) { childArray.push(convertHelper(children)); }); elementArray.push(childArray); } } return elementArray; } /** * This function converts the array structred AST (OLD AST) to the new * JSON structured ast(ASTV2) * @param {*} arrayAst * @return Json structred ast correspoding to the arrayAst. */ var convertV1ToV2 = function convertV1ToV2(arrayAst, injectIds) { var _id = 0; var id = injectIds ? function () { return _id++; } : null; var jsonAst = new Object(); if (id) jsonAst.id = id(); jsonAst.type = 'component'; jsonAst.name = 'div'; jsonAst.children = arrayAst.map(function (element) { return inverseConvertHelper(element, id); }); return jsonAst; }; /** * Helper function for inverseConvert * @param {*} arrayElement * @return JSON representation of the corresponding arrayElement */ function inverseConvertHelper(arrayElement, id) { var elementJson = new Object(); if (id) elementJson.id = id(); if (typeof arrayElement === 'string') { elementJson.type = 'textnode'; elementJson.value = arrayElement; } else if (['var', 'derived', 'data', 'meta'].indexOf(arrayElement[0]) > -1) { elementJson.type = arrayElement[0]; elementJson.properties = {}; arrayElement[1].forEach(function (property) { elementJson.properties[property[0]] = { type: property[1][0], value: property[1][1] }; }); } else { elementJson.type = 'component'; elementJson.name = arrayElement[0]; if (arrayElement[1].length !== 0) { elementJson.properties = {}; arrayElement[1].forEach(function (property) { elementJson.properties[property[0]] = { type: property[1][0], value: property[1][1] }; }); } if (arrayElement[2]) { elementJson.children = arrayElement[2].map(function (element) { return inverseConvertHelper(element, id); }); } } return elementJson; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } /** * Convert an AST to valid Idyll markup. * @param {object} node The AST node. * @return {string} The markup string. */ function toMarkup(node) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { insertFullWidth: false }; var markup = childrenToMarkup(node, 0, node.name === 'p' ? ' ' : '\n', options.insertFullWidth || false).trim(); var cleanedMarkup = markup.replace(/([\]\*\_]) ([,\.\!\?\:\[])/g, '$1$2'); return cleanedMarkup; } function childrenToMarkup(node, depth) { var separator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '\n'; var insertFullWidth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; var markup = ''; var _iterator = _createForOfIteratorHelper(getChildren(node)), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var child = _step.value; markup += separator + nodeToMarkup(child, depth, separator, insertFullWidth); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return markup.replace(/\n\n+/g, '\n\n'); } function nodeToMarkup(node, depth) { var separator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '\n'; var insertFullWidth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; var name = node.name && node.name.toLowerCase() || null; if (name === 'idylleditordroptarget') { return ''; } var markupNodes = ['strong', 'em', 'i', 'b', 'code', 'h1', 'h2', 'h3', 'h4', 'h5', 'a']; // normalize component names if (name && !htmlTags__default["default"].includes(name)) { node.name = node.name.split('-').map(function (s) { return s.charAt(0).toUpperCase() + s.slice(1); }).join(''); name = node.name.toLowerCase(); } switch (node.type) { case 'textnode': return "".concat(' '.repeat(depth)).concat(node.value.trim()); case 'component': if (name === 'textcontainer') { return "\n".concat(childrenToMarkup(node, depth, '\n', false)); } else if (name === 'p' && depth < 1) { return "\n".concat(childrenToMarkup(node, depth, '\n', false).trim(), "\n"); } else if (markupNodes.includes(name)) { switch (name) { case 'strong': case 'b': return "**".concat(childrenToMarkup(node, 0, ' ', false).trim(), "**"); case 'em': case 'i': return "*".concat(childrenToMarkup(node, 0, ' ', false).trim(), "*"); case 'code': return "`".concat(childrenToMarkup(node, 0, ' ', false).trim(), "`"); case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': if (node.children && node.children.length === 1 && node.children[0].type === 'textnode') { return "".concat('#'.repeat(+node.name[1]), " ").concat(childrenToMarkup(node, 0, ' ', false).trim()); } } } if (name === 'pre' && node.children && node.children.length === 1 && node.children[0].name && node.children[0].name.toLowerCase() === 'code') { return "\n```\n".concat(childrenToMarkup(node.children[0], 0, ' ', false).trim(), "\n```\n "); } else if (name === 'pre' && node.children && node.children.length === 1 && node.children[0].type === 'textnode') { return "\n```\n".concat(childrenToMarkup(node, 0, ' ', false).trim(), "\n```"); } var propString = propertiesToString(node, depth, insertFullWidth); if (hasChildren(node)) { if (name === 'a') { return "".concat(' '.repeat(depth), "[").concat(node.name).concat(propString ? "".concat(propString) : '', "]").concat(childrenToMarkup(node, depth + 1, ' ', false).trim(), "[/").concat(node.name, "]"); } return "".concat(' '.repeat(depth), "[").concat(node.name).concat(propString ? "".concat(propString) : '', "]").concat(childrenToMarkup(node, depth + 1, separator, false), "\n").concat(' '.repeat(depth), "[/").concat(node.name, "]"); } return "".concat(' '.repeat(depth), "[").concat(node.name).concat(propString ? "".concat(propString) : '', " /]"); case 'var': case 'derived': case 'data': case 'meta': return "".concat(' '.repeat(depth), "[").concat(node.type).concat(propertiesToString(node, depth, insertFullWidth), " /]"); } } function propertiesToString(node, depth, insertFullWidth) { var props = _objectSpread({}, node.properties); if (insertFullWidth && isComponentNode(node) && node.name.toLowerCase() !== 'textcontainer') { props.fullWidth = { type: 'value', value: true }; } var flatString = Object.keys(props || {}).reduce(function (memo, key) { return memo + " ".concat(key, ":").concat(propertyToString(props[key])); }, ''); if (flatString.length < 60) { return flatString; } return Object.keys(props || {}).reduce(function (memo, key) { return memo + "\n".concat(' '.repeat(depth + 1)).concat(key, ":").concat(propertyToString(props[key])); }, ''); } function propertyToString(property) { switch (property.type) { case VALUE: return JSON.stringify(property.value); case EXPRESSION: return "`".concat(property.value, "`"); case VARIABLE: return property.value; } } exports.COMPONENT = COMPONENT; exports.DATA = DATA; exports.DERIVED = DERIVED; exports.EXPRESSION = EXPRESSION; exports.META = META; exports.TEXTNODE = TEXTNODE; exports.VALUE = VALUE; exports.VAR = VAR; exports.VARIABLE = VARIABLE; exports.appendChild = appendChild; exports.appendChildren = appendChildren; exports.clearProperties = clearProperties; exports.cloneNode = cloneNode; exports.convertV1ToV2 = convertV1ToV2; exports.convertV2ToV1 = convertV2ToV1; exports.createComponentNode = createComponentNode; exports.createNode = createNode; exports.createTextNode = createTextNode; exports.extractText = extractText; exports.filterChildren = filterChildren; exports.getChildren = getChildren; exports.getNodeName = getNodeName; exports.getNodeType = getNodeType; exports.getProperties = getProperties; exports.getProperty = getProperty; exports.getPropertyKeys = getPropertyKeys; exports.getPropertyType = getPropertyType; exports.getPropertyValue = getPropertyValue; exports.hasChildren = hasChildren; exports.hasProperties = hasProperties; exports.hasProperty = hasProperty; exports.isComponentNode = isComponentNode; exports.isMetaNode = isMetaNode; exports.isTextNode = isTextNode; exports.isVariableNode = isVariableNode; exports.mapChildren = mapChildren; exports.prependChild = prependChild; exports.prependChildren = prependChildren; exports.queryNodes = queryNodes; exports.removeNodes = removeNodes; exports.removeProperty = removeProperty; exports.setChildren = setChildren; exports.setExpressionProperty = setExpressionProperty; exports.setProperties = setProperties; exports.setProperty = setProperty; exports.setValueProperty = setValueProperty; exports.setVariableProperty = setVariableProperty; exports.toMarkup = toMarkup; exports.validateNode = validateNode; exports.validateProperties = validateProperties; exports.visitNodes = visitNodes; //# sourceMappingURL=index.js.map