Cybrkyd's Git Repositories

jottings - commit: 724fa5e

commit 724fa5efbf2455ccc2e6f80386db3ec71b68a63947b351363c72bde72e8163ab
author Cybrkyd <git@cybrkyd.com> 2026-06-18 11:57:48 +0100
committer Cybrkyd <git@cybrkyd.com> 2026-06-18 11:57:48 +0100
v0.3

Commit Message

Bug fix

Bug #1: Shifting spellcheck squiggles. The longer the text, the more the squiggles progressed to the right of the flagged words.

Bug #2: Some leftover text was visible in editor window on document change where second doc text length was shorter than text length in first doc.

- Replace innerText with textContent
- Insert a real "\n" text node everywhere
- function insertTextAtCursor
- clearTimeout(autoSaveTimer) in load, delete and event listener for new

📊 Diffstat

resources/js/app.js 53
1 files changed, 50 insertions(+), 3 deletions(-)

Diff

diff --git a/resources/js/app.js b/resources/js/app.js
index f2ed386..93a649c 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -25,16 +25,39 @@ const spellMenuItems = document.getElementById('spellMenuItems');
const spellMenuAdd = document.getElementById('spellMenuAdd');
// Editor text helpers
+
+ // innerText is out; textContent is a little more sane for flat run of text nodes
function getEditorText() {
- return editor.innerText.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
+ return editor.textContent.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
}
function setEditorText(text) {
- editor.innerText = text;
+ editor.textContent = text;
clearTimeout(spellDebounce);
runSpellcheck();
}
+ // Insert a literal text string at the current caret position
+ function insertTextAtCursor(text) {
+ const selection = window.getSelection();
+ if (!selection || selection.rangeCount === 0) return;
+
+ const range = selection.getRangeAt(0);
+ if (!editor.contains(range.commonAncestorContainer)) return;
+
+ range.deleteContents();
+ const textNode = document.createTextNode(text);
+ range.insertNode(textNode);
+
+ range.setStartAfter(textNode);
+ range.setEndAfter(textNode);
+ selection.removeAllRanges();
+ selection.addRange(range);
+
+ // Let input handler run for normal typing
+ editor.dispatchEvent(new Event('input', { bubbles: true }));
+ }
+
// Canvas sizing
function resizeCanvas() {
const editorRect = editor.getBoundingClientRect();
@@ -196,7 +219,7 @@ function runSpellcheck() {
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
- // Helper to get client rects for a text range (indices into innerText)
+ // Helper to get client rects for a text range (indices into textContent)
function getRectsForTextRange(startIdx, endIdx) {
const rects = [];
@@ -565,6 +588,8 @@ async function loadDocuments() {
const notes = await readNotes();
const note = notes.find(n => n.id === doc.id);
if (note) {
+ //Clear any stale auto-save - they were firing against wrong doc
+ clearTimeout(autoSaveTimer);
setEditorText(note.content);
updateCounts(note.content);
currentDocId = doc.id;
@@ -638,6 +663,8 @@ async function deleteDocument(id) {
await writeNotes(notes);
if (currentDocId === id) {
+ //Clear any stale auto-save - they were firing against wrong doc
+ clearTimeout(autoSaveTimer);
currentDocId = null;
currentDocName = null;
setEditorText('');
@@ -740,6 +767,8 @@ document.getElementById("saveBtn").onclick = function() {
};
document.getElementById("newBtn").onclick = function() {
+ //Clear any stale auto-save - they were firing against wrong doc
+ clearTimeout(autoSaveTimer);
setEditorText('');
updateCounts('');
currentDocId = null;
@@ -787,6 +816,24 @@ editor.addEventListener("input", function() {
}, 3000);
});
+ // Intercept Enter and insert a real "\n" text node.
+ // Of course, this makes it necessary to Enter twice just to go to a new line, and
+ // Enter thrice for a new paragraph. A nice UI bug in the making!
+ editor.addEventListener("keydown", function(e) {
+ if (e.key === "Enter") {
+ e.preventDefault();
+ insertTextAtCursor("\n");
+ }
+ });
+
+ // Force every paste down to plain text. Insert it the same as if typed
+ editor.addEventListener("paste", function(e) {
+ e.preventDefault();
+ const clipboardData = e.clipboardData || window.clipboardData;
+ const text = clipboardData ? clipboardData.getData("text/plain") : "";
+ if (text) insertTextAtCursor(text);
+ });
+
// Context menu
editor.addEventListener("contextmenu", handleEditorContextMenu);