UNPKG

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