diff --git a/data/static/style.css b/data/static/style.css
index 8a2e5a5..e00bb75 100644
--- a/data/static/style.css
+++ b/data/static/style.css
@@ -26,7 +26,7 @@
font-weight: bold;
font-style: italic;
}
-.currentpage, .pagebutton, input[type=file]::file-selector-button, button.warn, input[type=submit].warn, .linkbutton.warn, button.critical, input[type=submit].critical, .linkbutton.critical, button, input[type=submit], .linkbutton {
+.tab-button, .currentpage, .pagebutton, input[type=file]::file-selector-button, button.warn, input[type=submit].warn, .linkbutton.warn, button.critical, input[type=submit].critical, .linkbutton.critical, button, input[type=submit], .linkbutton {
cursor: default;
color: black;
font-size: 0.9em;
@@ -511,6 +511,50 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
.babycode-editor {
height: 150px;
+ font-size: 1rem;
+}
+
+.babycode-editor-container {
+ width: 100%;
+}
+
+.babycode-preview-errors-container {
+ font-size: 0.8rem;
+}
+
+.tab-button {
+ background-color: rgb(177, 206, 204.5);
+ border-bottom: none;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ margin-bottom: 0;
+}
+.tab-button:hover {
+ background-color: rgb(192.6, 215.8, 214.6);
+}
+.tab-button:active {
+ background-color: rgb(166.6881496063, 178.0118503937, 177.4261417323);
+}
+.tab-button:disabled {
+ background-color: rgb(209.535, 211.565, 211.46);
+}
+.tab-button.active {
+ background-color: #beb1ce;
+ padding-top: 8px;
+}
+
+.tab-content {
+ display: none;
+}
+.tab-content.active {
+ min-height: 250px;
+ display: block;
+ background-color: rgb(191.3137931034, 189.7, 193.3);
+ border: 1px solid black;
+ padding: 10px;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
}
ul, ol {
diff --git a/js/babycode-editor.js b/js/babycode-editor.js
index 075191c..5d1d113 100644
--- a/js/babycode-editor.js
+++ b/js/babycode-editor.js
@@ -59,4 +59,48 @@
e.preventDefault();
insertTag("code", true)
})
+
+ const previewEndpoint = "/api/babycode-preview";
+ let previousMarkup = "";
+ const previewTab = document.getElementById("tab-preview");
+ previewTab.addEventListener("tab-activated", async () => {
+ const previewContainer = document.getElementById("babycode-preview-container");
+ const previewErrorsContainer = document.getElementById("babycode-preview-errors-container");
+ // previewErrorsContainer.textContent = "";
+ const markup = ta.value.trim();
+ if (markup === "" || markup === previousMarkup) {
+ return;
+ }
+ previousMarkup = markup;
+ const req = await fetch(previewEndpoint, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({markup: markup})
+ })
+ if (!req.ok) {
+ switch (req.status) {
+ case 429:
+ previewErrorsContainer.textContent = "(Old preview, try again in a few seconds.)"
+ previousMarkup = "";
+ break;
+ case 400:
+ previewErrorsContainer.textContent = "(Request got malformed.)"
+ break;
+ case 401:
+ previewErrorsContainer.textContent = "(You are not logged in.)"
+ break;
+ default:
+ previewErrorsContainer.textContent = "(Error. Check console.)"
+ console.error(req.error);
+ break;
+ }
+ return;
+ }
+
+ const json_resp = await req.json();
+ previewContainer.innerHTML = json_resp.html;
+ previewErrorsContainer.textContent = "";
+ });
}
diff --git a/js/tabs.js b/js/tabs.js
new file mode 100644
index 0000000..3066310
--- /dev/null
+++ b/js/tabs.js
@@ -0,0 +1,30 @@
+function activateSelfDeactivateSibs(button) {
+ if (button.classList.contains("active")) return;
+
+ Array.from(button.parentNode.children).forEach(s => {
+ if (s === button){
+ button.classList.add('active');
+ } else {
+ s.classList.remove('active');
+ }
+ const targetId = s.dataset.targetId;
+ const target = document.getElementById(targetId);
+
+ if (!target) return;
+
+ if (s.classList.contains('active')) {
+ target.classList.add('active');
+ target.dispatchEvent(new CustomEvent("tab-activated", {bubbles: false}))
+ } else {
+ target.classList.remove('active');
+ }
+ });
+}
+
+document.addEventListener("DOMContentLoaded", () => {
+ document.querySelectorAll(".tab-button").forEach(button => {
+ button.addEventListener("click", () => {
+ activateSelfDeactivateSibs(button);
+ });
+ });
+});
diff --git a/sass/style.scss b/sass/style.scss
index e602371..07b20aa 100644
--- a/sass/style.scss
+++ b/sass/style.scss
@@ -45,6 +45,7 @@ $lighter: color.scale($accent_color, $lightness: 60%, $saturation: -60%);
$main_bg: color.scale($accent_color, $lightness: -10%, $saturation: -40%);
$button_color: color.adjust($accent_color, $hue: 90);
+$button_color2: color.adjust($accent_color, $hue: 180);
%button-base {
cursor: default;
@@ -524,8 +525,44 @@ input[type="text"], input[type="password"], textarea, select {
.babycode-editor {
height: 150px;
+ font-size: 1rem;
}
+.babycode-editor-container {
+ width: 100%;
+}
+
+.babycode-preview-errors-container {
+ font-size: 0.8rem;
+}
+
+.tab-button {
+ @include button($button_color);
+ border-bottom: none;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ margin-bottom: 0;
+
+ &.active {
+ background-color: $button_color2;
+ padding-top: 8px;
+ }
+}
+
+.tab-content {
+ display: none;
+
+ &.active {
+ min-height: 250px;
+ display: block;
+ background-color: color.adjust($button_color2, $saturation: -20%);
+ border: 1px solid black;
+ padding: 10px;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+ }
+}
ul, ol {
margin: 10px 0 10px 30px;
diff --git a/views/base.etlua b/views/base.etlua
index 5da0af2..c6fab0f 100644
--- a/views/base.etlua
+++ b/views/base.etlua
@@ -18,5 +18,6 @@
+