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

XAML Whitespace Behavior #43

Merged
merged 8 commits into from
Dec 7, 2021
Merged

Conversation

shartte
Copy link
Contributor

@shartte shartte commented Feb 14, 2021

XamlX's whitespace behavior is far from what Microsoft's XAML does. In particular, it's currently impossible to define a control that behaves like WPF's TextBlock and LineBreak.

This PR aims to get XamlX to the right place. First, I created a test case that fully passes against WPF's XAML parser and ported this to XamlX, with the intent to then make modifications to make it pass with XamlX.

Microsoft's documentation on this topic: https://docs.microsoft.com/en-us/dotnet/desktop/xaml-services/white-space-processing

Fun observation: [TrimSurroundingWhitespace] doesn't actually do anything in my WPF tests. It seems hardcoded to <LineBreak/>.

…ignificant whitespace between property-setters in case xml:space="preserve" is used.
…required further changes to various bits and pieces of the XamlCompiler (to ignore that whitespace). This was neccessary to allow for collections declaring themselves as whitespace-significant actually receiving the whitespace nodes they need.
… where PropertyType is properly set (which is required for properly transforming whitespace).
@shartte shartte marked this pull request as ready for review February 19, 2021 21:51
@shartte
Copy link
Contributor Author

shartte commented Feb 19, 2021

@kekekeks This is a big bad breaking change, and in some cases it's quite hard to bake this into the current architecture.

Can you take a look at this?

The unit tests were tested against WPF as well. The primary difference is that I did not opt to replicate a WPF bug (since it only exists in their dynamic parser), and that WPF treats "object Prop {get;set;}" different from "string Prop {get;set;}" with regards to handling xml:space="preserve" (both object and string will maintain the whitespace in our case).

pps: This does not implement stripping new-lines between eastern asian characters

}
else
{
foreach (var setter in Setters)
Copy link
Owner

Choose a reason for hiding this comment

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

I'm not sure if we should mutate setters here. It also treats

public void set_Foo(int value);

as IEnumerable<int> property. Which doesn't really make sense and feels like a hack just for whitespace handling

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should do that only if the setter was added with BinderParameters.AllowMultiple. Would that be the case for `set_Foo' ?

(I also didn't like all of this when I wrote it, to be honest)

Copy link
Owner

Choose a reason for hiding this comment

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

I think we need to add an extra marker to Add-like setters, so you could check for that in ApplyWhitespaceNormalization transformer

Copy link
Contributor Author

@shartte shartte Feb 20, 2021

Choose a reason for hiding this comment

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

I thought that's what BinderParameters.AllowMultiple is for?
I coded this under the assumption that add-style setters are marked BinderParameters.AllowMultiple = true, while set-style setters are not.

p.s.: We do have the limitation that an Avalonia control that only uses Add(...) with no associated getter will not be able to declare it's content as whitespace-significant, since that attribute is expected on the collection-type, rather than the control.

… property setters to determine if whitespace-only nodes should be removed.
@shartte
Copy link
Contributor Author

shartte commented Feb 24, 2021

@kekekeks I removed the type-system changes (PropertyType junk). Instead, I now inspect the available setters directly in the whitespace normalization transformer

@kekekeks
Copy link
Owner

kekekeks commented Feb 25, 2021

Awesome, will merge once the corresponding PR in Avalonia repo is merged (submodule references work with unmerged PRs)

@shartte
Copy link
Contributor Author

shartte commented Feb 25, 2021

Ah cool, we'll swap the submodule ref then. Thanks!

@shartte
Copy link
Contributor Author

shartte commented Feb 25, 2021

@kekekeks I found a bug in CecilHelpers.Equals that affected IXamlType.IsAssignableFrom

This broke the whitespace normalization in Avalonia because IDictionary<string, T> was suddenly assignable from string (and thus being detected as a scalar string property).

Fixed in f4cad31

Copy link
Owner

@kekekeks kekekeks left a comment

Choose a reason for hiding this comment

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

@Gillibald has confirmed that it works

@kekekeks kekekeks merged commit e068b3d into kekekeks:master Dec 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants