about summary refs log tree commit diff stats
path: root/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'frontend')
-rw-r--r--frontend/static/search.js31
-rw-r--r--frontend/templates/blocks/options.gotmpl112
-rw-r--r--frontend/templates/blocks/search.gotmpl17
-rw-r--r--frontend/templates/index.gotmpl13
4 files changed, 102 insertions, 71 deletions
diff --git a/frontend/static/search.js b/frontend/static/search.js
index f034fe1..60fa30d 100644
--- a/frontend/static/search.js
+++ b/frontend/static/search.js
@@ -1,5 +1,10 @@
 const search = document.getElementById("search");
-const results = document.getElementById("results");
+let results = document.getElementById("results");
+
+const range = new Range();
+range.setStartAfter(search);
+range.setEndAfter(search.parentNode.lastChild);
+
 let state = history.state || {
   url: new URL(location).toJSON(),
   opened: [],
@@ -24,7 +29,7 @@ function detailsToggled(ev) {
   state.url = nextURL.toJSON();
   history.replaceState(state, "", nextURL);
 }
-function addToggleEventListeners() {
+function addToggleEventListeners(results) {
   results.querySelectorAll("details").forEach((details) =>
     // toggle event doesn't bubble :(
     details.addEventListener("toggle", detailsToggled, { passive: true }),
@@ -49,18 +54,25 @@ search.addEventListener("submit", function (ev) {
       }
     })
     .then(function (html) {
-      results.innerHTML =
-        escapePolicy !== null ? escapePolicy.createHTML(html) : html;
-      addToggleEventListeners();
+      const fragment = range.createContextualFragment(
+        escapePolicy !== null ? escapePolicy.createHTML(html) : html,
+      );
+      const results = fragment.firstElementChild;
+      range.deleteContents();
+      range.insertNode(results);
+      addToggleEventListeners(results);
     })
     .catch(function (error) {
-      results.innerText = error.message;
+      range.deleteContents();
+      range.insertNode(new Text(error.message));
       console.error("fetch failed", error);
     });
   ev.preventDefault();
 });
 
-addToggleEventListeners();
+if (results !== null) {
+  addToggleEventListeners(results);
+}
 
 if (state.opened.length > 0) {
   state.opened.forEach((id) =>
@@ -71,7 +83,8 @@ if (state.opened.length > 0) {
 }
 
 addEventListener("popstate", function (ev) {
-  if (ev.state == null || ev.state.url.pathname == "/") {
-    results.replaceChildren();
+  if (ev.state == null || ev.state.url.pathname.startsWith("/search/")) {
+    range.deleteContents();
+    search.reset();
   }
 });
diff --git a/frontend/templates/blocks/options.gotmpl b/frontend/templates/blocks/options.gotmpl
index 2f9d88a..e39d60c 100644
--- a/frontend/templates/blocks/options.gotmpl
+++ b/frontend/templates/blocks/options.gotmpl
@@ -1,59 +1,61 @@
-{{ template "results" . }}
-{{ define "results" }}
-  {{- with .Results }}
-    {{- range .Results }}
-      <details id="{{ .Option }}">
-        <summary>
-          {{ .Option }}
-        </summary>
-        <p>
-          {{ markdown .Description }}
-        </p>
-        <dl>
-          {{- with .Type }}
-            <dt>Type</dt>
-            <dd><code>{{ . }}</code></dd>
-          {{- end }}
-          {{- with .Default }}
-            {{- if or .Text .Markdown }}
-              <dt>Default</dt>
-              <dd>
-                {{- if .Markdown }}
-                  {{ markdown .Markdown }}
-                {{- else }}
-                  <pre><code>{{ .Text }}</code></pre>
-                {{- end }}
-              </dd>
+{{- template "results" .Results -}}
+{{- define "results" }}
+  <div id="results">
+    {{- with . }}
+      {{- range .Results }}
+        <details id="{{ .Option }}">
+          <summary>
+            {{ .Option }}
+          </summary>
+          <p>
+            {{ markdown .Description }}
+          </p>
+          <dl>
+            {{- with .Type }}
+              <dt>Type</dt>
+              <dd><code>{{ . }}</code></dd>
             {{- end }}
-          {{- end }}
-          {{- with .Example }}
-            {{- if or .Text .Markdown }}
-              <dt>Example</dt>
-              <dd>
-                {{- if .Markdown }}
-                  {{ markdown .Markdown }}
-                {{- else }}
-                  <pre><code>{{ .Text }}</code></pre>
-                {{- end }}
-              </dd>
+            {{- with .Default }}
+              {{- if or .Text .Markdown }}
+                <dt>Default</dt>
+                <dd>
+                  {{- if .Markdown }}
+                    {{ markdown .Markdown }}
+                  {{- else }}
+                    <pre><code>{{ .Text }}</code></pre>
+                  {{- end }}
+                </dd>
+              {{- end }}
             {{- end }}
-          {{- end }}
-          {{- with .RelatedPackages }}
-            <dt>Related Packages</dt>
-            <dd>{{ . }}</dd>
-          {{- end }}
-          {{- with .Declarations }}
-            <dt>Declared</dt>
-            {{- range . }}
-              <dd>
-                <a href="{{ .URL }}">{{ .Name }}</a>
-              </dd>
+            {{- with .Example }}
+              {{- if or .Text .Markdown }}
+                <dt>Example</dt>
+                <dd>
+                  {{- if .Markdown }}
+                    {{ markdown .Markdown }}
+                  {{- else }}
+                    <pre><code>{{ .Text }}</code></pre>
+                  {{- end }}
+                </dd>
+              {{- end }}
             {{- end }}
-          {{- end }}
-        </dl>
-      </details>
-    {{- else }}
-      Nothing found
+            {{- with .RelatedPackages }}
+              <dt>Related Packages</dt>
+              <dd>{{ . }}</dd>
+            {{- end }}
+            {{- with .Declarations }}
+              <dt>Declared</dt>
+              {{- range . }}
+                <dd>
+                  <a href="{{ .URL }}">{{ .Name }}</a>
+                </dd>
+              {{- end }}
+            {{- end }}
+          </dl>
+        </details>
+      {{- else }}
+        Nothing found
+      {{- end }}
     {{- end }}
-  {{- end }}
-{{ end }}
+  </div>
+{{- end }}
diff --git a/frontend/templates/blocks/search.gotmpl b/frontend/templates/blocks/search.gotmpl
new file mode 100644
index 0000000..5482e6b
--- /dev/null
+++ b/frontend/templates/blocks/search.gotmpl
@@ -0,0 +1,17 @@
+{{- template "main" . }}
+{{- template "js" . }}
+
+{{- define "main" }}
+  <label for="query">Search</label>
+  <form id="search" action="/options/results">
+    <input id="query" name="query" type="search" value="{{ .Query }}" />
+    <button>Search</button>
+  </form>
+  {{- with .Results }}
+    {{ block "results" . }}{{ end }}
+  {{- end }}
+{{- end }}
+
+{{- define "js" }}
+  <script src="/static/search.js" defer></script>
+{{- end }}
diff --git a/frontend/templates/index.gotmpl b/frontend/templates/index.gotmpl
index d5046e1..3c2840a 100644
--- a/frontend/templates/index.gotmpl
+++ b/frontend/templates/index.gotmpl
@@ -13,18 +13,17 @@
       <p>Search Nix Packages and options from NixOS, Darwin and Home-Manager</p>
       <nav>
         <a href="/">Home</a>
+        <a href="/search/nixos">NixOS Options</a>
       </nav>
     </header>
     <main>
-      <label for="query">Search </label>
-      <form id="search" action="/options/results">
-        <input id="query" name="query" type="search" value="{{ .Query }}" />
-        <button>Search</button>
-      </form>
-      <div id="results">{{ block "results" . }}{{ end }}</div>
+      {{ block "main" . }}
+        <p>Hello!</p>
+      {{ end }}
     </main>
     <footer>Made by <a href="https://alanpearce.eu">Alan Pearce</a></footer>
-    <script src="/static/search.js" defer></script>
+    {{ block "js" . }}
+    {{ end }}
     {{ .LiveReload }}
   </body>
 </html>