diff --git a/src/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cs b/src/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cs index ff348f135250..b17cbf20af75 100644 --- a/src/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cs +++ b/src/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cs @@ -49,6 +49,8 @@ protected override AWebView CreatePlatformView() blazorAndroidWebView.Settings.JavaScriptEnabled = true; blazorAndroidWebView.Settings.DomStorageEnabled = true; + blazorAndroidWebView.Settings.MinimumFontSize = 1; + blazorAndroidWebView.Settings.MinimumLogicalFontSize = 1; } _webViewClient = new WebKitWebViewClient(this); diff --git a/src/BlazorWebView/tests/DeviceTests/Elements/BlazorWebViewTests.Behaviors.cs b/src/BlazorWebView/tests/DeviceTests/Elements/BlazorWebViewTests.Behaviors.cs index 561f29063fe0..dd08c6158925 100644 --- a/src/BlazorWebView/tests/DeviceTests/Elements/BlazorWebViewTests.Behaviors.cs +++ b/src/BlazorWebView/tests/DeviceTests/Elements/BlazorWebViewTests.Behaviors.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Components.WebView.Maui; @@ -43,4 +45,75 @@ await InvokeOnMainThreadAsync(async () => }); } #endif + +#if ANDROID + const string SmallFontSpanId = "smallFontSpan"; + const string SmallFontCssValue = "4.87761px"; + + static class SmallFontTestStaticFilesContents + { + public const string SmallFontIndexHtmlContent = @" + + +
+ + +Hi, this is a paragraph.
+ tiny span text + + "; + + _webView = new WebView + { + Source = new HtmlWebViewSource { Html = html }, + HeightRequest = 100, + AutomationId = "SmallFontWebView" + }; + + _resultLabel = new Label + { + Text = "Not checked yet", + AutomationId = "ComputedFontSizeLabel" + }; + + _checkButton = new Button + { + Text = "Get computed font size of span", + AutomationId = "CheckFontSizeButton", + Command = new Command(async () => await CheckComputedFontSizeAsync()) + }; + + // Update the result label once the WebView finishes loading the HTML, so the test + // can wait for "WebView loaded" before tapping the button instead of racing navigation. + _webView.Navigated += (_, __) => _resultLabel.Text = "WebView loaded"; + + Content = new VerticalStackLayout + { + Children = + { + new Label { Text = $"Expected computed font-size to stay close to {SmallFontCssValue} (i.e. under 8px), not be clamped up by the platform WebView's minimum font size." }, + _webView, + _checkButton, + _resultLabel + } + }; + } + + async Task CheckComputedFontSizeAsync() + { + var computedFontSize = await _webView.EvaluateJavaScriptAsync( + $"window.getComputedStyle(document.getElementById('{SmallFontSpanId}')).fontSize"); + + _resultLabel.Text = computedFontSize?.Trim('"') ?? string.Empty; + } + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26924.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26924.cs new file mode 100644 index 000000000000..5a8225c43ca6 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue26924.cs @@ -0,0 +1,30 @@ +using System.Globalization; +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue26924 : _IssuesUITest +{ + public Issue26924(TestDevice device) : base(device) + { + } + + public override string Issue => "Font Size of span Element Not Rendering Correctly in Mobile Mode in .NET MAUI Blazor"; + + [Test] + [Category(UITestCategories.WebView)] + public void SmallFontSizeSpanIsNotClampedByMinimumFontSize() + { + // The result label is updated to "WebView loaded" once the WebView finishes loading + // the HTML, so wait for that before tapping the button to avoid racing navigation. + App.WaitForTextToBePresentInElement("ComputedFontSizeLabel", "WebView loaded"); + App.Tap("CheckFontSizeButton"); + App.WaitForTextToBePresentInElement("ComputedFontSizeLabel", "px"); + var computedFontSizeText = App.WaitForElement("ComputedFontSizeLabel").GetText(); + Assert.That(computedFontSizeText, Is.Not.Null); + Assert.That(float.Parse(computedFontSizeText!.Trim().TrimEnd('p', 'x'), CultureInfo.InvariantCulture), Is.LessThan(8f)); + } +} + diff --git a/src/Core/src/Platform/Android/WebViewExtensions.cs b/src/Core/src/Platform/Android/WebViewExtensions.cs index f09cd7397f23..10635091583a 100644 --- a/src/Core/src/Platform/Android/WebViewExtensions.cs +++ b/src/Core/src/Platform/Android/WebViewExtensions.cs @@ -39,6 +39,10 @@ public static void UpdateSettings(this AWebView platformWebView, IWebView webVie platformWebView.Settings.JavaScriptEnabled = javaScriptEnabled; platformWebView.Settings.DomStorageEnabled = domStorageEnabled; + // Android WebView defaults MinimumFontSize to 8, which silently + // clamps up any CSS font-size below 8px. + platformWebView.Settings.MinimumFontSize = 1; + platformWebView.Settings.MinimumLogicalFontSize = 1; } public static void UpdateUserAgent(this AWebView platformWebView, IWebView webView)