Skip to content
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

[iOS] Double dash in input field crash fix #20584

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue20439"
xmlns:ns="clr-namespace:Maui.Controls.Sample.Issues">
<ShellContent
Title="Home">
<ContentPage>
<StackLayout VerticalOptions="Center">
<Entry AutomationId="entry" Text="Tap here"/>
<Button AutomationId="button" Text="Open the input page" Clicked="Button_Clicked"/>
</StackLayout>
</ContentPage>
</ShellContent>

<ShellContent
Title="Text input page">
<ContentPage>
<Editor VerticalOptions="Center"
AutomationId="editor"
HeightRequest="100"
Text="Potential auto correcting words: -- :-) ... omw \n" />
</ContentPage>
</ShellContent>
</Shell>
@@ -0,0 +1,20 @@
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Xaml;

namespace Maui.Controls.Sample.Issues
{
[XamlCompilation(XamlCompilationOptions.Compile)]
[Issue(IssueTracker.Github, 20439, "[iOS] Double dash in Entry or Editor crashes the app", PlatformAffected.iOS)]
public partial class Issue20439 : Shell
{
public Issue20439()
{
InitializeComponent();
}

void Button_Clicked(object sender, System.EventArgs e)
{
CurrentItem = Items[1];
}
}
}
Expand Up @@ -41,6 +41,12 @@ static void UpdateText(this IUITextInput textInput, InputView inputView, bool is
// position if needed when the text was modified by a Converter.
var textRange = textInput.GetTextRange(textInput.BeginningOfDocument, textInput.EndOfDocument);
var oldText = textInput.TextInRange(textRange) ?? string.Empty;

// We need this variable because in some cases because of the iOS's
rmarinho marked this conversation as resolved.
Show resolved Hide resolved
// auto correction eg. eg '--' => '—' the actual text in the input might have
rmarinho marked this conversation as resolved.
Show resolved Hide resolved
// a different length that the one that has been set in the control.
var newTextLength = textInput.TextInRange(textRange)?.Length ?? 0;

var newText = TextTransformUtilites.GetTransformedText(
inputView?.Text,
textInput.GetSecureTextEntry() ? TextTransform.Default : inputView.TextTransform
Expand All @@ -50,8 +56,8 @@ static void UpdateText(this IUITextInput textInput, InputView inputView, bool is
{
// Re-calculate the cursor offset position if the text was modified by a Converter.
// but if the text is being set by code, let's just move the cursor to the end.
var cursorOffset = newText.Length - oldText.Length;
var cursorPosition = isEditing ? textInput.GetCursorPosition(cursorOffset) : newText.Length;
var cursorOffset = newTextLength - oldText.Length;
var cursorPosition = isEditing ? textInput.GetCursorPosition(cursorOffset) : newTextLength;
kubaflo marked this conversation as resolved.
Show resolved Hide resolved

textInput.ReplaceText(textRange, newText);

Expand Down
28 changes: 28 additions & 0 deletions src/Controls/tests/UITests/Tests/Issues/Issue20439.cs
@@ -0,0 +1,28 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.AppiumTests.Issues
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file-scoped namespace might be better

{
public class Issue20439 : _IssuesUITest
{
public override string Issue => "[iOS] Double dash in Entry or Editor crashes the app";

public Issue20439(TestDevice device) : base(device)
{
}

[Test]
public void ErrorShouldNotBeThrown()
{
this.IgnoreIfPlatforms(new TestDevice[] { TestDevice.Android, TestDevice.Mac, TestDevice.Windows });

_ = App.WaitForElement("entry");
App.Click("entry");
App.Click("button");

// The test passes if no crash is observed
App.FindElement("editor");
}
}
}