Browse Source

fix prediction text for browser

pull/10328/head
Emmanuel Hansen 3 years ago
parent
commit
4edc10caba
  1. 31
      src/Browser/Avalonia.Browser/AvaloniaView.cs
  2. 2
      src/Browser/Avalonia.Browser/Interop/InputHelper.cs
  3. 20
      src/Browser/Avalonia.Browser/webapp/modules/avalonia/input.ts

31
src/Browser/Avalonia.Browser/AvaloniaView.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices.JavaScript;
using Avalonia.Browser.Interop;
@ -15,6 +16,7 @@ using Avalonia.Platform;
using Avalonia.Rendering.Composition;
using Avalonia.Threading;
using SkiaSharp;
using static System.Runtime.CompilerServices.RuntimeHelpers;
namespace Avalonia.Browser
{
@ -94,6 +96,7 @@ namespace Avalonia.Browser
InputHelper.SubscribeTextEvents(
_inputElement,
OnBeforeInput,
OnTextInput,
OnCompositionStart,
OnCompositionUpdate,
@ -316,11 +319,37 @@ namespace Avalonia.Browser
return _topLevelImpl.RawTextEvent(data);
}
private bool OnBeforeInput(JSObject arg, int start, int end)
{
var type = arg.GetPropertyAsString("inputType");
Console.WriteLine(type);
if (type != "deleteByComposition")
{
if (type == "deleteContentBackward")
{
start = _inputElement.GetPropertyAsInt32("selectionStart");
end = _inputElement.GetPropertyAsInt32("selectionEnd");
}
else
{
start = -1;
end = -1;
}
}
if(start != -1 && end != -1 && _client != null)
{
_client.SelectInSurroundingText(start, end);
}
return false;
}
private bool OnCompositionStart (JSObject args)
{
if (_client == null)
return false;
Console.WriteLine("composition start");
_client.SetPreeditText(null);
IsComposing = true;
@ -331,6 +360,7 @@ namespace Avalonia.Browser
{
if (_client == null)
return false;
Console.WriteLine("composition update");
_client.SetPreeditText(args.GetPropertyAsString("data"));
@ -342,6 +372,7 @@ namespace Avalonia.Browser
if (_client == null)
return false;
Console.WriteLine("composition end");
IsComposing = false;
_client.SetPreeditText(null);
_topLevelImpl.RawTextEvent(args.GetPropertyAsString("data")!);

2
src/Browser/Avalonia.Browser/Interop/InputHelper.cs

@ -18,6 +18,8 @@ internal static partial class InputHelper
[JSImport("InputHelper.subscribeTextEvents", AvaloniaModule.MainModuleName)]
public static partial void SubscribeTextEvents(
JSObject htmlElement,
[JSMarshalAs<JSType.Function<JSType.Object, JSType.Number, JSType.Number, JSType.Boolean>>]
Func<JSObject, int, int, bool> onBeforeInput,
[JSMarshalAs<JSType.Function<JSType.String, JSType.String, JSType.Boolean>>]
Func<string, string?, bool> onInput,
[JSMarshalAs<JSType.Function<JSType.Object, JSType.Boolean>>]

20
src/Browser/Avalonia.Browser/webapp/modules/avalonia/input.ts

@ -47,6 +47,7 @@ export class InputHelper {
public static subscribeTextEvents(
element: HTMLInputElement,
beforeInputCallback: (args: InputEvent, start: number, end: number) => boolean,
inputCallback: (type: string, data: string | null) => boolean,
compositionStartCallback: (args: CompositionEvent) => boolean,
compositionUpdateCallback: (args: CompositionEvent) => boolean,
@ -68,6 +69,25 @@ export class InputHelper {
};
element.addEventListener("compositionstart", compositionStartHandler);
const beforeInputHandler = (args: InputEvent) => {
const ranges = args.getTargetRanges();
let start = -1;
let end = -1;
if (ranges.length > 0) {
start = ranges[0].startOffset;
end = ranges[0].endOffset;
}
if (args.inputType === "insertCompositionText") {
start = 2;
end = start + 2;
}
if (beforeInputCallback(args, start, end)) {
args.preventDefault();
}
};
element.addEventListener("beforeinput", beforeInputHandler);
const compositionUpdateHandler = (args: CompositionEvent) => {
if (compositionUpdateCallback(args)) {
args.preventDefault();

Loading…
Cancel
Save