mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-16 05:39:24 +00:00
Filters out prefixed LTR/RTL marks from context.
This commit is contained in:
parent
fcbd7db229
commit
dbbeccebdb
5 changed files with 43 additions and 41 deletions
|
|
@ -201,8 +201,7 @@ open class InputViewController: UIInputViewController, KeymanWebDelegate {
|
|||
newRange = context.startIndex..<context.startIndex
|
||||
}
|
||||
|
||||
setText(context)
|
||||
setSelectionRange(NSRange(newRange, in: context), manually: false)
|
||||
setContextState(text: context, range: NSRange(newRange, in: context))
|
||||
}
|
||||
|
||||
func insertText(_ keymanWeb: KeymanWebViewController, numCharsToDelete: Int, newText: String) {
|
||||
|
|
@ -411,24 +410,35 @@ open class InputViewController: UIInputViewController, KeymanWebDelegate {
|
|||
func showHelpBubble(afterDelay delay: TimeInterval) {
|
||||
keymanWeb.showHelpBubble(afterDelay: delay)
|
||||
}
|
||||
|
||||
// func setCursorRange(_ range: NSRange) {
|
||||
// keymanWeb.setCursorRange(range)
|
||||
// }
|
||||
|
||||
func setText(_ text: String?) {
|
||||
keymanWeb.setText(text)
|
||||
}
|
||||
|
||||
|
||||
func clearText() {
|
||||
setText(nil)
|
||||
setSelectionRange(NSRange(location: 0, length: 0), manually: true)
|
||||
setContextState(text: nil, range: NSRange(location: 0, length: 0))
|
||||
log.info("Cleared text.")
|
||||
}
|
||||
|
||||
func setSelectionRange(_ range: NSRange, manually: Bool) {
|
||||
|
||||
func setContextState(text: String?, range: NSRange) {
|
||||
// Check for any LTR or RTL marks at the context's start; if they exist, we should
|
||||
// offset the selection range.
|
||||
let characterOrderingChecks = [ "\u{200e}" /*LTR*/, "\u{202e}" /*RTL 1*/, "\u{200f}" /*RTL 2*/ ]
|
||||
var offsetPrefix = false;
|
||||
|
||||
let context = text ?? ""
|
||||
|
||||
for codepoint in characterOrderingChecks {
|
||||
if(context.hasPrefix(codepoint)) {
|
||||
offsetPrefix = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var selRange = range;
|
||||
if(offsetPrefix) { // If we have a character ordering mark, offset range location to hide it.
|
||||
selRange = NSRange(location: selRange.location - 1, length: selRange.length)
|
||||
}
|
||||
|
||||
keymanWeb.setText(context)
|
||||
if range.location != NSNotFound {
|
||||
keymanWeb.setCursorRange(range)
|
||||
keymanWeb.setCursorRange(selRange)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -184,6 +184,12 @@ extension KeymanWebViewController {
|
|||
|
||||
func setText(_ text: String?) {
|
||||
var text = text ?? ""
|
||||
// Remove any system-added LTR/RTL marks.
|
||||
text = text.replacingOccurrences(of: "\u{200e}", with: "") // Unicode's LTR codepoint
|
||||
text = text.replacingOccurrences(of: "\u{200f}", with: "") // Unicode's RTL codepoint (v1)
|
||||
text = text.replacingOccurrences(of: "\u{202e}", with: "") // Unicode's RTL codepoint (v2)
|
||||
|
||||
// JavaScript escape-sequence encodings.
|
||||
text = text.replacingOccurrences(of: "\\", with: "\\\\")
|
||||
text = text.replacingOccurrences(of: "'", with: "\\'")
|
||||
text = text.replacingOccurrences(of: "\n", with: "\\n")
|
||||
|
|
|
|||
|
|
@ -903,16 +903,12 @@ public class Manager: NSObject, HTTPDownloadDelegate, UIGestureRecognizerDelegat
|
|||
Manager.shared.inputViewController.resetKeyboardState()
|
||||
}
|
||||
|
||||
func setText(_ text: String?) {
|
||||
inputViewController.setText(text)
|
||||
}
|
||||
|
||||
func clearText() {
|
||||
inputViewController.clearText()
|
||||
}
|
||||
|
||||
func setSelectionRange(_ range: NSRange, manually: Bool) {
|
||||
inputViewController.setSelectionRange(range, manually: manually)
|
||||
func setContextState(text: String?, range: NSRange) {
|
||||
inputViewController.setContextState(text: text, range: range)
|
||||
}
|
||||
|
||||
var vibrationSupportLevel: VibrationSupport {
|
||||
|
|
|
|||
|
|
@ -112,11 +112,11 @@ public class TextField: UITextField, KeymanResponder {
|
|||
super.text = ""
|
||||
}
|
||||
|
||||
Manager.shared.setText(self.text)
|
||||
let textRange = selectedTextRange ?? UITextRange()
|
||||
let newRange = NSRange(location: offset(from: beginningOfDocument, to: textRange.start),
|
||||
length: offset(from: textRange.start, to: textRange.end))
|
||||
Manager.shared.setSelectionRange(newRange, manually: false)
|
||||
|
||||
Manager.shared.setContextState(text: self.text, range: newRange)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +127,8 @@ public class TextField: UITextField, KeymanResponder {
|
|||
}
|
||||
let newRange = NSRange(location: offset(from: beginningOfDocument, to: range.start),
|
||||
length: offset(from: range.start, to: range.end))
|
||||
Manager.shared.setSelectionRange(newRange, manually: false)
|
||||
|
||||
Manager.shared.setContextState(text: self.text, range: newRange)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,11 +160,11 @@ public class TextField: UITextField, KeymanResponder {
|
|||
@objc func textFieldTextDidChange(_ notification: Notification) {
|
||||
if shouldUpdateKMText {
|
||||
// Catches copy/paste operations
|
||||
Manager.shared.setText(text)
|
||||
let textRange = selectedTextRange!
|
||||
let newRange = NSRange(location: offset(from: beginningOfDocument, to: textRange.start),
|
||||
length: offset(from: textRange.start, to: textRange.end))
|
||||
Manager.shared.setSelectionRange(newRange, manually: false)
|
||||
|
||||
Manager.shared.setContextState(text: text, range: newRange)
|
||||
shouldUpdateKMText = false
|
||||
}
|
||||
}
|
||||
|
|
@ -262,12 +263,6 @@ extension TextField: UITextFieldDelegate {
|
|||
|
||||
log.debug("TextField: \(self.hashValue) setFont: \(font?.familyName ?? "nil")")
|
||||
|
||||
// copy this textField's text to the webview
|
||||
Manager.shared.setText(text)
|
||||
let textRange = selectedTextRange!
|
||||
let newRange = NSRange(location: offset(from: beginningOfDocument, to: textRange.start),
|
||||
length: offset(from: textRange.start, to: textRange.end))
|
||||
Manager.shared.setSelectionRange(newRange, manually: false)
|
||||
log.debug("TextField: \(self.hashValue) Became first responder. Value: \(String(describing: text))")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,14 +109,13 @@ public class TextView: UITextView, KeymanResponder {
|
|||
super.text = ""
|
||||
}
|
||||
|
||||
Manager.shared.inputViewController.setText(self.text)
|
||||
Manager.shared.inputViewController.setSelectionRange(selectedRange, manually: false)
|
||||
Manager.shared.inputViewController.setContextState(text: self.text, range: selectedRange)
|
||||
}
|
||||
}
|
||||
|
||||
public override var selectedTextRange: UITextRange? {
|
||||
didSet {
|
||||
Manager.shared.setSelectionRange(selectedRange, manually: false)
|
||||
Manager.shared.setContextState(text: self.text, range: selectedRange)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -259,9 +258,6 @@ extension TextView: UITextViewDelegate {
|
|||
|
||||
log.debug("TextView: \(self.hashValue) setFont: \(font?.familyName ?? "nil")")
|
||||
|
||||
// copy this textView's text to the webview
|
||||
Manager.shared.setText(text)
|
||||
Manager.shared.setSelectionRange(selectedRange, manually: false)
|
||||
log.debug("TextView: \(self.hashValue) Became first responder. Value: \(String(describing: text))")
|
||||
}
|
||||
|
||||
|
|
@ -275,8 +271,7 @@ extension TextView: UITextViewDelegate {
|
|||
public func textViewDidChange(_ textView: UITextView) {
|
||||
if shouldUpdateKMText {
|
||||
// Catches copy/paste operations
|
||||
Manager.shared.setText(textView.text)
|
||||
Manager.shared.setSelectionRange(textView.selectedRange, manually: false)
|
||||
Manager.shared.setContextState(text: textView.text, range: textView.selectedRange)
|
||||
shouldUpdateKMText = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue