diff --git a/packages/cli/src/commands/make-site.tsx b/packages/cli/src/commands/make-site.tsx index 2b7313d..77b118a 100644 --- a/packages/cli/src/commands/make-site.tsx +++ b/packages/cli/src/commands/make-site.tsx @@ -1,5 +1,5 @@ import { RenderContext } from "@rdf-toolkit/explorer-views/context"; -import renderHTML, { HtmlContent } from "@rdf-toolkit/explorer-views/jsx/html"; +import renderHTML, { HtmlContent, HtmlElement } from "@rdf-toolkit/explorer-views/jsx/html"; import renderMain from "@rdf-toolkit/explorer-views/pages/main"; import renderNavigation from "@rdf-toolkit/explorer-views/pages/navigation"; import renderFooter from "@rdf-toolkit/explorer-views/sections/footer"; @@ -188,22 +188,64 @@ function renderPage(iri: string, context: Website, links: HtmlContent, scripts: const main = renderMain(subject, iri in context.documents ? context.documents[iri] : null, context); - return - - - {title} – {context.title} - {links} - {scripts} - - - -
- {main} -
- - ; + // from the context, get the IRI + const iri_class: Class | undefined = context.schema.classes.get(subject); + // get all of the parent classes of 'iri_class' by iterating over the 'subClassOf' property. + // Do this recursively until there are no more parent classes. + const reachable_classes: Class[] = []; + function get_reachable_classes(class_: Class) { + reachable_classes.push(class_); + for (const parent_class of class_.subClassOf as IRIOrBlankNode[]) { + // get the class object from the IRI + const defn = context.schema.classes.get(parent_class); + // if it's not null, then call the function recursively + if (defn) { + get_reachable_classes(defn); + } + } + } + if (iri_class) { + get_reachable_classes(iri_class); + } + + + // generate the source for a javascript function which sets the open attribute + // on all
elements in the document if the class is in the 'reachable_classes' array + const script = ` + function set_open() { + const details = document.querySelectorAll("details"); + const reachable_classes = [${reachable_classes.map(c => `"${c.id.value}"`).join(", ")}]; + for (const detail of details) { + const iri = detail.getAttribute("iri"); + console.log(iri); + if (reachable_classes.includes(iri)) { + detail.open = true; + } + } + } + document.addEventListener("DOMContentLoaded", set_open); + `; + + // Render the HTML + return ( + + + + {title} – {context.title} + {links} + {scripts} + + + + +
+ {main} +
+ + + ); } function resolveHref(url: string, base: string): string { diff --git a/packages/explorer-views/src/components/treeview.tsx b/packages/explorer-views/src/components/treeview.tsx index e3b87e5..c84d2e4 100644 --- a/packages/explorer-views/src/components/treeview.tsx +++ b/packages/explorer-views/src/components/treeview.tsx @@ -1,8 +1,10 @@ import { Ix } from "@rdf-toolkit/iterable"; +import { IRI, IRIOrBlankNode } from "@rdf-toolkit/rdf/terms"; import { HtmlContent } from "../jsx/html.js"; import "./treeview.css"; export interface TreeNode { + readonly id: IRIOrBlankNode; readonly label: HtmlContent; readonly children?: Iterable; readonly open?: boolean; @@ -13,7 +15,7 @@ function renderNode(node: TreeNode, depth: number): HtmlContent { .map(child => renderNode(child, node.open ? 1 : depth + 1)) .wrap(children =>
  • -
    3}> +
    3} iri={node.id.value}> {node.label} {depth >= 9 ? "\u2026" :
      {children}
    }
    diff --git a/packages/explorer-views/src/jsx/html.ts b/packages/explorer-views/src/jsx/html.ts index 521682d..758c272 100644 --- a/packages/explorer-views/src/jsx/html.ts +++ b/packages/explorer-views/src/jsx/html.ts @@ -150,6 +150,10 @@ export default function render(content: HtmlContent): string { } return result; } + // if content is a script tag, and no 'src' attribute is provided, render the content as a script tag + else if (content && content.type === "script" && !content.props.src) { + return ""; + } else if (content) { let result = "<" + content.type + renderAttributes(content.props) + ">"; if (!(content.type in noEndTag)) { diff --git a/packages/explorer-views/src/jsx/jsx-runtime.ts b/packages/explorer-views/src/jsx/jsx-runtime.ts index a5a3ad7..2007f14 100644 --- a/packages/explorer-views/src/jsx/jsx-runtime.ts +++ b/packages/explorer-views/src/jsx/jsx-runtime.ts @@ -371,6 +371,7 @@ declare global { details: GlobalAttributes & { open?: boolean; + iri?: string; }; summary: GlobalAttributes; diff --git a/packages/explorer-views/src/pages/navigation.tsx b/packages/explorer-views/src/pages/navigation.tsx index 6ca4065..746cbb6 100644 --- a/packages/explorer-views/src/pages/navigation.tsx +++ b/packages/explorer-views/src/pages/navigation.tsx @@ -11,14 +11,14 @@ import "./navigation.css"; function createTree(items: Iterable, parents: (item: T) => Iterable, context: RenderContext, rootIRIs: Iterable | null, options?: RenderOptions): TreeNode[] { const roots: TreeNode[] = []; - const tree: { [P in string]: { readonly label: HtmlContent; readonly children: TreeNode[], readonly open: boolean } } = {}; + const tree: { [P in string]: { readonly id: IRIOrBlankNode, readonly label: HtmlContent; readonly children: TreeNode[], readonly open: boolean } } = {}; for (const item of items) { if (IRI.is(item.id)) { - const node = tree[item.id.value] || (tree[item.id.value] = { label: renderRdfTerm(item.id, context, options), children: [], open: item.id === Rdfs.Resource || item.id === Owl.Thing }); + const node = tree[item.id.value] || (tree[item.id.value] = { id: item.id, label: renderRdfTerm(item.id, context, options), children: [], open: item.id === Rdfs.Resource || item.id === Owl.Thing }); let hasParents = false; for (const parent of parents(item)) { - (tree[parent.value] || (tree[parent.value] = { label: renderRdfTerm(parent, context, options), children: [], open: parent === Rdfs.Resource || parent === Owl.Thing })).children.push(node); + (tree[parent.value] || (tree[parent.value] = { id: parent, label: renderRdfTerm(parent, context, options), children: [], open: parent === Rdfs.Resource || parent === Owl.Thing })).children.push(node); hasParents = true; } if (!hasParents) { @@ -73,7 +73,7 @@ export default function render(title: string | undefined, context: RenderContext { id: "navigation-files", label: "Files", - content: renderTreeView(Object.keys(context.documents).sort().map(x => ({ label: renderRdfTerm(IRI.create(x), context, { rawIRIs: true, hideError: true }) }))) + content: renderTreeView(Object.keys(context.documents).sort().map(x => ({ id: IRI.create(x), label: renderRdfTerm(IRI.create(x), context, { rawIRIs: true, hideError: true }) }))) }, ]) }