From 1b650db1204163e10ce71ce6c25ea18f788ecac0 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 18 May 2017 13:10:27 +0700 Subject: [PATCH 1/9] Testing setup + #63 fix. There's some funky formatting issues on mobile/touch-based devices, though that may be hesitancy on their part to work well with dynamic elements. --- testing/issues-63.html | 100 ++++++++++++++++++++++++++ testing/issues-63.js | 156 ++++++++++++++++++++++++++++++++++++++++ web/source/keymanweb.js | 90 +++++++++++++++++++---- 3 files changed, 334 insertions(+), 12 deletions(-) create mode 100644 testing/issues-63.html create mode 100644 testing/issues-63.js diff --git a/testing/issues-63.html b/testing/issues-63.html new file mode 100644 index 0000000000..6158017025 --- /dev/null +++ b/testing/issues-63.html @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + KeymanWeb Sample Page - Uncompiled Source + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

KeymanWeb Sample Page - Uncompiled Source

+ +
+ +
+

This version is used to test KeymanWeb's ability to cope with page mutations.

+ + + + + + + +
+
+

Return to testing home page

+ + + + + + + diff --git a/testing/issues-63.js b/testing/issues-63.js new file mode 100644 index 0000000000..caaccb14ca --- /dev/null +++ b/testing/issues-63.js @@ -0,0 +1,156 @@ +// JavaScript Document samplehdr.js: Keyboard management for KeymanWeb demonstration pages + +/* + The keyboard name and/or ISO language code must be specified for each keyboard that is to be available. + If the same keyboard is used for several languages, it must be listed for each + language, but the keyboard itself will only be loaded once. + If two (or more) keyboards are to be available for a given language, both must be listed. + Any number of keyboards may be specified in one or more calls. + Keyboard paths may be absolute (with respect to the server root) or relative to the keyboards option path. + The actual keyboard object will be downloaded asynchronously when first selected for use. + + Each argument to addKeyboards() is a string, for example: + european2 loads the current version of the Eurolatin 2 keyboard (for its default language) + european2@fra loads the current version of the Eurolatin 2 keyboard for French + european2@fra@1.2 loads version 1.2 of the Eurolatin 2 keyboard for French + + Argument syntax also supports the following extensions: + @fra load the current version of the default keyboard for French + @fra$ load all available keyboards (current version) for French + + Each call to addKeyboards() requires a single call to the remote server, + (unless all keyboards listed are local and fully specified) so it is better + to use multiple arguments rather than separate function calls. + + Calling addKeyboards() with no arguments returns a list of *all* available keyboards. + The Toolbar (desktop browser) UI is best suited for allowing users to select + the appropriate language and keyboard in this case. + + Keyboards may also be specified by language name using addKeyboardsForLanguage() + for example: + keymanweb.addKeyboardsForLanguage('Burmese'); + + Appending $ to the language name will again cause all available keyboards for that + language to be loaded rather than the default keyboard. + + The first call to addKeyboardsForLanguage() makes an additional call to the + keyman API to load the current list of keyboard/language associations. + + In this example, the following function loads the indicated keyboards, + and is called when the page loads. +*/ + + function loadKeyboards() + { + var kmw=tavultesoft.keymanweb; + + // The first keyboard added will be the default keyboard for touch devices. + // For faster loading, it may be best for the default keybaord to be + // locally sourced. + kmw.addKeyboards({id:'us',name:'English',language:{id:'eng',name:'English'}, + filename:'./us-1.0.js'}); + + // Add more keyboards to the language menu, by keyboard name, + // keyboard name and language code, or just the ISO 639 language code. + kmw.addKeyboards('french','european2@swe','european2@nor','@heb'); + + // Add a keyboard by language name. Note that the name must be spelled + // correctly, or the keyboard will not be found. (Using ISO codes is + // usually easier.) + kmw.addKeyboardsForLanguage('Dzongkha'); + + // Add a fully-specified, locally-sourced, keyboard with custom font + kmw.addKeyboards({id:'lao_2008_basic',name:'Lao Basic', + language:{ + id:'lao',name:'Lao',region:'Asia', + font:{family:'LaoWeb',source:['../font/saysettha_web.ttf','../font/saysettha_web.woff','../font/saysettha_web.eot']} + }, + filename:'./lao_2008_basic.js' + }); + + // The following two optional calls should be delayed until language menus are fully loaded: + // (a) a specific mapped input element input is focused, to ensure that the OSK appears + // (b) a specific keyboard is loaded, rather than the keyboard last used. + //window.setTimeout(function(){kmw.setActiveElement('ta1',true);},2500); + //window.setTimeout(function(){kmw.setActiveKeyboard('Keyboard_french','fra');},3000); + + // Note that locally specified keyboards will be listed before keyboards + // requested from the remote server by user interfaces that do not order + // keyboards alphabetically by language. + } + + { + var inputCounter = 1; + var removalCounter = 1; + var removedElements = []; + } + + function addInputs() + { + var masterDiv = document.getElementById('DynamicTextboxes'); + + var newTextArea = document.createElement("textarea"); + + var i = inputCounter++; + + newTextArea.id = 'ta' + i; + newTextArea.className = 'test'; + newTextArea.placeholder = "Dynamic area #" + i + "!"; + + var newInput = document.createElement("input"); + newInput.id = 'in' + i; + newInput.className = 'test'; + newInput.placeholder = "Dynamic area #" + i + "!"; + + //masterDiv.appendChild(newTextArea); + //masterDiv.appendChild(newInput); + + var newDiv = document.createElement("div"); + newDiv.id = "dynamic_div" + i; + + //newDiv.appendChild(newTextArea); + newDiv.appendChild(newInput); + + masterDiv.appendChild(newDiv); + } + + function removeInputs() + { + var parent = document.getElementById('DynamicTextboxes'); + var div = document.getElementById("dynamic_div" + removalCounter); + if(div) + { + removalCounter++; + parent.removeChild(div); + removedElements.push(div); + } + } + + function restoreInputs() + { + var masterDiv = document.getElementById('DynamicTextboxes'); + removalCounter = 1; + + for(var i = 0; i < removedElements.length; i++) + { + masterDiv.appendChild(removedElements[i]); + } + + removedElements = []; + } + + function addIFrame() + { + var masterDiv = document.getElementById('DynamicTextboxes'); + + var frame = document.createElement("iframe"); + frame.height = "100"; + frame.src = "issue-29-iframe.html"; + frame.onload = function() {console.log('Original onload!');}; + + //masterDiv.appendChild(frame); + + var newDiv = document.createElement("div"); + newDiv.appendChild(frame); + masterDiv.appendChild(newDiv); + } \ No newline at end of file diff --git a/web/source/keymanweb.js b/web/source/keymanweb.js index 7bbac87060..daccf567c9 100644 --- a/web/source/keymanweb.js +++ b/web/source/keymanweb.js @@ -894,6 +894,18 @@ // The specified element must be validated as a touch element to proceed. if(!keymanweb.isKMWInput(Pelem)) return; + // Add the exposed member 'kmw_ip' to allow page to refer to duplicated element + if(Pelem['kmw_ip']) { + + // Wait, we've already established a member for this one before! Just reuse that one! + for(var i=0; i < keymanweb.inputList.length; i++) + if(keymanweb.inputList[i] == Pelem['kmw_ip']) return; // Actually, it's even on our list already! Don't touch it! + + // OK, we'd removed the element from our input list at some time in the past. Safe to re-add. + keymanweb.inputList.push(Pelem['kmw_ip']); + return; + } + var x=document.createElement('DIV'); x['base']=x.base=Pelem; @@ -903,16 +915,6 @@ else x.base.className='keymanweb-font'; - // Add the exposed member 'kmw_ip' to allow page to refer to duplicated element - if(Pelem['kmw_ip']) { - // Wait, we've already established a member for this one before! Just reuse that one! - for(var i=0; i < keymanweb.inputList.length; i++) - if(keymanweb.inputList[i] == Pelem['kmw_ip']) return; - - // OK, we'd removed the element from our input list at some time in the past. Safe to re-add. - keymanweb.inputList.push(Pelem['kmw_ip']); - return; - } Pelem['kmw_ip']=x; // Make sure the element's on the list of registered inputs. It can't NOT be, so we're fine. @@ -2828,7 +2830,7 @@ { if(t[i] == activeBase) break; } - + // Find the next (or previous) element in the list if(bBack) i=i-1; else i=i+1; if(i >= t.length) i=i-t.length; @@ -2840,7 +2842,7 @@ // Set focusing flag to prevent OSK disappearing keymanweb.focusing=true; var target=t[i]['kmw_ip']; - + // Focus if next element is non-mapped if(typeof(target) == 'undefined') { @@ -3652,7 +3654,58 @@ } // There also exists a 'mutation.removedNodes' array. We'll need to address that for issue #63. + for(j = 0; j < mutation.removedNodes.length; j++) + { + var removedNode = mutation.removedNodes[j]; + var lcTagName = "" + + if(removedNode.tagName) { + lcTagName = removedNode.tagName.toLowerCase(); + } + + var childRemovals = []; + // Will need to handle this in case of child elements in a newly-added element with child elements. + if(removedNode.getElementsByTagName) + { + var arr = removedNode.getElementsByTagName('input'); + for(k = 0; k < arr.length; k++) + childRemovals.push(arr[k]); + + arr = removedNode.getElementsByTagName('textarea'); + for(k = 0; k < arr.length; k++) + childRemovals.push(arr[k]); + + arr = removedNode.getElementsByTagName('iframe'); + for(k = 0; k < arr.length; k++) + childRemovals.push(arr[k]); + } + + if(lcTagName == 'input' || lcTagName == 'textarea' || lcTagName == 'iframe') + { + dirtyFlag = true; + keymanweb._MutationRemovalObserved(addedNode); + } + + for(k = 0; k < childRemovals.length; k++) + { + dirtyFlag = true; + keymanweb._MutationRemovalObserved(childRemovals[k]); + } + + // if something was removed, chances are it's gonna mess up our touch-based layout scheme, so let's update the touch elements. + if(dirtyFlag && device.touchable) + { + window.setTimeout(function() { + for(k = 0; k < keymanweb.sortedInputs.length; k++) + { + if(keymanweb.sortedInputs[k]['kmw_ip']) { + keymanweb.updateInput(keymanweb.sortedInputs[k]['kmw_ip']); + } + } + }, 1); + } + } // After all mutations have been handled, we need to recompile our .sortedInputs array. if(dirtyFlag) { keymanweb.listInputs(); @@ -3716,6 +3769,19 @@ } } + // Used by the mutation event handler to properly decouple any elements dynamically removed from the document. + keymanweb._MutationRemovalObserved = function(Pelem) + { + var element = Pelem; + if(device.touchable) { + element = Pelem['kmw_ip']; + } + var index = keymanweb.inputList.indexOf(Pelem); + if(index != -1) { + keymanweb.inputList.splice(index, 1); + } + } + // Create an ordered list of all text and search input elements and textarea elements // except any tagged with class 'kmw-disabled' // TODO: email and url types should perhaps use default keyboard only From f320d6fc2fb0c0ab4b0af7148ae5a83ad9a7c836 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 18 May 2017 14:45:13 +0700 Subject: [PATCH 2/9] Fixed up the odd tablet behavior when dynamically removed elements were readded. ... yes, that could be a thing. Issue #63 complete! Also moved testing files from temporary 'testing' directory to /web/samples. --- {testing => web/samples}/issues-63.html | 0 {testing => web/samples}/issues-63.js | 0 web/source/keymanweb.js | 24 +++++++++++++++--------- 3 files changed, 15 insertions(+), 9 deletions(-) rename {testing => web/samples}/issues-63.html (100%) rename {testing => web/samples}/issues-63.js (100%) diff --git a/testing/issues-63.html b/web/samples/issues-63.html similarity index 100% rename from testing/issues-63.html rename to web/samples/issues-63.html diff --git a/testing/issues-63.js b/web/samples/issues-63.js similarity index 100% rename from testing/issues-63.js rename to web/samples/issues-63.js diff --git a/web/source/keymanweb.js b/web/source/keymanweb.js index daccf567c9..af66930456 100644 --- a/web/source/keymanweb.js +++ b/web/source/keymanweb.js @@ -903,7 +903,7 @@ // OK, we'd removed the element from our input list at some time in the past. Safe to re-add. keymanweb.inputList.push(Pelem['kmw_ip']); - return; + return Pelem['kmw_ip']; } var x=document.createElement('DIV'); @@ -3707,8 +3707,20 @@ } } // After all mutations have been handled, we need to recompile our .sortedInputs array. + if(dirtyFlag) { - keymanweb.listInputs(); + keymanweb.listInputs(); + + if(dirtyFlag & device.touchable) { + window.setTimeout(function() { + for(k = 0; k < keymanweb.sortedInputs.length; k++) + { + if(keymanweb.sortedInputs[k]['kmw_ip']) { + keymanweb.updateInput(keymanweb.sortedInputs[k]['kmw_ip']); + } + } + }, 1); + } } } }); @@ -3753,13 +3765,7 @@ if(Pelem.tagName.toLowerCase() != 'iframe') { if(keymanweb.isKMWInput(Pelem)) { - var x = keymanweb.setupTouchElement(Pelem); - - if(x) - { - // if needed, let the timeout variable be: keymanweb.touchInputAddedTimer - window.setTimeout(function() {keymanweb.updateInput(x);}, 1); - } + keymanweb.setupTouchElement(Pelem); } else { From 81bf91346feabd69f6f1376772e85d106b5d7233 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 1 Jun 2017 14:40:28 +0700 Subject: [PATCH 3/9] Restructured testing page structure & added testing pages to the samples index.html page. --- web/samples/index.html | 4 ++++ web/samples/{issue53.html => issue-53.html} | 4 ++-- web/samples/{issue53.js => issue-53.js} | 0 web/samples/issue-62.html | 3 ++- web/samples/{issues-63.html => issue-63.html} | 5 +++-- web/samples/{issues-63.js => issue-63.js} | 0 web/samples/{issue58 => issue53}/issue58.html | 0 web/samples/{issue58 => issue53}/issue58.js | 0 .../layered_debug_keyboard-1.0.js | 0 .../layered_debug_keyboard-1.0.json | 0 .../layered_debug_keyboard-1.0_load.js | 0 .../layered_debug_keyboard-layout.js | 0 .../{issue58 => issue53}/layered_debug_keyboard.ico | Bin .../{issue58 => issue53}/layered_debug_keyboard.kmn | 0 .../{issue58 => issue53}/layered_debug_keyboard.kpj | 0 .../{issue58 => issue53}/layered_debug_keyboard.kvk | 0 16 files changed, 11 insertions(+), 5 deletions(-) rename web/samples/{issue53.html => issue-53.html} (97%) rename web/samples/{issue53.js => issue-53.js} (100%) rename web/samples/{issues-63.html => issue-63.html} (97%) rename web/samples/{issues-63.js => issue-63.js} (100%) rename web/samples/{issue58 => issue53}/issue58.html (100%) rename web/samples/{issue58 => issue53}/issue58.js (100%) rename web/samples/{issue58 => issue53}/layered_debug_keyboard-1.0.js (100%) rename web/samples/{issue58 => issue53}/layered_debug_keyboard-1.0.json (100%) rename web/samples/{issue58 => issue53}/layered_debug_keyboard-1.0_load.js (100%) rename web/samples/{issue58 => issue53}/layered_debug_keyboard-layout.js (100%) rename web/samples/{issue58 => issue53}/layered_debug_keyboard.ico (100%) rename web/samples/{issue58 => issue53}/layered_debug_keyboard.kmn (100%) rename web/samples/{issue58 => issue53}/layered_debug_keyboard.kpj (100%) rename web/samples/{issue58 => issue53}/layered_debug_keyboard.kvk (100%) diff --git a/web/samples/index.html b/web/samples/index.html index 6e58f6588e..9ce9605dac 100644 --- a/web/samples/index.html +++ b/web/samples/index.html @@ -23,5 +23,9 @@

