Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using AndroidX.AppCompat.Widget;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
using Xunit;

namespace Microsoft.Maui.DeviceTests
Expand Down Expand Up @@ -34,11 +35,7 @@ static int GetPlatformCursorPosition(EditorHandler editorHandler)
static int GetPlatformSelectionLength(EditorHandler editorHandler)
{
var textView = GetPlatformControl(editorHandler);

if (textView != null)
return textView.SelectionEnd - textView.SelectionStart;

return -1;
return textView?.GetSelectedTextLength() ?? -1;
}

Task<float> GetPlatformOpacity(EditorHandler editorHandler)
Expand Down Expand Up @@ -139,6 +136,33 @@ public async Task RotationYConsistent()
Assert.Equal(expected, platformRotationY);
}

[Fact]
[Description("The SelectionLength property should handle right-to-left text selection correctly and not return negative values")]
public async Task SelectionLengthRightToLeft()
{
var editor = new Editor()
{
Text = "Hello World"
};

var handler = await CreateHandlerAsync<EditorHandler>(editor);
var platformControl = GetPlatformControl(handler);

await InvokeOnMainThreadAsync(() =>
{
platformControl.SetSelection(5, 0); // SelectionStart=5, SelectionEnd=0
int platformSelectionLength = GetPlatformSelectionLength(handler);
Assert.True(platformSelectionLength >= 0,
$"Platform selection length should never be negative, but got: {platformSelectionLength}");
Assert.Equal(5, platformSelectionLength);

// The virtual view should also show positive selection length
Assert.True(editor.SelectionLength >= 0,
$"Virtual view selection length should never be negative, but got: {editor.SelectionLength}");
Assert.Equal(5, editor.SelectionLength);
});
}

[Fact]
[Description("The Rotation property of a Editor should match with native Rotation")]
public async Task RotationConsistent()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using AndroidX.AppCompat.Widget;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
using Xunit;

namespace Microsoft.Maui.DeviceTests
Expand Down Expand Up @@ -33,13 +34,8 @@ static int GetPlatformCursorPosition(EntryHandler entryHandler)
static int GetPlatformSelectionLength(EntryHandler entryHandler)
{
var editText = GetPlatformControl(entryHandler);

if (editText != null)
return editText.SelectionEnd - editText.SelectionStart;

return -1;
return editText?.GetSelectedTextLength() ?? -1;
}

Task<float> GetPlatformOpacity(EntryHandler entryHandler)
{
return InvokeOnMainThreadAsync(() =>
Expand Down Expand Up @@ -165,6 +161,33 @@ public async Task RotationConsistent()
Assert.Equal(expected, platformRotation);
}

[Fact]
[Description("The SelectionLength property should handle right-to-left text selection correctly and not return negative values")]
public async Task SelectionLengthRightToLeft()
{
var entry = new Entry()
{
Text = "Hello World"
};

var handler = await CreateHandlerAsync<EntryHandler>(entry);
var platformControl = GetPlatformControl(handler);

await InvokeOnMainThreadAsync(() =>
{
platformControl.SetSelection(5, 0);
int platformSelectionLength = GetPlatformSelectionLength(handler);
Assert.True(platformSelectionLength >= 0,
$"Platform selection length should never be negative, but got: {platformSelectionLength}");
Assert.Equal(5, platformSelectionLength);

// The virtual view should also show positive selection length
Assert.True(entry.SelectionLength >= 0,
$"Virtual view selection length should never be negative, but got: {entry.SelectionLength}");
Assert.Equal(5, entry.SelectionLength);
});
}

//src/Compatibility/Core/tests/Android/TranslationTests.cs
[Fact]
[Description("The Translation property of a Entry should match with native Translation")]
Expand Down
17 changes: 12 additions & 5 deletions src/Core/src/Platform/Android/EditTextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,18 @@ static int GetSelectionStart(EditText editText, ITextInput entry)

static int GetSelectionEnd(EditText editText, ITextInput entry, int start)
{
int end = start;
int selectionLength = entry.SelectionLength;
end = System.Math.Max(start, System.Math.Min(editText.Length(), start + selectionLength));
int newSelectionLength = System.Math.Max(0, end - start);
int end = Math.Max(start, Math.Min(editText.Length(), start + selectionLength));
int newSelectionLength = Math.Max(0, end - start);

// If 'start > editText.SelectionEnd', it indicates a reverse selection (right-to-left selection),
// where the user selected text starting from the right and moving to the left.
if (start > editText.SelectionEnd && selectionLength > 0)
{
end = editText.SelectionEnd;
newSelectionLength = selectionLength;
}

// Updating this property results in UpdateSelectionLength being called again messing things up
if (newSelectionLength != selectionLength)
entry.SelectionLength = newSelectionLength;
Expand All @@ -274,8 +282,7 @@ static int GetSelectionEnd(EditText editText, ITextInput entry, int start)
// TODO: NET8 issoto - Revisit this, marking this method as `internal` to avoid breaking public API changes
internal static int GetSelectedTextLength(this EditText editText)
{
var selectedLength = editText.SelectionEnd - editText.SelectionStart;
return Math.Max(0, selectedLength);
return Math.Abs(editText.SelectionEnd - editText.SelectionStart);
}

internal static void SetInputType(this EditText editText, ITextInput textInput)
Expand Down
Loading