-
-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(android): Always display HTML banner when suggestions aren't available #9696
Changes from 44 commits
4273140
9b06591
d3872ee
3a785f5
b46d50f
3df2668
131180c
db728df
b91d651
7d3de5a
018abd4
a5aef7a
510de72
d366f33
b45c61e
8a48fd2
bb5a9f8
a6b7b95
926a2a2
6247a52
8630121
1e30002
6535acd
6593ae2
11af550
1d40beb
8961e9d
6170e04
c619873
cb431fe
879129e
263da40
712b2a2
856ed13
830c282
27480eb
095b823
c83410a
d6a14a8
35a37bc
76eab6e
0bcdea1
887e6b2
68f2661
44fa59b
8249abd
37e9cf5
37e9bbd
b41f049
2b34c64
4c453cc
d77df39
4ebc1e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,10 @@ | ||||||||||||||||||
<!-- Custom banner theme --> | ||||||||||||||||||
<div style="background: white; width: 100%; height: 100%; position: absolute; left: 0; top: 0"> | ||||||||||||||||||
<!--<div style="height: 1px; left: 0; position: absolute; top: 0; width: 100%; background: black"></div>--> | ||||||||||||||||||
<img src="$BANNER" style="height:100%; background: white; display: block"> | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm no CSS wizard, but...
Suggested change
Something like this should help us shrink the image.
Just spitballing an idea, but you may wish to replace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, a small warning before you consider getting fancy: https://css-tricks.com/oh-hey-padding-percentage-is-based-on-the-parent-elements-width/ Padding percentage doesn't work ideally for us here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll update the user-testing screenshots with some updated styling ( |
||||||||||||||||||
|
||||||||||||||||||
<!-- Tri-color line --> | ||||||||||||||||||
<div style="height: 7%; left: 0; position: absolute; bottom: 0; width: 56%; background: #F68924"></div> | ||||||||||||||||||
<div style="height: 7%; left: 56%; position: absolute; bottom: 0; width: 23%; background: #CC3846"></div> | ||||||||||||||||||
<div style="height: 7%; left: 79%; position: absolute; bottom: 0; width: 21%; background: #79C3DA"></div> | ||||||||||||||||||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.keyman.android; | ||
|
||
import android.content.Context; | ||
|
||
import com.keyman.engine.KMManager; | ||
import com.keyman.engine.util.FileUtils; | ||
|
||
import java.io.File; | ||
|
||
public class BannerController { | ||
|
||
// Paths relative to assets folder for banner themes | ||
public static final String KM_BANNER_THEME_KEYMAN = "svg/banner.html"; | ||
public static final String KM_BANNER_THEME_KEYMAN_SVG = "svg/keyman_banner.svg"; | ||
|
||
|
||
public static void setHTMLBanner(Context context, KMManager.KeyboardType keyboardType) { | ||
if (keyboardType == KMManager.KeyboardType.KEYBOARD_TYPE_UNDEFINED) { | ||
return; | ||
} | ||
|
||
// Always use Keyman banner theme | ||
String contents = FileUtils.readContents(context, KM_BANNER_THEME_KEYMAN); | ||
|
||
// If $BANNER string exists, replace with actual path | ||
File bannerPath = new File(KMManager.getResourceRoot(), KM_BANNER_THEME_KEYMAN_SVG); | ||
if (bannerPath.exists()) { | ||
contents = contents.replace("$BANNER", bannerPath.getAbsolutePath()); | ||
} | ||
|
||
KMManager.setHTMLBanner(keyboardType, contents); | ||
KMManager.setBanner(keyboardType, KMManager.BannerType.HTML); | ||
KMManager.showBanner(true); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -8,6 +8,9 @@ if(window.parent && window.parent.jsInterface && !window.jsInterface) { | |||||||||||||||||
var device = window.jsInterface.getDeviceType(); | ||||||||||||||||||
var oskHeight = Math.ceil(window.jsInterface.getKeyboardHeight() / window.devicePixelRatio); | ||||||||||||||||||
var oskWidth = 0; | ||||||||||||||||||
var bannerHeight = 0; | ||||||||||||||||||
var bannerImagePath = ''; | ||||||||||||||||||
var bannerHTMLContents = ''; | ||||||||||||||||||
var fragmentToggle = 0; | ||||||||||||||||||
|
||||||||||||||||||
var sentryManager = new KeymanSentryManager({ | ||||||||||||||||||
|
@@ -37,11 +40,13 @@ function init() { | |||||||||||||||||
oninserttext: insertText, | ||||||||||||||||||
root:'./' | ||||||||||||||||||
}).then(function () { // Note: For non-upgraded API 21, arrow functions will break the keyboard! | ||||||||||||||||||
const bannerHeight = Math.ceil(window.jsInterface.getDefaultBannerHeight() / window.devicePixelRatio); | ||||||||||||||||||
bannerHeight = Math.ceil(window.jsInterface.getDefaultBannerHeight() / window.devicePixelRatio); | ||||||||||||||||||
if (bannerHeight > 0) { | ||||||||||||||||||
|
||||||||||||||||||
// The OSK is not available until initialization is complete. | ||||||||||||||||||
keyman.osk.bannerView.activeBannerHeight = bannerHeight; | ||||||||||||||||||
keyman.refreshOskLayout(); | ||||||||||||||||||
// The OSK is not available until initialization is complete. | ||||||||||||||||||
keyman.osk.bannerView.activeBannerHeight = bannerHeight; | ||||||||||||||||||
keyman.refreshOskLayout(); | ||||||||||||||||||
} | ||||||||||||||||||
}); | ||||||||||||||||||
|
||||||||||||||||||
keyman.addEventListener('keyboardloaded', setIsChiral); | ||||||||||||||||||
|
@@ -53,6 +58,29 @@ function init() { | |||||||||||||||||
notifyHost('pageLoaded'); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
function showBanner(flag) { | ||||||||||||||||||
console_debug("Setting banner display for dictionaryless keyboards to " + flag); | ||||||||||||||||||
console_debug("bannerHTMLContents: " + bannerHTMLContents); | ||||||||||||||||||
var bc = keyman.osk.bannerController; | ||||||||||||||||||
if (bc) { | ||||||||||||||||||
if (bannerHTMLContents != '') { | ||||||||||||||||||
bc.inactiveBanner = flag ? new bc.HTMLBanner(bannerHTMLContents) : null; | ||||||||||||||||||
} else { | ||||||||||||||||||
bc.inactiveBanner = flag ? new bc.ImageBanner(bannerImgPath) : null; | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
function setBannerImage(path) { | ||||||||||||||||||
bannerImgPath = path; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
// Set the HTML banner to use when predictive-text is not available | ||||||||||||||||||
// contents - HTML content to use for the banner | ||||||||||||||||||
function setBannerHTML(contents) { | ||||||||||||||||||
bannerHTMLContents = contents; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
function notifyHost(event, params) { | ||||||||||||||||||
console_debug('notifyHost(event='+event+',params='+params+')'); | ||||||||||||||||||
// TODO: Update all other host notifications to use notifyHost instead of directly setting window.location.hash | ||||||||||||||||||
|
@@ -65,13 +93,21 @@ function notifyHost(event, params) { | |||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
// Update the KMW banner height | ||||||||||||||||||
// h is in dpi (different from iOS) | ||||||||||||||||||
function setBannerHeight(h) { | ||||||||||||||||||
if (h > 0) { | ||||||||||||||||||
var osk = keyman.osk; | ||||||||||||||||||
osk.banner.height = Math.ceil(h / window.devicePixelRatio); | ||||||||||||||||||
// The banner itself may not be loaded yet. This will preemptively help set | ||||||||||||||||||
// its eventual display height. | ||||||||||||||||||
bannerHeight = Math.ceil(h / window.devicePixelRatio); | ||||||||||||||||||
|
||||||||||||||||||
if (keyman.osk) { | ||||||||||||||||||
keyman.osk.bannerView.activeBannerHeight = bannerHeight; | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
// Refresh KMW OSK | ||||||||||||||||||
|
||||||||||||||||||
// Refresh KMW's OSK | ||||||||||||||||||
keyman.refreshOskLayout(); | ||||||||||||||||||
doResetContext(); | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to reset the context when adjusting the banner? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I got the pattern from ios-host.js There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reverted this and the other call too |
||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
function setOskHeight(h) { | ||||||||||||||||||
|
@@ -82,6 +118,7 @@ function setOskHeight(h) { | |||||||||||||||||
keyman.core.activeKeyboard.refreshLayouts(); | ||||||||||||||||||
} | ||||||||||||||||||
keyman.refreshOskLayout(); | ||||||||||||||||||
doResetContext(); | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to reset the context when adjusting the keyboard height? |
||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
function setOskWidth(w) { | ||||||||||||||||||
|
@@ -168,18 +205,13 @@ function enableSuggestions(model, mayPredict, mayCorrect) { | |||||||||||||||||
keyman.core.languageProcessor.mayPredict = mayPredict; | ||||||||||||||||||
keyman.core.languageProcessor.mayCorrect = mayCorrect; | ||||||||||||||||||
|
||||||||||||||||||
registerModel(model); | ||||||||||||||||||
keyman.addModel(model); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
function setBannerOptions(mayPredict) { | ||||||||||||||||||
keyman.core.languageProcessor.mayPredict = mayPredict; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
function registerModel(model) { | ||||||||||||||||||
//window.console.log('registerModel: ' + model); | ||||||||||||||||||
keyman.addModel(model); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this change in this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I originally started banner management by keeping similarity with ios-host.js keyman/ios/engine/KMEI/KeymanEngine/resources/Keyman.bundle/Contents/Resources/ios-host.js Lines 323 to 330 in 8ebb725
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reverted |
||||||||||||||||||
function resetContext() { | ||||||||||||||||||
keyman.resetContext(); | ||||||||||||||||||
} | ||||||||||||||||||
|
@@ -269,6 +301,10 @@ function hideKeyboard() { | |||||||||||||||||
window.location.hash = 'hideKeyboard' + fragmentToggle; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
function doResetContext() { | ||||||||||||||||||
keyman.resetContext(); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
darcywong00 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
function showKeyboard() { | ||||||||||||||||||
// Refresh KMW OSK | ||||||||||||||||||
keyman.refreshOskLayout(); | ||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -7,13 +7,11 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||
import java.io.File; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.ArrayList; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.HashMap; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
import org.json.JSONArray; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import org.json.JSONException; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import org.json.JSONObject; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
import com.keyman.engine.BaseActivity; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import com.keyman.engine.data.Keyboard; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import com.keyman.engine.data.KeyboardController; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import com.keyman.engine.KMManager.KeyboardType; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -25,19 +23,11 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||
import com.keyman.engine.util.KMLog; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import com.keyman.engine.util.KMString; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
import android.Manifest; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.annotation.SuppressLint; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.content.Context; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.content.SharedPreferences; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.content.pm.ApplicationInfo; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.content.pm.PackageManager; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.content.res.Configuration; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.graphics.Color; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.graphics.Rect; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.graphics.RectF; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.graphics.Typeface; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.os.Build; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.os.Bundle; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.os.Handler; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.util.DisplayMetrics; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.util.Log; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -46,7 +36,6 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||
import android.view.LayoutInflater; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.view.MotionEvent; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.view.View; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.view.ViewGroup; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.view.WindowManager; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.view.inputmethod.ExtractedText; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.view.inputmethod.ExtractedTextRequest; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -56,12 +45,9 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||
import android.webkit.WebSettings; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.webkit.WebView; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.widget.Button; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.widget.FrameLayout; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.widget.GridLayout; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.widget.PopupWindow; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.widget.PopupWindow.OnDismissListener; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.widget.RelativeLayout; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.widget.TextView; | ||||||||||||||||||||||||||||||||||||||||||||||||||
import android.widget.Toast; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
import io.sentry.Breadcrumb; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -84,19 +70,10 @@ final class KMKeyboard extends WebView { | |||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
private static String currentKeyboard = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||
* Banner state value: "blank" - no banner available. | ||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||
protected static final String KM_BANNER_STATE_BLANK = "blank"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||
* Banner state value: "suggestion" - dictionary suggestions are shown. | ||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||
protected static final String KM_BANNER_STATE_SUGGESTION = "suggestion"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||
* Current banner state. | ||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||
protected static String currentBanner = KM_BANNER_STATE_BLANK; | ||||||||||||||||||||||||||||||||||||||||||||||||||
protected static KMManager.BannerType currentBanner = KMManager.BannerType.HTML; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
private static String txtFont = ""; | ||||||||||||||||||||||||||||||||||||||||||||||||||
private static String oskFont = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -105,6 +82,10 @@ final class KMKeyboard extends WebView { | |||||||||||||||||||||||||||||||||||||||||||||||||
private GestureDetector gestureDetector; | ||||||||||||||||||||||||||||||||||||||||||||||||||
private static ArrayList<OnKeyboardEventListener> kbEventListeners = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Stores the current html string for use by the Banner | ||||||||||||||||||||||||||||||||||||||||||||||||||
// when predictive text is not active | ||||||||||||||||||||||||||||||||||||||||||||||||||
protected String htmlBannerString = ""; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Facilitates a 'lazy init' - we'll only check the preference when it matters, | ||||||||||||||||||||||||||||||||||||||||||||||||||
// rather than at construction time. | ||||||||||||||||||||||||||||||||||||||||||||||||||
private Boolean _shouldShowHelpBubble = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -400,6 +381,9 @@ public void onConfigurationChanged(Configuration newConfig) { | |||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
int bannerHeight = KMManager.getBannerHeight(context); | ||||||||||||||||||||||||||||||||||||||||||||||||||
int oskHeight = KMManager.getKeyboardHeight(context); | ||||||||||||||||||||||||||||||||||||||||||||||||||
if (this.htmlBannerString != null && !this.htmlBannerString.isEmpty()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
loadJavascript(KMString.format("setBannerHTML('%s')", this.htmlBannerString)); | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will this work with arbitrary HTML, even HTML that contains There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And shouldn't this read:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is setting up a WebView operation. Don't forget about that JS queue we set up a while back; this adds an entry to that queue (when necessary). (We are on the Java / Android side here; your suggestion would be a JS-side call.) We want the equivalent of what you've typed when within the WebView; the trick is making sure the values marshal across the WebView boundary properly in order to do so. We'd probably be best off by using I forget how we do the JSON.stringify bit within Java-land, but I know it's an existing pattern already in the code base. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if you are responding to my suggestion here @jahorton?
See ll.387-389. those are also all calling
See ll.650-654. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, all of these should be setup as a single There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #8534 - what has been noted here is a very likely contributor to that issue. If those calls are kept separately, each call is a separate async call into the WebView, and those delays could very easily contribute to layout reflow / flashing... especially since each affects the keyboard's layout. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For proper escaping, here's the basic pattern: keyman/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java Lines 618 to 636 in 5a0c1a3
Something like:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This will be addressed on separate PR |
||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
loadJavascript(KMString.format("setBannerHeight(%d)", bannerHeight)); | ||||||||||||||||||||||||||||||||||||||||||||||||||
loadJavascript(KMString.format("setOskWidth(%d)", newConfig.screenWidthDp)); | ||||||||||||||||||||||||||||||||||||||||||||||||||
loadJavascript(KMString.format("setOskHeight(%d)", oskHeight)); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -425,22 +409,15 @@ public static String currentKeyboard() { | |||||||||||||||||||||||||||||||||||||||||||||||||
return currentKeyboard; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
public static void setCurrentBanner(String banner) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
currentBanner = banner; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
public static String currentBanner() { return currentBanner; } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
protected void toggleSuggestionBanner(HashMap<String, String> associatedLexicalModel, boolean keyboardChanged) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
//reset banner state if new language has no lexical model | ||||||||||||||||||||||||||||||||||||||||||||||||||
if (currentBanner != null && currentBanner.equals(KM_BANNER_STATE_SUGGESTION) | ||||||||||||||||||||||||||||||||||||||||||||||||||
if (currentBanner == KMManager.BannerType.SUGGESTION | ||||||||||||||||||||||||||||||||||||||||||||||||||
&& associatedLexicalModel == null) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
setCurrentBanner(KMKeyboard.KM_BANNER_STATE_BLANK); | ||||||||||||||||||||||||||||||||||||||||||||||||||
currentBanner = KMManager.BannerType.HTML; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
if(keyboardChanged) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
setLayoutParams(KMManager.getKeyboardLayoutParams()); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
showBanner(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||
// Since there's always a banner, no need to update setLayoutParams() | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -653,6 +630,29 @@ public boolean setKeyboard(String packageID, String keyboardID, String languageI | |||||||||||||||||||||||||||||||||||||||||||||||||
return retVal; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
public void showBanner(boolean flag) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
String jsString = KMString.format("showBanner(%b)", flag); | ||||||||||||||||||||||||||||||||||||||||||||||||||
loadJavascript(jsString); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
public KMManager.BannerType getBanner() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
return currentBanner; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
public void setBanner(KMManager.BannerType bannerType) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
currentBanner = bannerType; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
public String getHTMLBanner() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
return this.htmlBannerString; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
public void setHTMLBanner(String contents) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
this.htmlBannerString = contents; | ||||||||||||||||||||||||||||||||||||||||||||||||||
String jsString = KMString.format("setBannerHTML('%s')", contents); | ||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will this work with arbitrary HTML, even HTML that contains There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handled now with JSONObject.quote() |
||||||||||||||||||||||||||||||||||||||||||||||||||
loadJavascript(jsString); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
public void setChirality(boolean flag) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
this.isChiral = flag; | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -173,8 +173,7 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { | |
if (KMManager.currentLexicalModel != null) { | ||
modelPredictionPref = prefs.getBoolean(KMManager.getLanguagePredictionPreferenceKey(KMManager.currentLexicalModel.get(KMManager.KMKey_LanguageID)), true); | ||
} | ||
kmKeyboard.setCurrentBanner((isModelActive && modelPredictionPref) ? | ||
KMKeyboard.KM_BANNER_STATE_SUGGESTION : KMKeyboard.KM_BANNER_STATE_BLANK); | ||
KMManager.setBannerOptions(isModelActive && modelPredictionPref); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This tells KMW whether predictions are enabled or not |
||
RelativeLayout.LayoutParams params = KMManager.getKeyboardLayoutParams(); | ||
kmKeyboard.setLayoutParams(params); | ||
} else if (url.indexOf("suggestPopup") >= 0) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<img src="banner/keyman_banner.svg" ...
in banner.htmlKMManager.copyHTMLBannerAssets(path)
will callcopyAsset()
for each file in the path to copy it to the resources 'banner/' folder:copyAsset(context, filename, "banner/", true)