BlockNode.js (6095B)
1 "use strict"; 2 3 Object.defineProperty(exports, "__esModule", { 4 value: true 5 }); 6 exports.createBlockNode = void 0; 7 8 var _is = require("../../utils/is.js"); 9 10 var _array = require("../../utils/array.js"); 11 12 var _factory = require("../../utils/factory.js"); 13 14 var name = 'BlockNode'; 15 var dependencies = ['ResultSet', 'Node']; 16 var createBlockNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) { 17 var ResultSet = _ref.ResultSet, 18 Node = _ref.Node; 19 20 /** 21 * @constructor BlockNode 22 * @extends {Node} 23 * Holds a set with blocks 24 * @param {Array.<{node: Node} | {node: Node, visible: boolean}>} blocks 25 * An array with blocks, where a block is constructed as an Object 26 * with properties block, which is a Node, and visible, which is 27 * a boolean. The property visible is optional and is true by default 28 */ 29 function BlockNode(blocks) { 30 if (!(this instanceof BlockNode)) { 31 throw new SyntaxError('Constructor must be called with the new operator'); 32 } // validate input, copy blocks 33 34 35 if (!Array.isArray(blocks)) throw new Error('Array expected'); 36 this.blocks = blocks.map(function (block) { 37 var node = block && block.node; 38 var visible = block && block.visible !== undefined ? block.visible : true; 39 if (!(0, _is.isNode)(node)) throw new TypeError('Property "node" must be a Node'); 40 if (typeof visible !== 'boolean') throw new TypeError('Property "visible" must be a boolean'); 41 return { 42 node: node, 43 visible: visible 44 }; 45 }); 46 } 47 48 BlockNode.prototype = new Node(); 49 BlockNode.prototype.type = 'BlockNode'; 50 BlockNode.prototype.isBlockNode = true; 51 /** 52 * Compile a node into a JavaScript function. 53 * This basically pre-calculates as much as possible and only leaves open 54 * calculations which depend on a dynamic scope with variables. 55 * @param {Object} math Math.js namespace with functions and constants. 56 * @param {Object} argNames An object with argument names as key and `true` 57 * as value. Used in the SymbolNode to optimize 58 * for arguments from user assigned functions 59 * (see FunctionAssignmentNode) or special symbols 60 * like `end` (see IndexNode). 61 * @return {function} Returns a function which can be called like: 62 * evalNode(scope: Object, args: Object, context: *) 63 */ 64 65 BlockNode.prototype._compile = function (math, argNames) { 66 var evalBlocks = (0, _array.map)(this.blocks, function (block) { 67 return { 68 evaluate: block.node._compile(math, argNames), 69 visible: block.visible 70 }; 71 }); 72 return function evalBlockNodes(scope, args, context) { 73 var results = []; 74 (0, _array.forEach)(evalBlocks, function evalBlockNode(block) { 75 var result = block.evaluate(scope, args, context); 76 77 if (block.visible) { 78 results.push(result); 79 } 80 }); 81 return new ResultSet(results); 82 }; 83 }; 84 /** 85 * Execute a callback for each of the child blocks of this node 86 * @param {function(child: Node, path: string, parent: Node)} callback 87 */ 88 89 90 BlockNode.prototype.forEach = function (callback) { 91 for (var i = 0; i < this.blocks.length; i++) { 92 callback(this.blocks[i].node, 'blocks[' + i + '].node', this); 93 } 94 }; 95 /** 96 * Create a new BlockNode having it's childs be the results of calling 97 * the provided callback function for each of the childs of the original node. 98 * @param {function(child: Node, path: string, parent: Node): Node} callback 99 * @returns {BlockNode} Returns a transformed copy of the node 100 */ 101 102 103 BlockNode.prototype.map = function (callback) { 104 var blocks = []; 105 106 for (var i = 0; i < this.blocks.length; i++) { 107 var block = this.blocks[i]; 108 109 var node = this._ifNode(callback(block.node, 'blocks[' + i + '].node', this)); 110 111 blocks[i] = { 112 node: node, 113 visible: block.visible 114 }; 115 } 116 117 return new BlockNode(blocks); 118 }; 119 /** 120 * Create a clone of this node, a shallow copy 121 * @return {BlockNode} 122 */ 123 124 125 BlockNode.prototype.clone = function () { 126 var blocks = this.blocks.map(function (block) { 127 return { 128 node: block.node, 129 visible: block.visible 130 }; 131 }); 132 return new BlockNode(blocks); 133 }; 134 /** 135 * Get string representation 136 * @param {Object} options 137 * @return {string} str 138 * @override 139 */ 140 141 142 BlockNode.prototype._toString = function (options) { 143 return this.blocks.map(function (param) { 144 return param.node.toString(options) + (param.visible ? '' : ';'); 145 }).join('\n'); 146 }; 147 /** 148 * Get a JSON representation of the node 149 * @returns {Object} 150 */ 151 152 153 BlockNode.prototype.toJSON = function () { 154 return { 155 mathjs: 'BlockNode', 156 blocks: this.blocks 157 }; 158 }; 159 /** 160 * Instantiate an BlockNode from its JSON representation 161 * @param {Object} json An object structured like 162 * `{"mathjs": "BlockNode", blocks: [{node: ..., visible: false}, ...]}`, 163 * where mathjs is optional 164 * @returns {BlockNode} 165 */ 166 167 168 BlockNode.fromJSON = function (json) { 169 return new BlockNode(json.blocks); 170 }; 171 /** 172 * Get HTML representation 173 * @param {Object} options 174 * @return {string} str 175 * @override 176 */ 177 178 179 BlockNode.prototype.toHTML = function (options) { 180 return this.blocks.map(function (param) { 181 return param.node.toHTML(options) + (param.visible ? '' : '<span class="math-separator">;</span>'); 182 }).join('<span class="math-separator"><br /></span>'); 183 }; 184 /** 185 * Get LaTeX representation 186 * @param {Object} options 187 * @return {string} str 188 */ 189 190 191 BlockNode.prototype._toTex = function (options) { 192 return this.blocks.map(function (param) { 193 return param.node.toTex(options) + (param.visible ? '' : ';'); 194 }).join('\\;\\;\n'); 195 }; 196 197 return BlockNode; 198 }, { 199 isClass: true, 200 isNode: true 201 }); 202 exports.createBlockNode = createBlockNode;