Fixed up attachType:'manual' code and performed some requested refactoring.

This commit is contained in:
Joshua Horton 2017-05-31 08:36:38 +07:00
parent 352cb66de5
commit 8d27f85e39
3 changed files with 177 additions and 60 deletions

View file

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<!-- Set the viewport width to match phone and tablet device widths -->
<meta name="viewport" content="width=device-width,user-scalable=no" />
<!-- Allow KeymanWeb to be saved to the iPhone home screen -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- Enable IE9 Standards mode -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>KeymanWeb Sample Page - Uncompiled Source</title>
<!-- Your page CSS -->
<style type='text/css'>
body {font-family: Tahoma,helvetica;}
h3 {font-size: 1em;font-weight:normal;color: darkred; margin-bottom: 4px}
.test {font-size: 1.5em; width:80%; min-height:30px; border: 1px solid gray;}
#KeymanWebControl {width:50%;min-width:600px;}
</style>
<!-- Insert uncompiled KeymanWeb source scripts -->
<script src="../source/kmwstring.js" type="application/javascript"></script>
<script src="../source/kmwbase.js" type="application/javascript"></script>
<script src="../source/keymanweb.js" type="application/javascript"></script>
<script src="../source/kmwosk.js" type="application/javascript"></script>
<script src="../source/kmwnative.js" type="application/javascript"></script>
<script src="../source/kmwcallback.js" type="application/javascript"></script>
<script src="../source/kmwkeymaps.js" type="application/javascript"></script>
<script src="../source/kmwlayout.js" type="application/javascript"></script>
<script src="../source/kmwinit.js" type="application/javascript"></script>
<!--
For desktop browsers, a script for the user interface must be inserted here.
Standard UIs are toggle, button, float and toolbar.
The toolbar UI is best for any page designed to support keyboards for
a large number of languages.
-->
<script src="../source/kmwuitoggle.js"></script>
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
<script>
var kmw=window.tavultesoft.keymanweb;
kmw.init({
resources:'resources',
attachType:'manual'
});
</script>
<!-- Add keyboard management script for local selection of keyboards to use -->
<script src="./samplehdr.js"></script>
</head>
<!-- Sample page HTML -->
<body onload='loadKeyboards();'>
<h2>KeymanWeb Sample Page - Uncompiled Source</h2>
<div>
<!--
The following DIV is used to position the Button or Toolbar User Interfaces on the page.
If omitted, those User Interfaces will appear at the top of the document body.
(It is ignored by other User Interfaces.)
-->
<div id='KeymanWebControl'></div>
<h3>Type in your language in this text area:</h3>
<textarea id='ta1' class='test' placeholder='Type here'></textarea>
<h3>or in this input field:</h3>
<input class='test' value='' placeholder='or here'/>
<!-- The following elements show how the language menu can be dynamically extended at any time -->
<h3>Add a keyboard by keyboard name:</h3>
<input type='input' id='kbd_id1' class='kmw-disabled' onkeypress="clickOnEnter(event,1);"/>
<input type='button' id='btn1' onclick='addKeyboard(1);' value='Add' />
<h3>Add a keyboard by ISO 639 language code:</h3>
<input type='input' id='kbd_id2' class='kmw-disabled' onkeypress="clickOnEnter(event,2);"/>
<input type='button' id='btn2' onclick='addKeyboard(2);' value='Add' />
<h3>Add a keyboard by language name:</h3>
<input type='input' id='kbd_id3' class='kmw-disabled' onkeypress="clickOnEnter(event,3);"/>
<input type='button' id='btn3' onclick='addKeyboard(3);' value='Add' />
<h3><a href="../samples/index.html">Return to testing home page</a></h3>
</div>
</body>
<!--
*** DEVELOPER NOTE -- FIREFOX CONFIGURATION FOR TESTING ***
*
* If the URL bar starts with <b>file://</b>, Firefox may not load the font used
* to display the special characters used in the On-Screen Keyboard.
*
* To work around this Firefox bug, navigate to <b>about:config</b>
* and set <b>security.fileuri.strict_origin_policy</b> to <b>false</b>
* while testing.
*
* Firefox resolves website-based CSS URI references correctly without needing
* any configuration change, so this change should only be made for file-based testing.
*
***
-->
</html>

View file

