Fix some bugs in how we use unist

master
Sir Robert Burbridge 2023-11-29 15:13:17 -05:00
parent 9c15911e3a
commit 1f4e4cef51
3 changed files with 36 additions and 33 deletions

19
package-lock.json generated
View File

@ -1,14 +1,15 @@
{ {
"name": "@thefarce/loom", "name": "@thefarce/loom",
"version": "0.0.2", "version": "0.1.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@thefarce/loom", "name": "@thefarce/loom",
"version": "0.0.2", "version": "0.1.0",
"dependencies": { "dependencies": {
"unist-util-is": "^6.0.0", "unist-util-is": "^6.0.0",
"unist-util-visit": "^5.0.0",
"unist-util-visit-parents": "^6.0.1" "unist-util-visit-parents": "^6.0.1"
}, },
"devDependencies": { "devDependencies": {
@ -4527,6 +4528,20 @@
"url": "https://opencollective.com/unified" "url": "https://opencollective.com/unified"
} }
}, },
"node_modules/unist-util-visit": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
"integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
"dependencies": {
"@types/unist": "^3.0.0",
"unist-util-is": "^6.0.0",
"unist-util-visit-parents": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-visit-parents": { "node_modules/unist-util-visit-parents": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",

View File

@ -1,6 +1,6 @@
{ {
"name": "@thefarce/loom", "name": "@thefarce/loom",
"version": "0.1.0", "version": "0.1.1",
"description": "A module for weaving form data with content data", "description": "A module for weaving form data with content data",
"type": "module", "type": "module",
"main": "index.mjs", "main": "index.mjs",
@ -16,6 +16,7 @@
}, },
"dependencies": { "dependencies": {
"unist-util-is": "^6.0.0", "unist-util-is": "^6.0.0",
"unist-util-visit": "^5.0.0",
"unist-util-visit-parents": "^6.0.1" "unist-util-visit-parents": "^6.0.1"
} }
} }

View File

@ -4,7 +4,7 @@
* (ASTs). * (ASTs).
*/ */
import { visitParents } from 'unist-util-visit-parents'; import { visit, SKIP } from 'unist-util-visit';
import { isAstNode } from './util.mjs'; import { isAstNode } from './util.mjs';
import { is } from 'unist-util-is'; import { is } from 'unist-util-is';
@ -25,7 +25,10 @@ export function transform (ast, ...transformers) {
// AST and stop processing it. If the function returns an AST node, // AST and stop processing it. If the function returns an AST node,
// replace the node with that AST node and continue processing with the // replace the node with that AST node and continue processing with the
// new node. // new node.
visitParents(tree, (node, ancestors) => { visit(tree, (node, index, parent) => {
let replaced = false;
let removed = false;
let transformed = transformers.reduce((workingNode, transformer) => { let transformed = transformers.reduce((workingNode, transformer) => {
// If the current node is null, just skip any further processing. // If the current node is null, just skip any further processing.
if (workingNode === null) { if (workingNode === null) {
@ -35,10 +38,11 @@ export function transform (ast, ...transformers) {
// Process the working node through the current function. Make sure // Process the working node through the current function. Make sure
// the transformer function knows not only the node but also its // the transformer function knows not only the node but also its
// ancestors. // ancestors.
let result = transformer(workingNode, ancestors); let result = transformer(workingNode);
// If the function returned null, just skip any further processing. // If the function returned null, just skip any further processing.
if (result === null) { if (result === null) {
removed = true;
return null; return null;
} }
// If the function returned 'undefined', this means that there's no // If the function returned 'undefined', this means that there's no
@ -51,6 +55,7 @@ export function transform (ast, ...transformers) {
// If the function returned an AST node, we replace the working node // If the function returned an AST node, we replace the working node
// with that AST node and continue processing with the new node. // with that AST node and continue processing with the new node.
else if (isAstNode(result)) { else if (isAstNode(result)) {
replaced = true;
return result; return result;
} }
@ -58,37 +63,19 @@ export function transform (ast, ...transformers) {
throw new Error(`Invalid transformer result: ${JSON.stringify(result)}`); throw new Error(`Invalid transformer result: ${JSON.stringify(result)}`);
}, node); }, node);
let parent = ancestors[ancestors.length - 1]; // If we need to replace the node, do it here.
if (replaced && transformed && parent) {
if (!parent) { parent.children.splice(index, 1, transformed);
return;
} }
// Loop through the first most recent ancestor and replace the current if (removed && parent) {
// node with the transformed node. If transformed is null, just delete
// the current node.
if (transformed === null) {
let index = -1;
parent.children.forEach((child, i) => {
if (is(child, node)) {
index = i;
}
})
parent.children.splice(index, 1); parent.children.splice(index, 1);
// This is special magick required by unist. It hints to the visit
// function that we removed this node from the tree, so skip it when
// walking further..
return [SKIP, index];
} }
// If the transformed node is the same as the current node, do nothing.
else if (is(node, transformed)) {
// do nothing
}
// Finally, replace the current node with the transformed node.
else {
parent.children.forEach((child, index) => {
if (is(child, node)) {
parent.children[index] = transformed;
}
});
}
}); });
return tree; return tree;