MCPcopy Create free account
hub / github.com/PrairieLearn/PrairieLearn / visitNode

Function visitNode

question-servers/freeform.js:384–461  ·  view source on GitHub ↗
(node)

Source from the content-addressed store, hash-verified

382 const questionElements = new Set([..._.keys(coreElementsCache), ..._.keys(context.course_elements)]);
383
384 const visitNode = async (node) => {
385 if (node.tagName && questionElements.has(node.tagName)) {
386 const elementName = node.tagName;
387 const elementFile = module.exports.getElementController(elementName, context);
388 if (phase === 'render' && !_.includes(renderedElementNames, elementName)) {
389 renderedElementNames.push(elementName);
390 }
391 // We need to wrap it in another node, since only child nodes
392 // are serialized
393 const serializedNode = parse5.serialize({
394 childNodes: [node],
395 });
396 let ret_val, consoleLog;
397 try {
398 [ret_val, consoleLog] = await module.exports.elementFunction(pc, phase, elementName, serializedNode, data, context);
399 } catch (e) {
400 const courseIssue = new Error(`${elementFile}: Error calling ${phase}(): ${e.toString()}`);
401 courseIssue.data = e.data;
402 courseIssue.fatal = true;
403 // We'll catch this and add it to the course issues list
404 throw courseIssue;
405 }
406 if (_.isString(consoleLog) && consoleLog.length > 0) {
407 const courseIssue = new Error(`${elementFile}: output logged on console during ${phase}()`);
408 courseIssue.data = { outputBoth: consoleLog };
409 courseIssue.fatal = false;
410 courseIssues.push(courseIssue);
411 }
412 if (phase == 'render') {
413 if (!_.isString(ret_val)) {
414 const courseIssue = new Error(`${elementFile}: Error calling ${phase}(): return value is not a string`);
415 courseIssue.data = { ret_val };
416 courseIssue.fatal = true;
417 throw courseIssue;
418 }
419 node = parse5.parseFragment(ret_val);
420 } else if (phase == 'file') {
421 // Convert ret_val from base64 back to buffer (this always works,
422 // whether or not ret_val is valid base64)
423 const buf = Buffer.from(ret_val, 'base64');
424 // If the buffer has non-zero length...
425 if (buf.length > 0) {
426 if (fileData.length > 0) {
427 // If fileData already has non-zero length, throw an error
428 const courseIssue = new Error(`${elementFile}: Error calling ${phase}(): attempting to overwrite non-empty fileData`);
429 courseIssue.fatal = true;
430 throw courseIssue;
431 } else {
432 // If not, replace fileData with buffer
433 fileData = buf;
434 }
435 }
436 } else {
437 // the following line is safe because we can't be in multiple copies of this function simultaneously
438 data = ret_val; // eslint-disable-line require-atomic-updates
439 const checkErr = module.exports.checkData(data, origData, phase);
440 if (checkErr) {
441 const courseIssue = new Error(`${elementFile}: Invalid state after ${phase}(): ${checkErr}`);

Callers 1

freeform.jsFile · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected