From 793d788706a7a35adb53fb0d22c6b629a9c1d215 Mon Sep 17 00:00:00 2001 From: Gnome Ann <> Date: Thu, 26 May 2022 14:34:40 -0400 Subject: [PATCH 1/3] Preserve whitespace in the editor --- static/custom.css | 1 + templates/index.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/static/custom.css b/static/custom.css index 677fc028..0fc761fb 100644 --- a/static/custom.css +++ b/static/custom.css @@ -4,6 +4,7 @@ body { chunk { color: #ffffff; + white-space: pre-wrap; } #gametext.adventure action { diff --git a/templates/index.html b/templates/index.html index 92b70753..887305c6 100644 --- a/templates/index.html +++ b/templates/index.html @@ -9,7 +9,7 @@ - + From 4b16600e49a24f9d43c16d9517eb0acfc9539313 Mon Sep 17 00:00:00 2001 From: vfbd Date: Fri, 24 Jun 2022 12:03:35 -0400 Subject: [PATCH 2/3] Clean up whitespace at the end of actions when loading story Specifically, we merge blank actions into the next action and we move whitespace at the end of non-blank actions to the beginning of the next action. --- aiserver.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/aiserver.py b/aiserver.py index c4123eaa..e4cfbd33 100644 --- a/aiserver.py +++ b/aiserver.py @@ -5473,7 +5473,8 @@ def loadRequest(loadpath, filename=None): for text in js['actions']: vars.actions_metadata[i] = {'Selected Text': text, 'Alternative Text': []} i+=1 - + + footer = "" if(len(vars.prompt.strip()) == 0): while(len(actions)): @@ -5483,9 +5484,25 @@ def loadRequest(loadpath, filename=None): break else: vars.gamestarted = False + vars.prompt = vars.prompt.lstrip() + ln = len(vars.prompt.rstrip()) + footer += vars.prompt[ln:] + vars.prompt = vars.prompt[:ln] if(vars.gamestarted): for s in actions: - vars.actions.append(s) + if(len(s.strip()) == 0): + # If this action only contains whitespace, we merge it with the next action + footer += s + continue + vars.actions.append(footer + s) + footer = "" + # If there is trailing whitespace at the end of an action, we move that whitespace to the beginning of the next action + ln = len(vars.actions[vars.actions.get_last_key()].rstrip()) + footer += vars.actions[vars.actions.get_last_key()][ln:] + vars.actions[vars.actions.get_last_key()] = vars.actions[vars.actions.get_last_key()][:ln] + if(len(vars.actions) == 0): + vars.gamestarted = False + # Try not to break older save files if("authorsnote" in js): From 6e138db1c0be03768e1c1297668260614011b9e1 Mon Sep 17 00:00:00 2001 From: vfbd Date: Fri, 24 Jun 2022 12:44:00 -0400 Subject: [PATCH 3/3] Clean up whitespace in the editor as well --- static/application.js | 45 +++++++++++++++++++++++++++++++++++++++++-- templates/index.html | 2 +- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/static/application.js b/static/application.js index b5c1a585..5b9820d2 100644 --- a/static/application.js +++ b/static/application.js @@ -1717,7 +1717,7 @@ function applyChunkDeltas(nodes) { var selected_chunks = buildChunkSetFromNodeArray(getSelectedNodes()); for(var i = 0; i < chunks.length; i++) { var chunk = document.getElementById("n" + chunks[i]); - if(chunk && formatChunkInnerText(chunk).length != 0 && chunks[i] != '0') { + if(chunk && formatChunkInnerText(chunk).trim().length != 0 && chunks[i] != '0') { if(!selected_chunks.has(chunks[i])) { modified_chunks.delete(chunks[i]); socket.send({'cmd': 'inlineedit', 'chunk': chunks[i], 'data': formatChunkInnerText(chunk)}); @@ -1726,7 +1726,7 @@ function applyChunkDeltas(nodes) { } else { if(!selected_chunks.has(chunks[i])) { modified_chunks.delete(chunks[i]); - socket.send({'cmd': 'inlineedit', 'chunk': chunks[i], 'data': ''}); + socket.send({'cmd': 'inlineedit', 'chunk': chunks[i], 'data': formatChunkInnerText(chunk)}); } empty_chunks.add(chunks[i]); } @@ -1858,6 +1858,46 @@ function highlightEditingChunks() { } } +function cleanupChunkWhitespace() { + // Merge empty chunks with the next chunk + var chunks = Array.from(empty_chunks); + chunks.sort(function(e) {parseInt(e)}); + for(var i = 0; i < chunks.length; i++) { + var original_chunk = document.getElementById("n" + chunks[i]); + original_chunk.innerText = footer + original_chunk.innerText; + footer = ""; + var chunk = original_chunk.nextSibling; + while(chunk) { + if(chunk.tagName === "CHUNK") { + break; + } + chunk = chunk.nextSibling; + } + if(chunk) { + chunk.innerText = original_chunk.innerText + chunk.innerText; + } + original_chunk.innerText = ""; + } + // Move whitespace at the end of non-empty chunks into the beginning of the next non-empty chunk + var chunks = Array.from(modified_chunks); + chunks.sort(function(e) {parseInt(e)}); + for(var i = 0; i < chunks.length; i++) { + var original_chunk = document.getElementById("n" + chunks[i]); + var chunk = original_chunk.nextSibling; + while(chunk) { + if(chunk.tagName === "CHUNK" && !empty_chunks.has(chunk.getAttribute("n"))) { + break; + } + chunk = chunk.nextSibling; + } + var ln = original_chunk.innerText.trimEnd().length; + if (chunk) { + chunk.innerText = original_chunk.innerText.substring(ln) + chunk.innerText; + } + original_chunk.innerText = original_chunk.innerText.substring(0, ln); + } +} + // This gets run every time the text in a chunk is edited // or a chunk is deleted function chunkOnDOMMutate(mutations, observer) { @@ -1936,6 +1976,7 @@ function chunkOnFocusOut(event) { if(document.activeElement === game_text[0] || game_text[0].contains(document.activeElement)) { return; } + cleanupChunkWhitespace(); syncAllModifiedChunks(true); setTimeout(function() { var blurred = game_text[0] !== document.activeElement; diff --git a/templates/index.html b/templates/index.html index 6acab35f..e2457a68 100644 --- a/templates/index.html +++ b/templates/index.html @@ -17,7 +17,7 @@ - + {% if flaskwebgui %}