mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-09 10:25:32 +00:00
108 lines
5.1 KiB
Objective-C
108 lines
5.1 KiB
Objective-C
//
|
|
// KMInputMethodBrowserClientEventHandler.m
|
|
// Keyman
|
|
//
|
|
// Created by tom on 1/5/18.
|
|
// Copyright © 2018 SIL International. All rights reserved.
|
|
//
|
|
|
|
#import "KMInputMethodBrowserClientEventHandler.h"
|
|
#import "KMInputMethodEventHandlerProtected.h"
|
|
#import "KMInputMethodBrowserClientEventHandlerProtected.h"
|
|
|
|
@implementation KMInputMethodBrowserClientEventHandler
|
|
|
|
// Because Google Docs can't report its context in any of the browsers (Safari, Chrome, Firefox) and Word sometimes
|
|
// has trouble doing this in Chrome, we want to try to detect it so each browser can respond appropriately.
|
|
NSUInteger _failuresToRetrieveExpectedContext;
|
|
|
|
- (instancetype)init {
|
|
return [self initWithLegacyMode:YES clientSelectionCanChangeUnexpectedly:YES];
|
|
}
|
|
|
|
- (instancetype)initWithLegacyMode:(BOOL)legacy clientSelectionCanChangeUnexpectedly:(BOOL) flagClientSelectionCanChangeUnexpectedly {
|
|
self = [super initWithLegacyMode:legacy clientSelectionCanChangeUnexpectedly: flagClientSelectionCanChangeUnexpectedly];
|
|
if (self) {
|
|
_failuresToRetrieveExpectedContext = 0;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)checkContextIn:(id) client {
|
|
if (!self.willDeleteNullChar && !self.contextOutOfDate && _failuresToRetrieveExpectedContext < 3) {
|
|
if (self.AppDelegate.debugMode) {
|
|
NSLog(@"Checking to see if we're in Google Docs (or some other site that can't give context).");
|
|
}
|
|
NSUInteger bufferLength = self.contextBuffer.length;
|
|
if (bufferLength) {
|
|
NSUInteger location = [client selectedRange].location;
|
|
|
|
if (location != NSNotFound && location > 0) {
|
|
if ([self AppDelegate].debugMode)
|
|
NSLog(@"Trying to get context up to location %lu", location);
|
|
NSString* clientContext = [self getLimitedContextFrom:client at:location];
|
|
if (clientContext == nil)
|
|
{
|
|
// Client is failing to provide useful response to attributedSubstringFromRange.
|
|
// Word (in MS Live) occasionally does this.
|
|
[self setInSiteThatDoesNotGiveContext];
|
|
}
|
|
else if (!clientContext.length) {
|
|
if ([self AppDelegate].debugMode) {
|
|
NSLog(@"Expected context = '%@'", self.contextBuffer);
|
|
NSLog(@"Actual clientContext was empty");
|
|
}
|
|
_failuresToRetrieveExpectedContext++;
|
|
}
|
|
else
|
|
{
|
|
unichar lastCodepointExpected = [self.contextBuffer characterAtIndex:bufferLength - 1];
|
|
unichar lastCodepointInClient = [clientContext characterAtIndex:clientContext.length - 1];
|
|
if (lastCodepointExpected != lastCodepointInClient) {
|
|
if ([self AppDelegate].debugMode) {
|
|
NSLog(@"Expected context = '%@'", self.contextBuffer);
|
|
NSLog(@"Actual clientContext = '%@'", (clientContext == nil ? @"{nil}" : clientContext));
|
|
NSLog(@"Last character expected (in contextBuffer) = '%lu'", (unsigned long)lastCodepointExpected);
|
|
NSLog(@"Last character in clientContext = '%lu'", (unsigned long)lastCodepointInClient);
|
|
}
|
|
// MS Word converts/reports plain spaces (32) as non-breaking spaces (160). If we
|
|
// get this kind of mismatch, we don't want to count this as a definite match, but
|
|
// we also don't want to count it as a failure to match. So just wait for a more
|
|
// reliable character to test.
|
|
if (lastCodepointInClient != 160 || lastCodepointExpected != 32) {
|
|
_failuresToRetrieveExpectedContext++;
|
|
}
|
|
}
|
|
else {
|
|
if ([self AppDelegate].debugMode) {
|
|
NSLog(@"We got what we were expecting from the client. We can stop checking.");
|
|
}
|
|
_failuresToRetrieveExpectedContext = NSUIntegerMax;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if ([self AppDelegate].debugMode) {
|
|
NSLog(@"bufferLength is %lu, but location was %lu.", bufferLength, location);
|
|
}
|
|
_failuresToRetrieveExpectedContext++;
|
|
}
|
|
|
|
if (_failuresToRetrieveExpectedContext == 3)
|
|
[self setInSiteThatDoesNotGiveContext];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)setInSiteThatDoesNotGiveContext {
|
|
if ([self AppDelegate].debugMode) {
|
|
NSLog(@"Detected some editor (e.g., Google Docs) that can't provide context.");
|
|
}
|
|
_failuresToRetrieveExpectedContext = NSUIntegerMax;
|
|
|
|
if (self.clientSelectionCanChangeUnexpectedly) {
|
|
self.clientCanProvideSelectionInfo = Unreliable;
|
|
self.clientSelectionCanChangeUnexpectedly = NO; // This isn't true (it can change unexpectedly), but we can't get the context, so we pretend/hope it won't.
|
|
}
|
|
}
|
|
@end
|