Skip to content

Commit ad52a3e

Browse files
[X] implicit xmlns declarations
Make the default xmlns implicitely pointing to maui default xmlns pre-load all available XmlsPrefixes for use the capability is disabled by default, and you need to opt-in - fixes #28849 - fixes #28850 - fixes #28847
1 parent e106339 commit ad52a3e

27 files changed

+378
-67
lines changed

Microsoft.Maui-vscode.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UITest.Analyzers", "src\Tes
212212
EndProject
213213
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Maui.Controls.Sample.Embedding", "src\Controls\samples\Controls.Sample.Embedding\Maui.Controls.Sample.Embedding.csproj", "{4ADCBA87-30DB-44F5-85E9-94A4F4132FD9}"
214214
EndProject
215+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGen.UnitTests", "src\Controls\tests\SourceGen.UnitTests\SourceGen.UnitTests.csproj", "{A426B2FC-F012-436B-BDD9-BEC0025DB96B}"
216+
EndProject
215217
Global
216218
GlobalSection(SolutionConfigurationPlatforms) = preSolution
217219
Debug|Any CPU = Debug|Any CPU
@@ -539,6 +541,10 @@ Global
539541
{4ADCBA87-30DB-44F5-85E9-94A4F4132FD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
540542
{4ADCBA87-30DB-44F5-85E9-94A4F4132FD9}.Release|Any CPU.Build.0 = Release|Any CPU
541543
{4ADCBA87-30DB-44F5-85E9-94A4F4132FD9}.Release|Any CPU.Deploy.0 = Release|Any CPU
544+
{A426B2FC-F012-436B-BDD9-BEC0025DB96B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
545+
{A426B2FC-F012-436B-BDD9-BEC0025DB96B}.Debug|Any CPU.Build.0 = Debug|Any CPU
546+
{A426B2FC-F012-436B-BDD9-BEC0025DB96B}.Release|Any CPU.ActiveCfg = Release|Any CPU
547+
{A426B2FC-F012-436B-BDD9-BEC0025DB96B}.Release|Any CPU.Build.0 = Release|Any CPU
542548
EndGlobalSection
543549
GlobalSection(SolutionProperties) = preSolution
544550
HideSolutionNode = FALSE
@@ -636,6 +642,7 @@ Global
636642
{0048EA9A-D751-4576-A2BB-2A37BFB385A5} = {25D0D27A-C5FE-443D-8B65-D6C987F4A80E}
637643
{DA001142-4777-4EDE-97D5-B1AC08162F99} = {7AC28763-9C68-4BF9-A1BA-25CBFFD2D15C}
638644
{4ADCBA87-30DB-44F5-85E9-94A4F4132FD9} = {E1082E26-D700-4127-9329-66D673FD2D55}
645+
{A426B2FC-F012-436B-BDD9-BEC0025DB96B} = {25D0D27A-C5FE-443D-8B65-D6C987F4A80E}
639646
EndGlobalSection
640647
GlobalSection(ExtensibilityGlobals) = postSolution
641648
SolutionGuid = {0B8ABEAD-D2B5-4370-A187-62B5ABE4EE50}

src/Controls/src/Build.Tasks/XamlCTask.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ public override bool Execute(out IList<Exception> thrownExceptions)
285285
ILRootNode rootnode = null;
286286
try
287287
{
288-
rootnode = ParseXaml(resource.GetResourceStream(), typeDef);
288+
rootnode = ParseXaml(resource.GetResourceStream(), module, typeDef);
289289
if (rootnode == null)
290290
{
291291
LoggingHelper.LogMessage(Low, $"{new string(' ', 8)}failed.");

src/Controls/src/Build.Tasks/XamlTask.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.ComponentModel;
44
using System.Diagnostics;
55
using System.IO;
6+
using System.Linq;
67
using System.Xml;
78
using Microsoft.Build.Framework;
89
using Microsoft.Build.Utilities;
@@ -40,9 +41,24 @@ public bool Execute()
4041

4142
public abstract bool Execute(out IList<Exception> thrownExceptions);
4243

43-
internal static ILRootNode ParseXaml(Stream stream, TypeReference typeReference)
44+
internal static ILRootNode ParseXaml(Stream stream, ModuleDefinition module, TypeReference typeReference)
4445
{
45-
using (var reader = XmlReader.Create(stream))
46+
var allowImplicitXmlns = module.Assembly.CustomAttributes.Any(a =>
47+
a.AttributeType.FullName == typeof(Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute).FullName
48+
&& (a.ConstructorArguments.Count == 0 || a.ConstructorArguments[0].Value is bool b && b));
49+
50+
var nsmgr = new XmlNamespaceManager(new NameTable());
51+
nsmgr.AddNamespace("__f__", XamlParser.MauiUri);
52+
if (allowImplicitXmlns)
53+
{
54+
nsmgr.AddNamespace("", XamlParser.DefaultImplicitUri);
55+
foreach (var xmlnsPrefix in XmlTypeExtensions.GetXmlnsPrefixAttributes(module))
56+
nsmgr.AddNamespace(xmlnsPrefix.Prefix, xmlnsPrefix.XmlNamespace);
57+
}
58+
59+
using (var reader = XmlReader.Create(stream,
60+
new XmlReaderSettings { ConformanceLevel = allowImplicitXmlns ? ConformanceLevel.Fragment : ConformanceLevel.Document },
61+
new XmlParserContext(nsmgr.NameTable, nsmgr, null, XmlSpace.None)))
4662
{
4763
while (reader.Read())
4864
{
@@ -73,8 +89,22 @@ public static bool IsXaml(this EmbeddedResource resource, XamlCache cache, Modul
7389
if (!resource.Name.EndsWith(".xaml", StringComparison.InvariantCulture))
7490
return false;
7591

92+
var allowImplicitXmlns = module.Assembly.CustomAttributes.Any(a =>
93+
a.AttributeType.FullName == typeof(Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute).FullName
94+
&& (a.ConstructorArguments.Count == 0 || a.ConstructorArguments[0].Value is bool b && b));
95+
96+
var nsmgr = new XmlNamespaceManager(new NameTable());
97+
nsmgr.AddNamespace("__f__", XamlParser.MauiUri);
98+
if (allowImplicitXmlns)
99+
{
100+
nsmgr.AddNamespace("", XamlParser.DefaultImplicitUri);
101+
foreach (var xmlnsPrefix in XmlTypeExtensions.GetXmlnsPrefixAttributes(module))
102+
nsmgr.AddNamespace(xmlnsPrefix.Prefix, xmlnsPrefix.XmlNamespace);
103+
}
76104
using (var resourceStream = resource.GetResourceStream())
77-
using (var reader = XmlReader.Create(resourceStream))
105+
using (var reader = XmlReader.Create(resourceStream,
106+
new XmlReaderSettings { ConformanceLevel = allowImplicitXmlns ? ConformanceLevel.Fragment : ConformanceLevel.Document },
107+
new XmlParserContext(nsmgr.NameTable, nsmgr, null, XmlSpace.None)))
78108
{
79109
// Read to the first Element
80110
while (reader.Read() && reader.NodeType != XmlNodeType.Element)

src/Controls/src/Build.Tasks/XmlTypeExtensions.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,48 @@ public static XmlnsDefinitionAttribute GetXmlnsDefinition(this CustomAttribute c
109109
attr.AssemblyName = assemblyName ?? asmDef.Name.FullName;
110110
return attr;
111111
}
112+
113+
public static IList<XmlnsPrefixAttribute> GetXmlnsPrefixAttributes(ModuleDefinition module)
114+
{
115+
var xmlnsPrefixes = new List<XmlnsPrefixAttribute>();
116+
foreach (var ca in module.Assembly.CustomAttributes)
117+
{
118+
if (ca.AttributeType.FullName == typeof(XmlnsPrefixAttribute).FullName)
119+
{
120+
var attr = new XmlnsPrefixAttribute(
121+
ca.ConstructorArguments[0].Value as string,
122+
ca.ConstructorArguments[1].Value as string);
123+
xmlnsPrefixes.Add(attr);
124+
}
125+
}
126+
127+
if (module.AssemblyReferences?.Count > 0)
128+
{
129+
// Search for the attribute in the assemblies being
130+
// referenced.
131+
foreach (var asmRef in module.AssemblyReferences)
132+
{
133+
try
134+
{
135+
var asmDef = module.AssemblyResolver.Resolve(asmRef);
136+
foreach (var ca in asmDef.CustomAttributes)
137+
{
138+
if (ca.AttributeType.FullName == typeof(XmlnsPrefixAttribute).FullName)
139+
{
140+
var attr = new XmlnsPrefixAttribute(
141+
ca.ConstructorArguments[0].Value as string,
142+
ca.ConstructorArguments[1].Value as string);
143+
xmlnsPrefixes.Add(attr);
144+
}
145+
}
146+
}
147+
catch (System.Exception)
148+
{
149+
// Ignore assembly resolution errors
150+
}
151+
}
152+
}
153+
return xmlnsPrefixes;
154+
}
112155
}
113156
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#nullable enable
2+
using System;
3+
using System.Runtime.Versioning;
4+
5+
namespace Microsoft.Maui.Controls.Xaml.Internals;
6+
7+
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
8+
#if !NETSTANDARD
9+
[RequiresPreviewFeatures]
10+
#endif
11+
public sealed class AllowImplicitXmlnsDeclarationAttribute(bool allow = true) : Attribute
12+
{
13+
public bool Allow { get; } = allow;
14+
}

src/Controls/src/Core/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979

8080
[assembly: XmlnsPrefix("http://schemas.microsoft.com/dotnet/2021/maui", "maui")]
8181
[assembly: XmlnsPrefix("http://schemas.microsoft.com/dotnet/2021/maui/design", "d")]
82+
[assembly: XmlnsPrefix("http://schemas.microsoft.com/winfx/2009/xaml", "x")]
8283

8384
[assembly: StyleProperty("background-color", typeof(VisualElement), nameof(VisualElement.BackgroundColorProperty))]
8485
[assembly: StyleProperty("background", typeof(VisualElement), nameof(VisualElement.BackgroundProperty))]

src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,6 @@ const Microsoft.Maui.Controls.BrushTypeConverter.Rgba = "rgba" -> string!
383383
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.GradientBrushParser(Microsoft.Maui.Graphics.Converters.ColorTypeConverter? colorConverter = null) -> void
384384
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.Parse(string? css) -> Microsoft.Maui.Controls.GradientBrush?
385385
static Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.ParseStringToPathFigureCollection(Microsoft.Maui.Controls.Shapes.PathFigureCollection! pathFigureCollection, string? pathString) -> void
386+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute
387+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute.Allow.get -> bool
388+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute.AllowImplicitXmlnsDeclarationAttribute(bool allow = true) -> void

src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,3 +585,6 @@ const Microsoft.Maui.Controls.BrushTypeConverter.Rgba = "rgba" -> string!
585585
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.GradientBrushParser(Microsoft.Maui.Graphics.Converters.ColorTypeConverter? colorConverter = null) -> void
586586
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.Parse(string? css) -> Microsoft.Maui.Controls.GradientBrush?
587587
static Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.ParseStringToPathFigureCollection(Microsoft.Maui.Controls.Shapes.PathFigureCollection! pathFigureCollection, string? pathString) -> void
588+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute
589+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute.Allow.get -> bool
590+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute.AllowImplicitXmlnsDeclarationAttribute(bool allow = true) -> void

src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,3 +585,6 @@ const Microsoft.Maui.Controls.BrushTypeConverter.Rgba = "rgba" -> string!
585585
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.GradientBrushParser(Microsoft.Maui.Graphics.Converters.ColorTypeConverter? colorConverter = null) -> void
586586
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.Parse(string? css) -> Microsoft.Maui.Controls.GradientBrush?
587587
static Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.ParseStringToPathFigureCollection(Microsoft.Maui.Controls.Shapes.PathFigureCollection! pathFigureCollection, string? pathString) -> void
588+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute
589+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute.Allow.get -> bool
590+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute.AllowImplicitXmlnsDeclarationAttribute(bool allow = true) -> void

src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,4 +339,7 @@ const Microsoft.Maui.Controls.BrushTypeConverter.Rgb = "rgb" -> string!
339339
const Microsoft.Maui.Controls.BrushTypeConverter.Rgba = "rgba" -> string!
340340
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.GradientBrushParser(Microsoft.Maui.Graphics.Converters.ColorTypeConverter? colorConverter = null) -> void
341341
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.Parse(string? css) -> Microsoft.Maui.Controls.GradientBrush?
342-
static Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.ParseStringToPathFigureCollection(Microsoft.Maui.Controls.Shapes.PathFigureCollection! pathFigureCollection, string? pathString) -> void
342+
static Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.ParseStringToPathFigureCollection(Microsoft.Maui.Controls.Shapes.PathFigureCollection! pathFigureCollection, string? pathString) -> void
343+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute
344+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute.Allow.get -> bool
345+
Microsoft.Maui.Controls.Xaml.Internals.AllowImplicitXmlnsDeclarationAttribute.AllowImplicitXmlnsDeclarationAttribute(bool allow = true) -> void

0 commit comments

Comments
 (0)