Test uncompiled Keymanweb

Test fully compiled Keymanweb

Full multilingual (compiled) Keymanweb

+

Uncompiled Keymanweb - test desktop MutationObserver functionality

+

Uncompiled Keymanweb - light test for touch-based MutationObserver functionality

+

Uncompiled Keymanweb - test/stress-test touch-based MutationObserver functionality

+

Uncompiled Keymanweb - test touch-based keyboards with heterogenous layer structures/row counts.

diff --git a/web/samples/issue53.html b/web/samples/issue-53.html similarity index 97% rename from web/samples/issue53.html rename to web/samples/issue-53.html index c40ca5d94f..12714abb39 100644 --- a/web/samples/issue53.html +++ b/web/samples/issue-53.html @@ -51,8 +51,8 @@ - - + + diff --git a/web/samples/issue53.js b/web/samples/issue-53.js similarity index 100% rename from web/samples/issue53.js rename to web/samples/issue-53.js diff --git a/web/samples/issue-62.html b/web/samples/issue-62.html index 0dd68d437c..12124a0e06 100644 --- a/web/samples/issue-62.html +++ b/web/samples/issue-62.html @@ -46,7 +46,8 @@ diff --git a/web/samples/issues-63.html b/web/samples/issue-63.html similarity index 97% rename from web/samples/issues-63.html rename to web/samples/issue-63.html index 6158017025..33efbefcc4 100644 --- a/web/samples/issues-63.html +++ b/web/samples/issue-63.html @@ -46,12 +46,13 @@ - + diff --git a/web/samples/issues-63.js b/web/samples/issue-63.js similarity index 100% rename from web/samples/issues-63.js rename to web/samples/issue-63.js diff --git a/web/samples/issue58/issue58.html b/web/samples/issue53/issue58.html similarity index 100% rename from web/samples/issue58/issue58.html rename to web/samples/issue53/issue58.html diff --git a/web/samples/issue58/issue58.js b/web/samples/issue53/issue58.js similarity index 100% rename from web/samples/issue58/issue58.js rename to web/samples/issue53/issue58.js diff --git a/web/samples/issue58/layered_debug_keyboard-1.0.js b/web/samples/issue53/layered_debug_keyboard-1.0.js similarity index 100% rename from web/samples/issue58/layered_debug_keyboard-1.0.js rename to web/samples/issue53/layered_debug_keyboard-1.0.js diff --git a/web/samples/issue58/layered_debug_keyboard-1.0.json b/web/samples/issue53/layered_debug_keyboard-1.0.json similarity index 100% rename from web/samples/issue58/layered_debug_keyboard-1.0.json rename to web/samples/issue53/layered_debug_keyboard-1.0.json diff --git a/web/samples/issue58/layered_debug_keyboard-1.0_load.js b/web/samples/issue53/layered_debug_keyboard-1.0_load.js similarity index 100% rename from web/samples/issue58/layered_debug_keyboard-1.0_load.js rename to web/samples/issue53/layered_debug_keyboard-1.0_load.js diff --git a/web/samples/issue58/layered_debug_keyboard-layout.js b/web/samples/issue53/layered_debug_keyboard-layout.js similarity index 100% rename from web/samples/issue58/layered_debug_keyboard-layout.js rename to web/samples/issue53/layered_debug_keyboard-layout.js diff --git a/web/samples/issue58/layered_debug_keyboard.ico b/web/samples/issue53/layered_debug_keyboard.ico similarity index 100% rename from web/samples/issue58/layered_debug_keyboard.ico rename to web/samples/issue53/layered_debug_keyboard.ico diff --git a/web/samples/issue58/layered_debug_keyboard.kmn b/web/samples/issue53/layered_debug_keyboard.kmn similarity index 100% rename from web/samples/issue58/layered_debug_keyboard.kmn rename to web/samples/issue53/layered_debug_keyboard.kmn diff --git a/web/samples/issue58/layered_debug_keyboard.kpj b/web/samples/issue53/layered_debug_keyboard.kpj similarity index 100% rename from web/samples/issue58/layered_debug_keyboard.kpj rename to web/samples/issue53/layered_debug_keyboard.kpj diff --git a/web/samples/issue58/layered_debug_keyboard.kvk b/web/samples/issue53/layered_debug_keyboard.kvk similarity index 100% rename from web/samples/issue58/layered_debug_keyboard.kvk rename to web/samples/issue53/layered_debug_keyboard.kvk From f78af56025930ad6165f3c8527653cff4c916402 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 1 Jun 2017 14:45:28 +0700 Subject: [PATCH 4/9] Bringing the formatting up to preferred conventions. --- web/source/keymanweb.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/web/source/keymanweb.js b/web/source/keymanweb.js index 96fbc3b385..751ad802df 100644 --- a/web/source/keymanweb.js +++ b/web/source/keymanweb.js @@ -3656,8 +3656,7 @@ keymanweb.listInputs(); // if something was removed, chances are it's gonna mess up our touch-based layout scheme, so let's update the touch elements. - if(device.touchable) - { + if(device.touchable) { window.setTimeout(function() { for(k = 0; k < keymanweb.sortedInputs.length; k++) { if(keymanweb.sortedInputs[k]['kmw_ip']) { @@ -3726,8 +3725,7 @@ } // Used by the mutation event handler to properly decouple any elements dynamically removed from the document. - keymanweb._MutationRemovalObserved = function(Pelem) - { + keymanweb._MutationRemovalObserved = function(Pelem) { var element = Pelem; if(device.touchable) { element = Pelem['kmw_ip']; From 7320434b188139a09287c3e2522d30bfc1b5ae67 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Thu, 1 Jun 2017 15:38:50 +0700 Subject: [PATCH 5/9] A few variables didn't fully keep up with recent refactoring. --- web/source/keymanweb.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/source/keymanweb.js b/web/source/keymanweb.js index 751ad802df..a01ec74b40 100644 --- a/web/source/keymanweb.js +++ b/web/source/keymanweb.js @@ -3632,9 +3632,9 @@ // Will need to handle this in case of child elements in a newly-added element with child elements. if(removedNode.getElementsByTagName) { inputElementRemovals = inputElementRemovals.concat( - util.arrayFromNodeList(addedNode.getElementsByTagName('input')), - util.arrayFromNodeList(addedNode.getElementsByTagName('textarea')), - util.arrayFromNodeList(addedNode.getElementsByTagName('iframe')) + util.arrayFromNodeList(removedNode.getElementsByTagName('input')), + util.arrayFromNodeList(removedNode.getElementsByTagName('textarea')), + util.arrayFromNodeList(removedNode.getElementsByTagName('iframe')) ); } // After all mutations have been handled, we need to recompile our .sortedInputs array. @@ -3646,7 +3646,7 @@ } for(k = 0; k < childRemovals.length; k++) { - keymanweb._MutationRemovalObserved(childRemovals[k]); + keymanweb._MutationRemovalObserved(inputElementRemovals[k]); } /* After all mutations have been handled, we need to recompile our .sortedInputs array, but only. From 1c5fe171ff8c41d7a860f1d5c23f3d459294a85c Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Mon, 5 Jun 2017 09:14:52 +0700 Subject: [PATCH 6/9] Consolidated timeout/updateInput code; the inputs now work and arrange themselves properly UNLESS readded to the page, which is the one remaining issue at the moment. --- web/source/keymanweb.js | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/web/source/keymanweb.js b/web/source/keymanweb.js index a01ec74b40..9ef78adb90 100644 --- a/web/source/keymanweb.js +++ b/web/source/keymanweb.js @@ -3645,7 +3645,7 @@ keymanweb._MutationAdditionObserved(inputElementAdditions[k]); } - for(k = 0; k < childRemovals.length; k++) { + for(k = 0; k < inputElementRemovals.length; k++) { keymanweb._MutationRemovalObserved(inputElementRemovals[k]); } @@ -3653,11 +3653,12 @@ * if any have actually occurred. */ if(inputElementAdditions.length || inputElementRemovals.length) { - keymanweb.listInputs(); - - // if something was removed, chances are it's gonna mess up our touch-based layout scheme, so let's update the touch elements. - if(device.touchable) { + if(!device.touchable) { + keymanweb.listInputs(); + } else if(device.touchable) { // If something was added or removed, chances are it's gonna mess up our touch-based layout scheme, so let's update the touch elements. window.setTimeout(function() { + keymanweb.listInputs(); + for(k = 0; k < keymanweb.sortedInputs.length; k++) { if(keymanweb.sortedInputs[k]['kmw_ip']) { keymanweb.updateInput(keymanweb.sortedInputs[k]['kmw_ip']); @@ -3711,12 +3712,6 @@ if(Pelem.tagName.toLowerCase() != 'iframe') { if(keymanweb.isKMWInput(Pelem)) { var x = keymanweb.setupTouchElement(Pelem); - - if(x) { - window.setTimeout(function() { - keymanweb.updateInput(x); - }, 1); - } } else { keymanweb.setupNontouchElement(Pelem); } @@ -3729,6 +3724,7 @@ var element = Pelem; if(device.touchable) { element = Pelem['kmw_ip']; + // Remove our touch-based element somehow? } var index = keymanweb.inputList.indexOf(Pelem); if(index != -1) { From 2d8a69b2a0debf42b0aae7ea1a979c32b5484de9 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Mon, 5 Jun 2017 09:30:47 +0700 Subject: [PATCH 7/9] Fixed the re-added element problem, but found a new one: already-added elements don't reposition properly upon a text element resize (Triggered by language change, at minimum). --- web/source/keymanweb.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/web/source/keymanweb.js b/web/source/keymanweb.js index 9ef78adb90..0acf6cc443 100644 --- a/web/source/keymanweb.js +++ b/web/source/keymanweb.js @@ -897,7 +897,10 @@ return null; } - keymanweb.inputList.push(Pelem['kmw_ip']); + keymanweb.inputList.push(Pelem['kmw_ip']); + + console.log("Unexpected state - this element's simulated input DIV should have been removed from the page!"); + return Pelem['kmw_ip']; // May need setup elsewhere since it's just been re-added! } @@ -3711,7 +3714,7 @@ } else { if(Pelem.tagName.toLowerCase() != 'iframe') { if(keymanweb.isKMWInput(Pelem)) { - var x = keymanweb.setupTouchElement(Pelem); + keymanweb.setupTouchElement(Pelem); } else { keymanweb.setupNontouchElement(Pelem); } @@ -3724,7 +3727,10 @@ var element = Pelem; if(device.touchable) { element = Pelem['kmw_ip']; - // Remove our touch-based element somehow? + + // We get weird repositioning errors if we don't remove our simulated input element - and permanently. + Pelem.parentNode.removeChild(element); + Pelem['kmw_ip'] = null; // Erase the evidence that this was ever here. } var index = keymanweb.inputList.indexOf(Pelem); if(index != -1) { From 1d122317d1fd3c910cb86b96eb156b3cb23d7572 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Mon, 5 Jun 2017 09:36:32 +0700 Subject: [PATCH 8/9] Previously-mentioned issue now fixed. #63 ready to ship? --- web/source/keymanweb.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/source/keymanweb.js b/web/source/keymanweb.js index 0acf6cc443..74ced36069 100644 --- a/web/source/keymanweb.js +++ b/web/source/keymanweb.js @@ -1071,7 +1071,15 @@ // It has to be wrapped in an anonymous function to preserve scope and be applied to each element. (function(xx){ xx.base.addEventListener('resize',function(e){ - keymanweb.updateInput(xx); + /* A timeout is needed to let the base element complete its resizing before our + * simulated element can properly resize itself. + * + * Not doing this causes errors if the input elements are resized for whatever reason, such as + * changing languages to a text with greater height. + */ + window.setTimeout(function (){ + keymanweb.updateInput(xx); + }, 1); },false); })(x); From 8e57fc998ac505fcdc8f904a413621c4f39a9d15 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Mon, 5 Jun 2017 10:38:19 +0700 Subject: [PATCH 9/9] Requested refactoring complete; also changed a return type on a new method to boolean to facilitate any future optimization code. --- web/source/keymanweb.js | 42 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/web/source/keymanweb.js b/web/source/keymanweb.js index 74ced36069..519ebb3d2f 100644 --- a/web/source/keymanweb.js +++ b/web/source/keymanweb.js @@ -858,11 +858,7 @@ ); for(var n=0;n