This commit is contained in:
parent
eee51f6694
commit
a771da8902
2 changed files with 40 additions and 15 deletions
15
Dockerfile
15
Dockerfile
|
|
@ -37,24 +37,9 @@ RUN --mount=type=bind,source=src,target=src \
|
||||||
|
|
||||||
FROM docker.io/library/alpine:3.18 AS final
|
FROM docker.io/library/alpine:3.18 AS final
|
||||||
|
|
||||||
# Create a non-privileged user (recommended best practice)
|
|
||||||
ARG UID=10001
|
|
||||||
RUN adduser \
|
|
||||||
--disabled-password \
|
|
||||||
--gecos "" \
|
|
||||||
--home "/nonexistent" \
|
|
||||||
--shell "/sbin/nologin" \
|
|
||||||
--no-create-home \
|
|
||||||
--uid "${UID}" \
|
|
||||||
imnyang
|
|
||||||
|
|
||||||
RUN mkdir -p /app
|
RUN mkdir -p /app
|
||||||
RUN chmod -R 755 /app
|
RUN chmod -R 755 /app
|
||||||
RUN mkdir -p /app/uploads
|
RUN mkdir -p /app/uploads
|
||||||
RUN chown -R imnyang:imnyang /app
|
|
||||||
|
|
||||||
# Drop privileges for runtime.
|
|
||||||
USER imnyang
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@
|
||||||
<style>
|
<style>
|
||||||
@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap");
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--editor-font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: "JetBrains Mono", monospace;
|
font-family: "JetBrains Mono", monospace;
|
||||||
font-optical-sizing: auto;
|
font-optical-sizing: auto;
|
||||||
|
|
@ -27,6 +31,7 @@
|
||||||
|
|
||||||
.cm-editor {
|
.cm-editor {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
font-size: var(--editor-font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
|
|
@ -125,6 +130,13 @@
|
||||||
<input id="extension-input" type="text" inputmode="text" autocomplete="off" spellcheck="false"
|
<input id="extension-input" type="text" inputmode="text" autocomplete="off" spellcheck="false"
|
||||||
placeholder="txt" />
|
placeholder="txt" />
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<span>[</span>
|
||||||
|
<button id="increase-size-button" type="button">+</button>
|
||||||
|
<button id="reset-size-button" type="button">|</button>
|
||||||
|
<button id="decrease-size-button" type="button">-</button>
|
||||||
|
<span>]</span>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</header>
|
</header>
|
||||||
<div id="editor"></div>
|
<div id="editor"></div>
|
||||||
|
|
@ -158,8 +170,15 @@
|
||||||
const extensionInput = document.getElementById("extension-input");
|
const extensionInput = document.getElementById("extension-input");
|
||||||
const saveButton = document.getElementById("save-button");
|
const saveButton = document.getElementById("save-button");
|
||||||
const newButton = document.getElementById("new-button");
|
const newButton = document.getElementById("new-button");
|
||||||
|
const decreaseSizeButton = document.getElementById("decrease-size-button");
|
||||||
|
const resetSizeButton = document.getElementById("reset-size-button");
|
||||||
|
const increaseSizeButton = document.getElementById("increase-size-button");
|
||||||
|
|
||||||
const languageCompartment = new Compartment();
|
const languageCompartment = new Compartment();
|
||||||
|
const DEFAULT_EDITOR_FONT_SIZE = 14;
|
||||||
|
const MIN_EDITOR_FONT_SIZE = 10;
|
||||||
|
const MAX_EDITOR_FONT_SIZE = 28;
|
||||||
|
const EDITOR_FONT_SIZE_STEP = 1;
|
||||||
|
|
||||||
const LANGUAGE_PRESETS = {
|
const LANGUAGE_PRESETS = {
|
||||||
plain: {
|
plain: {
|
||||||
|
|
@ -233,6 +252,7 @@
|
||||||
let initialDoc = initialData.textContent;
|
let initialDoc = initialData.textContent;
|
||||||
let initialExtension = ".txt";
|
let initialExtension = ".txt";
|
||||||
let lastSuggestedExtension = ".txt";
|
let lastSuggestedExtension = ".txt";
|
||||||
|
let editorFontSize = DEFAULT_EDITOR_FONT_SIZE;
|
||||||
|
|
||||||
function normalizeExtension(value, fallback = ".txt") {
|
function normalizeExtension(value, fallback = ".txt") {
|
||||||
const cleaned = value
|
const cleaned = value
|
||||||
|
|
@ -266,6 +286,13 @@
|
||||||
saveButton.disabled = !isDirty();
|
saveButton.disabled = !isDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateEditorSize() {
|
||||||
|
document.documentElement.style.setProperty("--editor-font-size", `${editorFontSize}px`);
|
||||||
|
decreaseSizeButton.disabled = editorFontSize <= MIN_EDITOR_FONT_SIZE;
|
||||||
|
increaseSizeButton.disabled = editorFontSize >= MAX_EDITOR_FONT_SIZE;
|
||||||
|
resetSizeButton.disabled = editorFontSize === DEFAULT_EDITOR_FONT_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
function applyLanguagePreset(languageKey) {
|
function applyLanguagePreset(languageKey) {
|
||||||
const preset = LANGUAGE_PRESETS[languageKey] ?? LANGUAGE_PRESETS.plain;
|
const preset = LANGUAGE_PRESETS[languageKey] ?? LANGUAGE_PRESETS.plain;
|
||||||
const currentExtension = normalizeExtension(extensionInput.value, "");
|
const currentExtension = normalizeExtension(extensionInput.value, "");
|
||||||
|
|
@ -341,6 +368,18 @@
|
||||||
|
|
||||||
saveButton.onclick = saveFile;
|
saveButton.onclick = saveFile;
|
||||||
newButton.onclick = () => (window.location.href = "/");
|
newButton.onclick = () => (window.location.href = "/");
|
||||||
|
decreaseSizeButton.onclick = () => {
|
||||||
|
editorFontSize = Math.max(MIN_EDITOR_FONT_SIZE, editorFontSize - EDITOR_FONT_SIZE_STEP);
|
||||||
|
updateEditorSize();
|
||||||
|
};
|
||||||
|
resetSizeButton.onclick = () => {
|
||||||
|
editorFontSize = DEFAULT_EDITOR_FONT_SIZE;
|
||||||
|
updateEditorSize();
|
||||||
|
};
|
||||||
|
increaseSizeButton.onclick = () => {
|
||||||
|
editorFontSize = Math.min(MAX_EDITOR_FONT_SIZE, editorFontSize + EDITOR_FONT_SIZE_STEP);
|
||||||
|
updateEditorSize();
|
||||||
|
};
|
||||||
|
|
||||||
languageSelect.addEventListener("change", (event) => {
|
languageSelect.addEventListener("change", (event) => {
|
||||||
applyLanguagePreset(event.target.value);
|
applyLanguagePreset(event.target.value);
|
||||||
|
|
@ -365,6 +404,7 @@
|
||||||
saveFile();
|
saveFile();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
updateEditorSize();
|
||||||
refreshSaveState();
|
refreshSaveState();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue