commit 9882dee6c3413d794994f0e09ce454f21140cf7b
parent a52fdddf680aeaa4fc21180a749db10aedc85d7b
Author: weetat <wtenison@protonmail.com>
Date: Sun, 6 Apr 2025 17:40:10 +0000
Move fmd rendering to the client
The server no longer renders fmd. It serves the data directory at
/data/, and the home and subject pages fetch their .fmd files and run
them through the WASM interpreter. Drops the fmd Go dependency.
Diffstat:
11 files changed, 72 insertions(+), 249 deletions(-)
diff --git a/go.mod b/go.mod
@@ -1,5 +1,3 @@
module codeberg.org/wtenison/miki
go 1.23.2
-
-require codeberg.org/wtenison/fmd v0.0.0-20250313225030-eaad858f680c
diff --git a/go.sum b/go.sum
@@ -1,2 +0,0 @@
-codeberg.org/wtenison/fmd v0.0.0-20250313225030-eaad858f680c h1:+Qb1bZs+Uxmce7RGiBaic96C6MB23Ow/3G3DHmzxBOU=
-codeberg.org/wtenison/fmd v0.0.0-20250313225030-eaad858f680c/go.mod h1:E5rEefleqTyb7LRaUtJQQO1vMJK3f641ym9lUPWHc30=
diff --git a/src/filesystem/filesystem.go b/src/filesystem/filesystem.go
@@ -11,8 +11,6 @@ var WebGlobalPkg DirectoryPackage
func Init() {
- //// PULL SYSTEM INFO FROM JSON
-
var _fsDataStruct struct {
DataDirectory string `json:"data-directory"`
WebDirectory string `json:"web-directory"`
@@ -27,8 +25,6 @@ func Init() {
log.Printf("INFO:filesystem:Init:Dirs:%v", Dirs)
- //// GET GLOBAL WEB RESOURCES
-
var _err error
WebGlobalPkg, _err = MakeDirectoryPkg(filepath.Join(Dirs["web"], "/global"), SEARCH_DEPTH_INF, "*.html")
if _err != nil {
diff --git a/src/network/routes.go b/src/network/routes.go
@@ -1,15 +1,11 @@
package network
import (
- "bytes"
"log"
"net/http"
- "net/url"
- "os"
"path/filepath"
"text/template"
- fmd "codeberg.org/wtenison/fmd/src/core"
mfs "codeberg.org/wtenison/miki/src/filesystem"
)
@@ -22,6 +18,7 @@ func makeServerRoutes() {
mux = http.NewServeMux()
mux.Handle("/web/", http.StripPrefix("/web/", http.FileServer(http.Dir(mfs.Dirs["web"]))))
+ mux.Handle("/data/", http.StripPrefix("/data/", http.FileServer(http.Dir(mfs.Dirs["data"]))))
mux.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, filepath.Join(mfs.Dirs["web"], "/global/images/favicon.ico"))
@@ -62,19 +59,8 @@ func handlePageHome(w http.ResponseWriter, r *http.Request) {
return
}
- _filePath := filepath.Join(mfs.Dirs["data"], "/fmd/home.fmd")
- _fileContent, _err := os.ReadFile(_filePath)
- if _err != nil {
- _fileContent = bytes.NewBufferString("Could not open file.").Bytes()
- }
-
- var _templateDataContainer struct {
- FileText string
- }
- _templateDataContainer.FileText = fmd.InterpretFMDtoHTMLString(string(_fileContent))
-
// Render template.
- if _err = _tmpl.ExecuteTemplate(w, "index.html", _templateDataContainer); _err != nil {
+ if _err = _tmpl.ExecuteTemplate(w, "index.html", nil); _err != nil {
log.Printf("_ERROR:network:handlePage(\"/home\"):%s", _err)
http.Error(w, "_ERROR:network:handlePage(\"/home\"):template.ExecuteTemplate", http.StatusInternalServerError)
return
@@ -104,39 +90,8 @@ func handlePageSubject(w http.ResponseWriter, r *http.Request) {
return
}
- // Parse URL for query parameters.
- _urlContent, _err := url.Parse(r.URL.String())
- if _err != nil {
- log.Printf("_ERROR:network:handlePage(\"/subject\"):%s", _err)
- http.Error(w, "_ERROR:network:handlePage(\"/subject\"):url.Parse", http.StatusInternalServerError)
- }
-
- _urlQuerySubject, _err := url.ParseQuery(_urlContent.RawQuery)
- if _err != nil {
- log.Printf("_ERROR:network:handlePage(\"/subject\"):%s", _err)
- http.Error(w, "_ERROR:network:handlePage(\"/subject\"):url.ParseQuery", http.StatusInternalServerError)
- }
-
- _fileName := filepath.Base(_urlQuerySubject.Get("s"))
- _filePath := filepath.Join(mfs.Dirs["data"], "/fmd/"+_fileName+".fmd")
- _fileContent, _err := os.ReadFile(_filePath)
- if _err != nil {
- _fileContent = bytes.NewBufferString("Could not open file.").Bytes()
- }
-
- // Assign rendered FMD file to buffer.
- var _templateDataContainer struct {
- FileName string
- FileText string
- }
- _templateDataContainer.FileName = _fileName
- _templateDataContainer.FileText = fmd.InterpretFMDtoHTMLString(string(_fileContent))
- if _templateDataContainer.FileText == "" {
- _templateDataContainer.FileText = "No File Found"
- }
-
// Render template.
- if _err = _tmpl.ExecuteTemplate(w, "index.html", _templateDataContainer); _err != nil {
+ if _err = _tmpl.ExecuteTemplate(w, "index.html", nil); _err != nil {
log.Printf("_ERROR:network:handlePage(\"/subject\"):%s", _err)
http.Error(w, "_ERROR:network:handlePage(\"/subject\"):template.ExecuteTemplate", http.StatusInternalServerError)
return
@@ -158,36 +113,6 @@ func handlePageEdit(w http.ResponseWriter, r *http.Request) {
// Add 'global' file dependencies.
_rPkg.DependencyFiles = append(_rPkg.DependencyFiles, mfs.WebGlobalPkg.DependencyFiles...)
- // Get file name from URL
- _urlContent, _err := url.Parse(r.URL.String())
- if _err != nil {
- log.Printf("_ERROR:network:handle(\"/edit\"):%s", _err)
- http.Error(w, "_ERROR:network:handlePage(\"/edit\"):url.Parse", http.StatusInternalServerError)
- }
-
- // Parse URL for query parameters.
- _urlQuerySubject, _err := url.ParseQuery(_urlContent.RawQuery)
- if _err != nil {
- log.Printf("_ERROR:network:handlePage(\"/edit\"):%s", _err)
- http.Error(w, "_ERROR:network:handlePage(\"/edit\"):url.ParseQuery", http.StatusInternalServerError)
- }
-
- _fileName := filepath.Base(_urlQuerySubject.Get("s"))
- _filePath := filepath.Join(mfs.Dirs["data"], "/fmd/"+_fileName+".fmd")
- _fileContent, _err := os.ReadFile(_filePath)
- if _err != nil {
- _fileContent = bytes.NewBufferString("Could not open file.").Bytes()
- }
-
- // Extract file content into bufffer.
- var _templateDataContainer struct {
- FileText string
- }
- _templateDataContainer.FileText = string(_fileContent)
- if _err != nil {
- _templateDataContainer.FileText = _err.Error()
- }
-
// Create template from package.
_tmpl, _err := template.ParseFiles(_rPkg.DependencyFiles...)
if _err != nil {
@@ -197,7 +122,7 @@ func handlePageEdit(w http.ResponseWriter, r *http.Request) {
}
// Render template.
- if _err = _tmpl.ExecuteTemplate(w, "index.html", _templateDataContainer); _err != nil {
+ if _err = _tmpl.ExecuteTemplate(w, "index.html", nil); _err != nil {
log.Printf("_ERROR:network:handlePage(\"/edit\"):%s", _err)
http.Error(w, "_ERROR:network:handlePage(\"/edit\"):template.ExecuteTemplate", http.StatusInternalServerError)
return
diff --git a/web/edit/script.js b/web/edit/script.js
@@ -12,13 +12,11 @@ WebAssembly.instantiateStreaming(fetch("web/global/fmd/fmd.wasm"), go.importObje
.then((result) => {
go.run(result.instance);
-
fmdViewDescriptor.innerHTML = interpretFMD("span(class:\"__descriptor\"):{b:{TEXT PAD}<br>span:{Input fmd text here ▾}}")
- // call to FMD function
- // isValid = isValidFMD(text_view_content.value)
- // update FMD status bar
- // updateStatus()
+ loadFMDFileRaw("https://test.wtenison.com/web/edit/default.fmd", fmdViewPanelSet["text-editor"].content)
+
+ loadFMDFileHTML("https://test.wtenison.com/web/edit/legend.fmd", fmdViewPanelSet["guide-text"].content)
})
.catch(err => console.error('_ERROR:instantiateStreaming:failed to load WASM:', err));
@@ -102,44 +100,6 @@ function GotoFrame(nextActiveFrame) {
currentFMDView = nextActiveFrame
}
-// LOAD FMD //
-
-window.onload = function () {
- loadFMDFileRaw("https://test.wtenison.com/web/edit/default.fmd", fmdViewPanelSet["text-editor"].content)
- loadFMDFileHTML("https://test.wtenison.com/web/edit/legend.fmd", fmdViewPanelSet["guide-text"].content)
-}
-
-function loadFMDFileRaw(url, container) {
- return fetch(url)
- .then(response => response.text())
- .then(text => {
- // Load the text into the text editor & buffer
- _textBUffer = text
- })
- .then(() => {
- // If FMD is valid, render to HTML
- container.innerHTML = _textBUffer
- })
-}
-
-function loadFMDFileHTML(url, container) {
- return fetch(url)
- .then(response => response.text())
- .then(text => {
- // Load the text into the text editor & buffer
- _textBUffer = text
- }).
- then(() => {
- // If FMD is valid, render to HTML
- if (isValidFMD(_textBUffer)) {
- container.innerHTML = interpretFMD(_textBUffer)
- } else {
- container.innerHTML = "FMD Parsing Failed"
- }
- })
- .catch(err => console.error('_ERROR:fetch:failed to load FMD url:', err));
-}
-
document.getElementById("open-guide-bttn").onclick = (event) => {
if (!fmdViewPanelSet["guide-text"].root.classList.contains("--open")) {
GotoFrame("guide-text")
diff --git a/web/global/fmd/wasm_exec.js b/web/global/fmd/wasm_exec.js
@@ -539,3 +539,35 @@
});
}
})();
+
+
+function loadFMDFileRaw(url, container) {
+ return fetch(url)
+ .then(response => response.text())
+ .then(text => {
+ // Load the text into the text editor & buffer
+ _textBUffer = text
+ })
+ .then(() => {
+ // If FMD is valid, render to HTML
+ container.innerHTML = _textBUffer
+ })
+}
+
+function loadFMDFileHTML(url, container) {
+ return fetch(url)
+ .then(response => response.text())
+ .then(text => {
+ // Load the text into the text editor & buffer
+ _textBUffer = text
+ }).
+ then(() => {
+ // If FMD is valid, render to HTML
+ if (isValidFMD(_textBUffer)) {
+ container.innerHTML = interpretFMD(_textBUffer)
+ } else {
+ container.innerHTML = "FMD Parsing Failed"
+ }
+ })
+ .catch(err => console.error('_ERROR:fetch:failed to load FMD url:', err));
+}
diff --git a/web/global/templates/header.tmpl.html b/web/global/templates/header.tmpl.html
@@ -2,7 +2,7 @@
<header class="--center-on-body">
<div id="header-title" class="_content_"><span id="site-name"><i>miki.wtenison</i> :</span>
- <span class="--set-size_font-to-screen">{{.}}</span>
+ <span class="--set-size_font-to-screen"><b>{{.}}</b></span>
</div>
<nav id="header-nav-view" class="__view __mcol">
diff --git a/web/home/index.html b/web/home/index.html
@@ -5,15 +5,14 @@
<title>Miki / Home</title>
{{template "meta"}}
{{template "fmd"}}
+ <script src="/web/home/script.js" defer></script>
</head>
<body>
{{template "header" "HOME"}}
- <aside id="left-sidebar-view">
-
- </aside>
+ <aside id="left-sidebar-view"></aside>
<main class="--center-on-body">
@@ -23,9 +22,7 @@
</main>
- <aside id="right-sidebar-view">
-
- </aside>
+ <aside id="right-sidebar-view"></aside>
</body>
diff --git a/web/home/script.js b/web/home/script.js
@@ -6,109 +6,9 @@ WebAssembly.instantiateStreaming(fetch("web/global/fmd/fmd.wasm"), go.importObje
.then((result) => {
go.run(result.instance);
- isValid = isValidFMD(inputText.value)
- updateStatus()
+ _homePageContent = document.getElementById("home-page-view").getElementsByClassName("_content_")[0]
- })
- .catch(err => console.error('_ERROR:instantiateStreaming:failed to load WASM:', err));
-
-// FMD_VIEW
-
-isSmall = false
-text_view = document.getElementById("text_view")
-render_view = document.getElementById("render_view")
-swap_view_bttn = document.getElementById("swap_bttn")
-let paddingBuffer
-
-// This determines the view layout for the fmd view area
-// between larger and smaller screens.
-function mResize() {
- if (!isSmall && window.innerWidth <= 750) {
- // Set the size of the view elements
- text_view.style.width = "100%";
- render_view.style.width = "0%";
-
- paddingBuffer = renderView.style.padding;
- renderView.style.padding = "0";
-
- // Load the swap view button
- swap_view_bttn.classList.remove("--hide");
-
- // Update state
- isSmall = true;
-
- } else if (isSmall && window.innerWidth > 750) {
- // Set the size of the view elements
- text_view.style.width = "100%";
- text_view.style.padding = paddingBuffer;
- renderView.style.width = "100%";
- renderView.style.padding = paddingBuffer;
-
- // Hide the swap view button
- swap_view_bttn.classList.add("--hide");
-
- // Update state
- isSmall = false;
- }
-}
-
-// When on a small screen, this swaps the viewable element for
-// the fmd view area.
-function swapView() {
- if (isSmall) {
- // Swap the width of the views
- _bufferWidth = text_view.style.width;
- text_view.style.width = render_view.style.width;
- render_view.style.width = _bufferWidth;
+ loadFMDFileHTML("https://test.wtenison.com/data/fmd/home.fmd", _homePageContent)
- // Swap the padding of the views
- _bufferPadding = text_view.style.padding;
- text_view.style.padding = render_view.style.padding;
- render_view.style.padding = _bufferPadding;
-
- // Update the swap button content
- _width = parseInt(text_view.style.width)
- if (_width == 0) {
- swap_view_bttn.innerHTML = "< Return";
- } else {
- swap_view_bttn.innerHTML = "Preview >";
- }
- }
-}
-
-window.addEventListener("resize", () => { mResize() })
-swap_view_bttn.addEventListener("click", () => { swapView() })
-
-// FMD INTERPRETER
-
-let isValid
-inputText = document.getElementById("text_view")
-renderView = document.getElementById("render_view")
-text_status = document.getElementById("text_status")
-
-// This updates the fmd status to tell the user if their
-// input code is valid or not.
-function updateStatus() {
- if (isValid) {
- text_status.innerHTML = "OK";
- text_status.style.backgroundColor = "var(--color__mint-dark)";
- renderView.innerHTML = interpretFMD(inputText.value)
- } else {
- text_status.innerHTML = "ERROR"
- text_status.style.backgroundColor = "var(--color__red-light)";
- }
-}
-
-inputText.addEventListener('input', (event) => {
- isValid = isValidFMD(inputText.value)
-
- updateStatus()
-})
-
-window.onload = () => {
- // Resizes fmd view window
- mResize()
-
- // Sets the initial text in the fmd text view
- inputText.value = "h1:Welcome\nThis is some b:{i:test text}."
-}
-\ No newline at end of file
+ })
+ .catch(err => console.error('_ERROR:instantiateStreaming:failed to load WASM:', err));
+\ No newline at end of file
diff --git a/web/subject/index.html b/web/subject/index.html
@@ -5,27 +5,24 @@
<title>Miki / Subject</title>
{{template "meta"}}
{{template "fmd"}}
+ <script src="/web/subject/script.js" defer></script>
</head>
<body>
{{template "header" .FileName}}
- <aside id="left-sidebar-view">
-
- </aside>
+ <aside id="left-sidebar-view"></aside>
<main class="--center-on-body">
- <div id="home-page-view" class="__view">
+ <div id="subject-view" class="__view">
<div class="_content_">{{.FileText}}</div>
</div>
</main>
- <aside id="right-sidebar-view">
-
- </aside>
+ <aside id="right-sidebar-view"></aside>
</body>
diff --git a/web/subject/script.js b/web/subject/script.js
@@ -0,0 +1,19 @@
+// START WASM //
+
+const go = new global.Go();
+
+WebAssembly.instantiateStreaming(fetch("web/global/fmd/fmd.wasm"), go.importObject)
+ .then((result) => {
+ go.run(result.instance);
+ _subjectView = document.getElementById("subject-view")
+ _subjectContent = _subjectView.getElementsByClassName("_content_")[0]
+
+ _urlParams = new URLSearchParams(window.location.search);
+ const _subject = _urlParams.get("s");
+ if (_subject == "") {
+ _subjectContent.innerHTML = "No subject specified"
+ } else {
+ loadFMDFileHTML("https://test.wtenison.com/data/fmd/" + _subject + ".fmd", _subjectContent)
+ }
+ })
+ .catch(err => console.error('_ERROR:instantiateStreaming:failed to load WASM:', err));
+\ No newline at end of file