diff --git a/static/application.js b/static/application.js index 51767f10..04cf862e 100644 --- a/static/application.js +++ b/static/application.js @@ -78,6 +78,9 @@ var override_focusout = false; var sman_allow_delete = false; var sman_allow_rename = false; +// This is true iff [we're in macOS and the browser is Safari] or [we're in iOS] +var using_webkit_patch = null; + // Key states var shift_down = false; var do_clear_ent = false; @@ -974,7 +977,7 @@ function chunkOnPaste(event) { } // This gets run every time the caret moves in the editor -function chunkOnSelectionChange(event) { +function _chunkOnSelectionChange(event, do_blur_focus) { if(!gametext_bound || !allowedit || override_focusout) { override_focusout = false; return; @@ -985,14 +988,24 @@ function chunkOnSelectionChange(event) { highlightEditingChunks(); // Attempt to prevent Chromium-based browsers on Android from // scrolling away from the current selection - setTimeout(function() { - game_text.blur(); - game_text.focus(); - }, 144); + if(do_blur_focus && !using_webkit_patch) { + setTimeout(function() { + game_text.blur(); + game_text.focus(); + }, 144); + } }, 2); }, 2); } +function chunkOnSelectionChange(event) { + return _chunkOnSelectionChange(event, true); +} + +function chunkOnKeyDownSelectionChange(event) { + return _chunkOnSelectionChange(event, false); +} + // This gets run when you defocus the editor by clicking // outside of the editor or by pressing escape or tab function chunkOnFocusOut(event) { @@ -1091,7 +1104,7 @@ $(document).ready(function(){ rs_close = $("#btn_rsclose"); seqselmenu = $("#seqselmenu"); seqselcontents = $("#seqselcontents"); - + // Connect to SocketIO server socket = io.connect(window.document.origin); @@ -1116,6 +1129,36 @@ $(document).ready(function(){ game_text.attr('contenteditable', allowedit); } }); + // A simple feature detection test to determine whether the user interface + // is using WebKit (Safari browser's rendering engine) because WebKit + // requires special treatment to work correctly with the KoboldAI editor + if(using_webkit_patch === null) { + using_webkit_patch = (function() { + try { + var active_element = document.activeElement; + var c = document.createElement("chunk"); + var t = document.createTextNode("KoboldAI"); + c.appendChild(t); + game_text[0].appendChild(c); + var r = rangy.createRange(); + r.setStart(t, 6); + r.collapse(true); + var s = rangy.getSelection(); + s.removeAllRanges(); + s.addRange(r); + game_text.blur(); + game_text.focus(); + var offset = rangy.getSelection().focusOffset; + c.removeChild(t); + game_text[0].removeChild(c); + document.activeElement.blur(); + active_element.focus(); + return offset !== 6; + } catch (e) { + return false; + } + })(); + } } else if(msg.cmd == "updatescreen") { var _gamestarted = gamestarted; gamestarted = msg.gamestarted; @@ -1398,7 +1441,7 @@ $(document).ready(function(){ ).on('click', chunkOnSelectionChange ).on('keydown', - chunkOnSelectionChange + chunkOnKeyDownSelectionChange ).on('focusout', chunkOnFocusOut ); diff --git a/templates/index.html b/templates/index.html index 7098a824..55978aec 100644 --- a/templates/index.html +++ b/templates/index.html @@ -6,7 +6,7 @@ - +