Use JS to show/hide railroad diagrams based on page width (thanks @hober!)

This commit is contained in:
Eryn Wells 2022-10-21 11:06:13 -07:00
parent 44f11c6792
commit 84c7c714ed
4 changed files with 77 additions and 19 deletions

View file

@ -1,11 +1,4 @@
{{ $id := .Get "id" }}
{{ .Page.Scratch.Set "includes_railroad_diagram" true }}
<div class="centered">
<figure class="railroad-diagram" {{ if $id }}id="{{ $id }}"{{ end }}></figure>
</div>
<script defer type="module">
import { railroadDiagram } from {{ `/scripts/railroad-utils.js` | relURL }};
railroadDiagram(rr => {
{{ .Inner | safeJS }}
}, "{{ $id }}");
</script>
{{- $id := .Get "id" -}}
{{- .Page.Scratch.Set "includes_railroad_diagram" true -}}
<figure class="railroad-diagram" {{ if $id }}id="{{ $id }}"{{ end }}></figure>
{{ .Inner }}

View file

@ -0,0 +1,8 @@
{{- $parentID := .Parent.Get "id" -}}
{{- $narrowOnly := .Get "narrow" }}
<script defer type="module">
import { railroadDiagram } from {{ `/scripts/railroad-utils.js` | relURL }};
railroadDiagram(rr => {
{{ .Inner | safeJS }}
}, "{{ $parentID }}", {{ if $narrowOnly }}true{{ else }}false{{ end }});
</script>

View file

@ -1,6 +1,63 @@
import rr from "./railroad.js";
export function railroadDiagram(builder, elementID) {
const diagram = builder(rr);
diagram.addTo(document.getElementById(elementID));
class RailroadDiagramManager {
constructor() {
this.figures = new Map();
this.isCurrentlyNarrow = undefined;
this.diagramBreakpoint = window.matchMedia("(max-width: 450px)");
this.diagramBreakpoint.addEventListener("change", () => {
this.updateVisiblity();
});
}
add(svg) {
const parent = svg.parentElement;
if (!this.figures.has(parent)) {
this.figures.set(parent, []);
}
this.figures.get(parent).push(svg);
parent.removeChild(svg);
}
updateVisiblity() {
const isNarrow = this.diagramBreakpoint.matches;
if (isNarrow === this.isCurrentlyNarrow) {
return;
}
this.isCurrentlyNarrow = isNarrow;
for (let [figure, svgs] of this.figures.entries()) {
for (let svg of svgs) {
const svgHasNarrowClass = svg.classList.contains("narrow");
if (isNarrow && svgHasNarrowClass)
figure.appendChild(svg);
else if (!isNarrow && !svgHasNarrowClass)
figure.appendChild(svg);
else if (svg.parentElement === figure)
figure.removeChild(svg);
}
}
}
}
let railroadDiagramManager = new RailroadDiagramManager();
export function railroadDiagram(builder, elementID, isNarrow) {
const diagram = builder(rr);
const svg = diagram.addTo(document.getElementById(elementID));
if (isNarrow) {
svg.classList.add("narrow");
}
railroadDiagramManager.add(svg);
}
window.addEventListener("DOMContentLoaded", () => {
railroadDiagramManager.updateVisiblity();
});

View file

@ -9,7 +9,7 @@
svg.railroad-diagram path {
stroke-width: 2;
stroke: var(--foreground-body-color);
stroke: var(--html-color);
fill: none;
}
@ -17,7 +17,7 @@ svg.railroad-diagram text {
font-family: var(--font-family-monospace);
text-anchor: middle;
white-space: pre;
fill: var(--foreground-body-color);
fill: var(--html-color);
}
svg.railroad-diagram text.diagram-text {
@ -42,7 +42,7 @@ svg.railroad-diagram g.non-terminal text {
svg.railroad-diagram rect {
stroke-width: 2;
stroke: var(--foreground-body-color);
stroke: var(--html-color);
fill: var(--rect-fill);
}
@ -54,8 +54,8 @@ svg.railroad-diagram rect.group-box {
svg.railroad-diagram path.diagram-text {
stroke-width: 2;
stroke: var(--foreground-body-color);
fill: var(--background-body-color);
stroke: var(--html-color);
fill: var(--html-background-color);
cursor: help;
}