@ -1022,13 +1022,11 @@
* Description Save list of inputs for non-touch devices (desktop browsers)
*/
keymanweb.setupDesktopPage = function() {
for(var k=0; k<2; k++) {
var ipList=document.getElementsByTagName(k==0?'INPUT':'TEXTAREA');
for(var n=0;n<ipList.length;n++) {
// Registers all relevant static elements on the page.
keymanweb.setupDesktopElement(ipList[n]);
}
}
var ipList = [].concat(
util.arrayFromNodeList(document.getElementsByTagName('input')),
util.arrayFromNodeList(document.getElementsByTagName('textarea'))
);
ipList.forEach(keymanweb.setupDesktopElement);
}
/**
@ -3539,75 +3537,71 @@
// Restore and reload the currently selected keyboard
keymanweb.restoreCurrentKeyboard();
/* Setup of handlers for dynamically-added and (eventually) dynamically-removed elements.
* Reference: https://developer.mozilla.org/en/docs/Web/API/MutationObserver
*
* We place it here so that it loads after most of the other UI loads, reducing the MutationObserver's overhead.
*/
/* Setup of handlers for dynamically-added and (eventually) dynamically-removed elements.
* Reference: https://developer.mozilla.org/en/docs/Web/API/MutationObserver
*
* We place it here so that it loads after most of the other UI loads, reducing the MutationObserver's overhead.
* Of course, we only want to dynamically add elements if the user hasn't enabled the manual attachment option.
*/
if(keymanweb.options['attachType'] != 'manual') { //I1961
var observationTarget = document.querySelector('body');
var k; // our other iteration variables have already been declared previously.
keymanweb.mutationObserver = new MutationObserver(function(mutations) {
var dirtyFlag = false; // Notes if we need to recompute our .sortedInputs array.
var inputElementAdditions = [];
for(var i=0; i < mutations.length; i++) {
var mutation = mutations[i];
for(var j=0; j < mutation.addedNodes.length; j++) {
var addedNode = mutation.addedNodes[j];
var lcTagName = "";
if(addedNode.tagName) {
lcTagName = addedNode.tagName.toLowerCase();
}
var childAdditions = [];
var arrayFromNodeList = function(nl) {
var res = [];
for(var i=0; i < nl.length; i++) {
res.push(nl[i]);
}
return res;
}
for(var i=0; i < mutations.length; i++) {
var mutation = mutations[i];
for(var j=0; j < mutation.addedNodes.length; j++) {
var addedNode = mutation.addedNodes[j];
var lcTagName = addedNode.tagName ? addedNode.tagName.toLowerCase() : "";
// Will need to handle this in case of child elements in a newly-added element with child elements.
if(addedNode.getElementsByTagName) {
childAdditions = childAdditions.concat(
arrayFromNodeList(addedNode.getElementsByTagName('input')),
arrayFromNodeList(addedNode.getElementsByTagName('textarea')),
arrayFromNodeList(addedNode.getElementsByTagName('iframe'))
);
}
if(lcTagName == 'input' || lcTagName == 'textarea' || lcTagName == 'iframe') {
dirtyFlag = true;
keymanweb._MutationAdditionObserved(addedNode);
}
for(k = 0; k < childAdditions.length; k++) {
dirtyFlag = true;
keymanweb._MutationAdditionObserved(childAdditions[k]);
}
// Will need to handle this in case of child elements in a newly-added element with child elements.
if(addedNode.getElementsByTagName) {
inputElementAdditions = inputElementAdditions.concat(
util.arrayFromNodeList(addedNode.getElementsByTagName('input')),
util.arrayFromNodeList(addedNode.getElementsByTagName('textarea')),
util.arrayFromNodeList(addedNode.getElementsByTagName('iframe'))
);
}
// There also exists a 'mutation.removedNodes' array. We'll need to address that for issue #63.
// After all mutations have been handled, we need to recompile our .sortedInputs array.
if(dirtyFlag) {
keymanweb.listInputs();
if(lcTagName == 'input' || lcTagName == 'textarea' || lcTagName == 'iframe') {
inputElementAdditions.push(addedNode);
}
}
});
// There also exists a 'mutation.removedNodes' array. We'll need to address that for issue #63.
/* After all mutations have been handled, we need to recompile our .sortedInputs array, but only.
* if any have actually occurred.
*/
if(inputElementAdditions.length) {
keymanweb.listInputs();
}
}
for(var k = 0; k < inputElementAdditions.length; k++) {
keymanweb._MutationAdditionObserved(inputElementAdditions[k]);
}
});
var observationConfig = { childList: true, subtree: true };
keymanweb.mutationObserver.observe(observationTarget, observationConfig);
}
// Set exposed initialization flag to 2 to indicate deferred initialization also complete
keymanweb['initialized']=2;
}
// Used by the MutationObserver event handler to properly setup any elements dynamically added to the document post-initialization.
/**
* Function _MutationAdditionObserved
* Scope Private
* @param {Object} Pelem A page input, textarea, or iframe element.
* Description Used by the MutationObserver event handler to properly setup any elements dynamically added to the document post-initialization.
*
*/
keymanweb._MutationAdditionObserved = function(Pelem) {
if(!device.touchable) {
// keymanweb.attachToControl is written to handle iframes, but setupDesktopElement is not.

View file

@ -142,9 +142,21 @@ var __BUILD__ = 300;
{
osk.addEventListener('positionChanged', ui.oskPositionChanged);
}
*/
*/
/**
* Function arrayFromNodeList
* Scope Public
* @param {Object} nl a node list, as returned from getElementsBy_____ methods.
* Description Transforms a node list into an array. *
*/
util.arrayFromNodeList = function(nl) {
var res = [];
for(var i=0; i < nl.length; i++) {
res.push(nl[i]);
}
return res;
}
/**
* Function addEventListener