Fix some editor issues in Firefox and possibly mobile browsers
When Firefox 93.0 was released, they broke the ability to edit text across multiple chunks or across multiple paragraphs. If you tried, nothing would happen. Also, we are no longer using Mutation Observers to detect when a chunk is modified. We are now using the beforeinput event.
This commit is contained in:
parent
9b73d6a913
commit
bb51198f40
|
@ -71,7 +71,6 @@ var connected = false;
|
||||||
var newly_loaded = true;
|
var newly_loaded = true;
|
||||||
var modified_chunks = new Set();
|
var modified_chunks = new Set();
|
||||||
var empty_chunks = new Set();
|
var empty_chunks = new Set();
|
||||||
var mutation_observer = null;
|
|
||||||
var gametext_bound = false;
|
var gametext_bound = false;
|
||||||
var saved_prompt = "...";
|
var saved_prompt = "...";
|
||||||
var override_focusout = false;
|
var override_focusout = false;
|
||||||
|
@ -805,6 +804,48 @@ function chunkOnTextInput(event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This gets run when one or more chunks are edited. The event occurs before
|
||||||
|
// the actual edits are made by the browser, so we are free to check which
|
||||||
|
// nodes are selected or stop the event from occurring.
|
||||||
|
function chunkOnBeforeInput(event) {
|
||||||
|
// Register all selected chunks as having been modified
|
||||||
|
applyChunkDeltas(getSelectedNodes());
|
||||||
|
|
||||||
|
// Fix editing across chunks and paragraphs in Firefox 93.0 and higher
|
||||||
|
if(event.originalEvent.inputType === "deleteContentBackward" && document.queryCommandSupported && document.execCommand && document.queryCommandSupported('delete')) {
|
||||||
|
event.preventDefault();
|
||||||
|
document.execCommand('delete');
|
||||||
|
}
|
||||||
|
var s = rangy.getSelection();
|
||||||
|
if(!s.isCollapsed) {
|
||||||
|
s.deleteFromDocument();
|
||||||
|
}
|
||||||
|
if(buildChunkSetFromNodeArray(getSelectedNodes()).size === 0) {
|
||||||
|
var s = rangy.getSelection();
|
||||||
|
var r = s.getRangeAt(0);
|
||||||
|
if(document.queryCommandSupported && document.execCommand && document.queryCommandSupported('insertHTML')) {
|
||||||
|
document.execCommand('insertHTML', false, '<span id="_EDITOR_SENTINEL_">|</span>');
|
||||||
|
} else {
|
||||||
|
var t = document.createTextNode('|');
|
||||||
|
var b = document.createElement('span');
|
||||||
|
b.id = "_EDITOR_SENTINEL_";
|
||||||
|
b.insertNode(t);
|
||||||
|
r.insertNode(b);
|
||||||
|
}
|
||||||
|
var sentinel = document.getElementById("_EDITOR_SENTINEL_");
|
||||||
|
if(sentinel.nextSibling && sentinel.nextSibling.tagName === "CHUNK") {
|
||||||
|
r.selectNodeContents(sentinel.nextSibling);
|
||||||
|
r.collapse(true);
|
||||||
|
} else if(sentinel.previousSibling && sentinel.previousSibling.tagName === "CHUNK") {
|
||||||
|
r.selectNodeContents(sentinel.previousSibling);
|
||||||
|
r.collapse(false);
|
||||||
|
}
|
||||||
|
s.removeAllRanges();
|
||||||
|
s.addRange(r);
|
||||||
|
sentinel.parentNode.removeChild(sentinel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function chunkOnKeyDown(event) {
|
function chunkOnKeyDown(event) {
|
||||||
// Make escape commit the changes (Originally we had Enter here to but its not required and nicer for users if we let them type freely
|
// Make escape commit the changes (Originally we had Enter here to but its not required and nicer for users if we let them type freely
|
||||||
// You can add the following after 27 if you want it back to committing on enter : || (!event.shiftKey && event.keyCode == 13)
|
// You can add the following after 27 if you want it back to committing on enter : || (!event.shiftKey && event.keyCode == 13)
|
||||||
|
@ -1020,26 +1061,11 @@ function highlightEditingChunks() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This gets run every time the text in a chunk is edited
|
|
||||||
// or a chunk is deleted
|
|
||||||
function chunkOnDOMMutate(mutations, observer) {
|
|
||||||
if(!gametext_bound || !allowedit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var nodes = [];
|
|
||||||
for(var i = 0; i < mutations.length; i++) {
|
|
||||||
var mutation = mutations[i];
|
|
||||||
nodes = nodes.concat(Array.from(mutation.addedNodes), Array.from(mutation.removedNodes));
|
|
||||||
nodes.push(mutation.target);
|
|
||||||
}
|
|
||||||
applyChunkDeltas(nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This gets run every time you try to paste text into the editor
|
// This gets run every time you try to paste text into the editor
|
||||||
function chunkOnPaste(event) {
|
function chunkOnPaste(event) {
|
||||||
if(!gametext_bound) {
|
// Register the chunk we're pasting in as having been modified
|
||||||
return;
|
applyChunkDeltas(getSelectedNodes());
|
||||||
}
|
|
||||||
// If possible, intercept paste events into the editor in order to always
|
// If possible, intercept paste events into the editor in order to always
|
||||||
// paste as plaintext
|
// paste as plaintext
|
||||||
if(event.originalEvent.clipboardData && document.queryCommandSupported && document.execCommand && document.queryCommandSupported('insertHTML')) {
|
if(event.originalEvent.clipboardData && document.queryCommandSupported && document.execCommand && document.queryCommandSupported('insertHTML')) {
|
||||||
|
@ -1112,12 +1138,10 @@ function chunkOnFocusOut(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindGametext() {
|
function bindGametext() {
|
||||||
mutation_observer.observe(game_text[0], {characterData: true, childList: true, subtree: true});
|
|
||||||
gametext_bound = true;
|
gametext_bound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unbindGametext() {
|
function unbindGametext() {
|
||||||
mutation_observer.disconnect();
|
|
||||||
gametext_bound = false;
|
gametext_bound = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1532,6 +1556,8 @@ $(document).ready(function(){
|
||||||
// Register editing events
|
// Register editing events
|
||||||
game_text.on('textInput',
|
game_text.on('textInput',
|
||||||
chunkOnTextInput
|
chunkOnTextInput
|
||||||
|
).on('beforeinput',
|
||||||
|
chunkOnBeforeInput
|
||||||
).on('keydown',
|
).on('keydown',
|
||||||
chunkOnKeyDown
|
chunkOnKeyDown
|
||||||
).on('paste',
|
).on('paste',
|
||||||
|
@ -1543,7 +1569,6 @@ $(document).ready(function(){
|
||||||
).on('focusout',
|
).on('focusout',
|
||||||
chunkOnFocusOut
|
chunkOnFocusOut
|
||||||
);
|
);
|
||||||
mutation_observer = new MutationObserver(chunkOnDOMMutate);
|
|
||||||
|
|
||||||
// This is required for the editor to work correctly in Firefox on desktop
|
// This is required for the editor to work correctly in Firefox on desktop
|
||||||
// because the gods of HTML and JavaScript say so
|
// because the gods of HTML and JavaScript say so
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<script src="static/jquery-3.6.0.min.js"></script>
|
<script src="static/jquery-3.6.0.min.js"></script>
|
||||||
<script src="static/socket.io.min.js"></script>
|
<script src="static/socket.io.min.js"></script>
|
||||||
<script src="static/application.js?ver=1.16.4a"></script>
|
<script src="static/application.js?ver=1.16.4b"></script>
|
||||||
<script src="static/bootstrap.min.js"></script>
|
<script src="static/bootstrap.min.js"></script>
|
||||||
<script src="static/bootstrap-toggle.min.js"></script>
|
<script src="static/bootstrap-toggle.min.js"></script>
|
||||||
<script src="static/rangy-core.min.js"></script>
|
<script src="static/rangy-core.min.js"></script>
|
||||||
|
|
Loading…
Reference in New Issue