This is the code that runs https://bandolier.learnjsthehardway.com/ for you to review. It uses the https://git.learnjsthehardway.com/learn-javascript-the-hard-way/bandolier-template to create the documentation for the project.
https://bandolier.learnjsthehardway.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
3.9 KiB
153 lines
3.9 KiB
2 years ago
|
<script>
|
||
|
import template from "lodash/template";
|
||
|
import Icon from "$/client/components/Icon.svelte";
|
||
|
import Toasts from "$/client/components/Toasts.svelte";
|
||
|
import Code from "$/client/components/Code.svelte";
|
||
|
import { log } from "$/client/logging.js";
|
||
|
import Layout from "../Layout.svelte";
|
||
|
import api from '$/client/api.js';
|
||
|
import { onMount } from "svelte";
|
||
|
|
||
|
export let selected_template;
|
||
|
|
||
|
let showing_rendered = false;
|
||
|
let results = "";
|
||
|
let source = "";
|
||
|
let variable_json = "{ }";
|
||
|
let generators = [];
|
||
|
|
||
|
let variables = {};
|
||
|
let renderer = () => source;
|
||
|
let notice = "";
|
||
|
let last_good = "";
|
||
|
let send_toast;
|
||
|
|
||
|
let language = "javascript";
|
||
|
const language_list = {
|
||
|
"html": "html",
|
||
|
"svelte": "javascript",
|
||
|
"sh": "shell",
|
||
|
"js": "javascript"
|
||
|
}
|
||
|
|
||
|
const list_generators = async () => {
|
||
|
let [status, data] = await api.get('/api/devtools/djenterator');
|
||
|
|
||
|
if(status == 200) {
|
||
|
generators = data;
|
||
|
selected_template = generators[0];
|
||
|
} else {
|
||
|
log.debug("failed to load generators", status);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const render_template = () => {
|
||
|
try {
|
||
|
// avoid rendering when the current template doesn't match the renderer
|
||
|
if(selected_template == renderer._template) {
|
||
|
variables = variable_json ? JSON.parse(variable_json): {};
|
||
|
results = renderer(variables);
|
||
|
notice = "";
|
||
|
last_good = results;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
} catch(err) {
|
||
|
log.error(err);
|
||
|
notice = err.message;
|
||
|
results = last_good;
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const load_variables = async (template_name) => {
|
||
|
let res = await fetch(`/djenterator/${template_name}.vars`);
|
||
|
|
||
|
if(res.status == 200) {
|
||
|
variable_json = await res.text();
|
||
|
} else {
|
||
|
variable_json = '{}';
|
||
|
notice = `No ${template_name}.vars file found. ${res.status}`;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const detect_language = (name) => {
|
||
|
const ext = name.split(".")[1];
|
||
|
language = language_list[ext];
|
||
|
}
|
||
|
|
||
|
const load_template = async (template_name) => {
|
||
|
let res = await fetch(`/djenterator/${template_name}`);
|
||
|
|
||
|
if(res.status == 200) {
|
||
|
source = await res.text();
|
||
|
last_good = source;
|
||
|
detect_language(template_name);
|
||
|
|
||
|
try {
|
||
|
renderer = template(source);
|
||
|
// tag this template renderer so that we don't try to render it against the wrong one
|
||
|
renderer._template = template_name;
|
||
|
render_template();
|
||
|
} catch(error) {
|
||
|
log.error(error);
|
||
|
notice = `${error.message}`;
|
||
|
results = source;
|
||
|
}
|
||
|
} else {
|
||
|
notice = `Error loading ${template_name}: ${res.status}`;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const copy_code = () => {
|
||
|
navigator.clipboard.writeText(results).then(() => {
|
||
|
notice = "Code copied to clipboard.";
|
||
|
}, () => {
|
||
|
notice = "Failed copying to clipboard.";
|
||
|
});
|
||
|
}
|
||
|
|
||
|
$: if(variable_json) render_template();
|
||
|
|
||
|
// this reload the templates when you click on a new one
|
||
|
const re_render = async (what) => {
|
||
|
await load_variables(what);
|
||
|
await load_template(what);
|
||
|
}
|
||
|
|
||
|
$: if(selected_template) re_render(selected_template);
|
||
|
|
||
|
onMount(async () => await list_generators());
|
||
|
</script>
|
||
|
|
||
|
<style>
|
||
|
textarea.editor {
|
||
|
height: 15em;
|
||
|
background-color: var(--value0);
|
||
|
color: var(--value9);
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<Layout fullscreen={ true } header={ false } footer={ false } testid="page-bando-djenterator">
|
||
|
<blockstart style="width: 100%">
|
||
|
<block style="--w: 100%">
|
||
|
<select bind:value={ selected_template }>
|
||
|
{#each generators as template}
|
||
|
<option value={ template }>{ template }</option>
|
||
|
{/each}
|
||
|
</select>
|
||
|
|
||
|
<textarea class="editor" bind:value={ variable_json }></textarea>
|
||
|
{#if notice}
|
||
|
<callout class="error">{notice}</callout>
|
||
|
{/if}
|
||
|
|
||
|
{#if results}
|
||
|
<Code on:copy={ send_toast("Copied to clipboard!") } content={ results } language={ language } />
|
||
|
{/if}
|
||
|
|
||
|
</block>
|
||
|
</blockstart>
|
||
|
<Toasts bind:send_toast fade_after={ 10000 } orientation="bottom right" />
|
||
|
</Layout>
|