let _debug = false; if(_debug) { console = new Object(); console.log = function(log) { var iframe = document.createElement("IFRAME"); iframe.setAttribute("src", "ios-log:#iOS#" + log); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; if (typeof(window.webkit) != 'undefined') { window.webkit.messageHandlers.keyman.postMessage("ios-log:#iOS#" + log); } }; console.debug = console.log; console.info = console.log; console.warn = console.log; console.error = console.log; window.onerror = function(error, url, line) { console.log('ERROR: '+error+' URL:'+url+' L:'+line); }; } var oskHeight = 0; var oskWidth = 0; var bannerHeight = 0; var bannerImgPath = ''; var sentryManager = new KeymanSentryManager({ hostPlatform: "ios" }); sentryManager.init(); window.addEventListener('load', init, false); function init() { const device = navigator.userAgent.match(/iPad|Macintosh/) ? 'AppleTablet' : 'AppleMobile'; // As of iOS 15, Safari WebViews will try to avoid letting us use the "safe area" // at the bottom of iPhone X style devices. While `-webkit-fill-available` will partly // counteract this... it's only a "partly". Fortunately, we can manually force the // page to our desired size. document.body.style.height = window.outerHeight; var kmw=window['keyman']; kmw['showKeyboardList'] = menuKeyDown; kmw['menuKeyUp'] = menuKeyUp; kmw['hideKeyboard'] = hideKeyboard; kmw['getOskHeight'] = getOskHeight; kmw['getOskWidth'] = getOskWidth; kmw['beepKeyboard'] = beepKeyboard; kmw.init({ 'embeddingApp':device, 'fonts':'fonts/', oninserttext: insertText }).then(function() { if(bannerHeight > 0) { // The OSK is not available until initialization is complete. kmw.osk.bannerView.activeBannerHeight = bannerHeight; keyman.refreshOskLayout(); } }); } function verifyLoaded() { // During proper loads of KMW, a keyboard will be set very early on. // There's a chance that the keyboard is still loading, so we double-check // against the stub count. if(!keyman.core.activeKeyboard && !keyman.keyboardRequisitioner.cache.defaultStub) { location.reload(); } } function showBanner(flag) { console.log("Setting banner display for dictionaryless keyboards to " + flag); var bc = keyman.osk.bannerController; bc.inactiveBanner = flag ? new bc.ImageBanner(bannerImgPath) : null; } function setBannerImage(path) { bannerImgPath = path; var bc = keyman && keyman.osk && keyman.osk.bannerController; if(!bc) { return; } // If an inactive banner is set, update its image. bc.inactiveBanner = bc.inactiveBanner ? new bc.ImageBanner(bannerImgPath) : null; } function setBannerHeight(h) { if(h >= 0) { // The banner itself may not be loaded yet. This will preemptively help set // its eventual display height. bannerHeight = h; if(keyman.osk) { keyman.osk.bannerView.activeBannerHeight = h; } } // Refresh KMW's OSK keyman.refreshOskLayout(); doResetContext(); } function setOskHeight(height) { var kmw=window['keyman']; oskHeight = height; if(kmw && kmw.core && kmw.core.activeKeyboard) { kmw.core.activeKeyboard.refreshLayouts(); } kmw.refreshOskLayout(); doResetContext(); } function setOskWidth(width) { oskWidth = width; } function getOskWidth() { if (oskWidth == 0) oskWidth = Math.abs(window.orientation) == 90 ? screen.height : screen.width; if (Math.abs(window.orientation) == 90) document.body.className="kmw-embedded keyman-app kmw-landscape"; else document.body.className="kmw-embedded keyman-app kmw-portrait"; return oskWidth; } function getOskHeight() { var height = oskHeight; if(keyman.osk.banner._activeType != 'blank') { height = height - keyman.osk.banner.height; } return height; } var keyboardOffset = 0; function setKeymanLanguage(stub) { var kmw = window.keyman; KeymanWeb.registerStub(stub); kmw.setActiveKeyboard(stub.KI, stub.KLC).then(function() { keyman.refreshOskLayout(); doResetContext(); }); } var fragmentToggle = 0; /** * Inserts the selected string s * @param dn Number of pre-caret code points (UTF+8 characters) to delete * @param s Text to insert * @param dr Number of post-caret code points to delete. (optional) */ function insertText(dn, s, dr) { dr = dr || 0; // Sets a default value of zero when dr is undefined fragmentToggle = (fragmentToggle + 1) % 100; var insertHash = 'insertText-'+ fragmentToggle + '+dn=' + dn + '+s=' + toHex(s) + '+dr=' + dr; if (typeof(window.webkit) != 'undefined') window.webkit.messageHandlers.keyman.postMessage('#' + insertHash); } function beepKeyboard() { fragmentToggle = (fragmentToggle + 1) % 100; var beepHash = 'beep-'+ fragmentToggle; if(typeof(window.webkit) != 'undefined') { window.webkit.messageHandlers.keyman.postMessage('#' + beepHash); } } function oskCreateKeyPreview(x,y,w,h,t) { fragmentToggle = (fragmentToggle + 1) % 100; var div = document.createElement('div'); div.innerHTML = t; var dt = div.firstChild.nodeValue; var previewHash = 'showKeyPreview-'+fragmentToggle+'+x='+x+'+y='+y+'+w='+w+'+h='+h+'+t='+toHex(dt); //window.location.hash = 'showKeyPreview-'+fragmentToggle+'+x='+x+'+y='+y+'+w='+w+'+h='+h+'+t='+toHex(dt); if (typeof(window.webkit) != 'undefined') window.webkit.messageHandlers.keyman.postMessage('#' + previewHash); } function oskClearKeyPreview() { fragmentToggle = (fragmentToggle + 1) % 100; var dismissHash = 'dismissKeyPreview-'+fragmentToggle; //window.location.hash = 'dismissKeyPreview-'+fragmentToggle; if (typeof(window.webkit) != 'undefined') window.webkit.messageHandlers.keyman.postMessage('#' + dismissHash); } oskCreatePopup = function(obj,x,y,w,h) { if(obj != null) { var i; var s = ''; var shift = false; var frame = x.toString() + ',' + y.toString() + ',' + w.toString() + ',' + h.toString(); for(i=0; i => NaN; undefined + undefined => NaN. let selEnd = selStart + selLength; selEnd = isNaN(selEnd) ? undefined : selEnd; const shouldReset = keyman.context.updateContext(text, selStart, selEnd); if(!doSync || shouldReset) { keyman.resetContext(); } } function executePopupKey(keyID, keyText) { var kmw=window['keyman']; kmw['executePopupKey'](keyID, keyText); } function popupVisible(value) { var kmw=window['keyman']; kmw['popupVisible'](value); } function toHex(theString) { var hexString = ''; for (var i=0; i < theString.length; i++) { var theHex = theString.charCodeAt(i).toString(16).toUpperCase(); while (theHex.length < 4) { theHex = '0' + theHex; } theHex = '0x' + theHex; hexString += theHex + ','; } return hexString.substr(0, hexString.length-1); } function enableSuggestions(model, mayPredict, mayCorrect) { // Set the options first so that KMW's ModelManager can properly handle model enablement states // the moment we actually register the new model. keyman.core.languageProcessor.mayPredict = mayPredict; keyman.core.languageProcessor.mayCorrect = mayCorrect; keyman.addModel(model); } function setSpacebarText(mode) { keyman.config.spacebarText = mode; }