astro/packages/markdown/remark/src/remark-unwrap.ts
Matthew Phillips fc52321a88
Consolidate hydration scripts into just one (#3571)
* Remove redundant hydration scripts

* Prebuild the island JS

* Fix build

* Updates to tests

* Update more references

* Custom element test now has two classic scripts

* Account for non-default exports

* Restructure hydration directives

* Move nested logic into the island component

* Remove try/catch
2022-06-15 08:50:05 -04:00

44 lines
1.2 KiB
TypeScript

import { SKIP, visit as _visit } from 'unist-util-visit';
// This is a workaround.
// It fixes a compatibility issue between different, incompatible ASTs given by plugins to Unist
const visit = _visit as (
node: any,
type: string,
callback?: (node: any, index: number, parent: any) => any
) => any;
// Remove the wrapping paragraph for <astro-island> islands
export default function remarkUnwrap() {
const astroRootNodes = new Set();
let insideAstroRoot = false;
return (tree: any) => {
// reset state
insideAstroRoot = false;
astroRootNodes.clear();
visit(tree, 'html', (node) => {
if (node.value.indexOf('<astro-island') > -1 && !insideAstroRoot) {
insideAstroRoot = true;
}
if (node.value.indexOf('</astro-island') > -1 && insideAstroRoot) {
insideAstroRoot = false;
}
astroRootNodes.add(node);
});
visit(tree, 'paragraph', (node, index, parent) => {
if (parent && typeof index === 'number' && containsAstroRootNode(node)) {
parent.children.splice(index, 1, ...node.children);
return [SKIP, index];
}
});
};
function containsAstroRootNode(node: any) {
return node.children
.map((child: any) => astroRootNodes.has(child))
.reduce((all: boolean, v: boolean) => (all ? all : v), false);
}
}