public void IsNotSelfClosing_MultipleLines() { var xaml = @"<Element> </Element>"; Assert.IsFalse(XamlElementProcessor.IsSelfClosing(xaml.AsSpan())); }
public void IsSelfClosing_MultipleLines() { var xaml = @"<Element />"; Assert.IsTrue(XamlElementProcessor.IsSelfClosing(xaml.AsSpan())); }
public void GetElementName_SpaceSelfClosing_WithOffset() { var xaml = "<Ex><Foo />"; var actual = XamlElementProcessor.GetElementName(xaml.AsSpan(), 4); Assert.AreEqual("Foo", actual); }
public void GetElementName_Attribute_WithOffset() { var xaml = "<Ex><Foo Bar=\"True\"></Foo>"; var actual = XamlElementProcessor.GetElementName(xaml.AsSpan(), 4); Assert.AreEqual("Foo", actual); }
public void GetElementName_NotEmpty_WithOffset() { var xaml = "<Ex><Foo>Bar</Foo>"; var actual = XamlElementProcessor.GetElementName(xaml.AsSpan(), 4); Assert.AreEqual("Foo", actual); }
public void GetElementName_Empty_NoOffset() { var xaml = "<Foo></Foo>"; var actual = XamlElementProcessor.GetElementName(xaml.AsSpan()); Assert.AreEqual("Foo", actual); }
public void IsNotSelfClosing_WithNestedSelfClosing_MultipleLines() { var xaml = @"<Element> <OtherElement /> </Element>"; Assert.IsFalse(XamlElementProcessor.IsSelfClosing(xaml)); }
public void GetOpeningWithoutChildren_NoChildren() { var origin = "<Foo Bar=\"123\"></Foo>"; var expected = "<Foo Bar=\"123\">"; var actual = XamlElementProcessor.GetOpeningWithoutChildren(origin); Assert.AreEqual(expected, actual); }
public void GetOpeningWithoutChildren_SelfClosing() { var origin = "<Foo Bar=\"123\" />"; var expected = origin; var actual = XamlElementProcessor.GetOpeningWithoutChildren(origin); Assert.AreEqual(expected, actual); }
public void GetOpeningWithoutChildren_MultipleChildren_AndMultipleAttributesAsElements() { var origin = "<Foo><Foo.Bar=\"123\" /><Foo.Bar=\"123\" /><FuBar /><FuBar /></Foo>"; var expected = "<Foo><Foo.Bar=\"123\" /><Foo.Bar=\"123\" />"; var actual = XamlElementProcessor.GetOpeningWithoutChildren(origin); Assert.AreEqual(expected, actual); }
public void GetElementName_MultiLineSelfClosing_WithOffset() { var xaml = @"<Ex><Foo ar=""True"" />"; var actual = XamlElementProcessor.GetElementName(xaml.AsSpan(), 4); Assert.AreEqual("Foo", actual); }
public void GetOpeningWithoutChildren_MultipleChildren_AndMultipleAttributesAsElementsWithNesting_PlusAssortedWhitespace() { var origin = " <Foo> <Foo.Bar=\"123\">\r\n<Other />\r<Other />\r\n\r\n</Foo.Bar>\r\n<Foo.Bar=\"123\">\r\n <Other />\r\n <Other /></Foo.Bar ><Fu><Baa /></Fu><FuBar /> </Foo>"; var expected = "<Foo> <Foo.Bar=\"123\">\r\n<Other />\r<Other />\r\n\r\n</Foo.Bar>\r\n<Foo.Bar=\"123\">\r\n <Other />\r\n <Other /></Foo.Bar >"; var actual = XamlElementProcessor.GetOpeningWithoutChildren(origin); Assert.AreEqual(expected, actual); }
public void ClosingTag_IsSelfClosing() { Assert.IsTrue(XamlElementProcessor.IsSelfClosing("</Element>".AsSpan())); }
public void Issue183() { var xaml = @"<Grid Margin=""9""> <Grid.ColumnDefinitions> <ColumnDefinition Width=""Auto"" /> <ColumnDefinition Width=""*"" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height=""Auto"" /> <RowDefinition Height=""Auto"" /> <RowDefinition Height=""Auto"" /> <RowDefinition Height=""Auto"" /> <RowDefinition Height=""Auto"" /> <RowDefinition Height=""Auto"" /> <RowDefinition Height=""*"" /> <RowDefinition Height=""Auto"" /> </Grid.RowDefinitions> <TextBlock Grid.Row=""1"" Grid.Column=""0"" Margin=""0,0,10,0"" Text=""{x:Static strings:StringRes.Options_ClassGrouping}"" ToolTip=""{x:Static strings:StringRes.Options_ClassGroupingDescription}"" /> <TextBox Grid.Row=""1"" Grid.Column=""1"" Margin=""0,0,0,6"" AutomationProperties.HelpText=""{x:Static strings:StringRes.Options_ClassGroupingDescription}"" AutomationProperties.Name=""{x:Static strings:StringRes.Options_ClassGrouping}"" Text=""{Binding ClassGrouping, Mode=TwoWay}"" /> <TextBlock Grid.Row=""2"" Grid.Column=""0"" Margin=""0,0,10,0"" Text=""{x:Static strings:StringRes.Options_FallbackOutput}"" ToolTip=""{x:Static strings:StringRes.Options_FallbackOutputDescription}"" /> <themes:ClassicBorderDecorator x:Name=""FallbackOutputBorder"" Grid.Row=""2"" Grid.Column=""1"" Margin=""0,0,0,6"" BorderStyle=""Sunken""> <Grid> <avalonEdit:TextEditor x:Name=""FallbackOutputEntry"" MinHeight=""34"" AutomationProperties.HelpText=""{x:Static strings:StringRes.Options_FallbackOutputDescription}"" AutomationProperties.Name=""{x:Static strings:StringRes.Options_FallbackOutput}"" BorderBrush=""{Binding Path=BorderBrush, ElementName=ReferenceTextBox}"" BorderThickness=""{Binding Path=BorderThickness, ElementName=ReferenceTextBox}"" HorizontalScrollBarVisibility=""Hidden"" PreviewKeyDown=""TextEditorPreviewKeyDown"" SyntaxHighlighting=""XML"" TextChanged=""OnEditorTextChanged"" VerticalScrollBarVisibility=""Auto"" WordWrap=""True""> <avalonEdit:TextEditor.Options> <avalonEdit:TextEditorOptions EnableHyperlinks=""False"" /> </avalonEdit:TextEditor.Options> </avalonEdit:TextEditor> <local:WarningTriangle x:Name=""FallbackOutputEntryWarning"" Margin=""2"" HorizontalAlignment=""Right"" VerticalAlignment=""Top"" Visibility=""Collapsed"" /> </Grid> </themes:ClassicBorderDecorator> <TextBlock Grid.Row=""3"" Grid.Column=""0"" Margin=""0,0,10,0"" Text=""{x:Static strings:StringRes.Options_SubPropertyOutput}"" ToolTip=""{x:Static strings:StringRes.Options_SubPropertyOutputDescription}"" /> <themes:ClassicBorderDecorator x:Name=""SubPropertyOutputBorder"" Grid.Row=""3"" Grid.Column=""1"" Margin=""0,0,0,6"" BorderStyle=""Sunken""> <Grid> <avalonEdit:TextEditor x:Name=""SubPropertyOutputEntry"" MinHeight=""34"" AutomationProperties.HelpText=""{x:Static strings:StringRes.Options_SubPropertyOutputDescription}"" AutomationProperties.Name=""{x:Static strings:StringRes.Options_SubPropertyOutput}"" BorderBrush=""{Binding Path=BorderBrush, ElementName=ReferenceTextBox}"" BorderThickness=""{Binding Path=BorderThickness, ElementName=ReferenceTextBox}"" HorizontalScrollBarVisibility=""Hidden"" PreviewKeyDown=""TextEditorPreviewKeyDown"" SyntaxHighlighting=""XML"" TextChanged=""OnEditorTextChanged"" VerticalScrollBarVisibility=""Auto"" WordWrap=""True""> <avalonEdit:TextEditor.Options> <avalonEdit:TextEditorOptions EnableHyperlinks=""False"" /> </avalonEdit:TextEditor.Options> </avalonEdit:TextEditor> <local:WarningTriangle x:Name=""SubPropertyOutputEntryWarning"" Margin=""2"" HorizontalAlignment=""Right"" VerticalAlignment=""Top"" Visibility=""Collapsed"" /> </Grid> </themes:ClassicBorderDecorator> <TextBlock Grid.Row=""4"" Grid.Column=""0"" Margin=""0,0,10,0"" Text=""{x:Static strings:StringRes.Options_EnumMappingOutput}"" ToolTip=""{x:Static strings:StringRes.Options_EnumMappingOutputDescription}"" /> <themes:ClassicBorderDecorator x:Name=""EnumMemberOutputBorder"" Grid.Row=""4"" Grid.Column=""1"" Margin=""0"" BorderStyle=""Sunken""> <Grid> <avalonEdit:TextEditor x:Name=""EnumMemberOutputEntry"" MinHeight=""34"" AutomationProperties.HelpText=""{x:Static strings:StringRes.Options_EnumMappingOutputDescription}"" AutomationProperties.Name=""{x:Static strings:StringRes.Options_EnumMappingOutput}"" BorderBrush=""{Binding Path=BorderBrush, ElementName=ReferenceTextBox}"" BorderThickness=""{Binding Path=BorderThickness, ElementName=ReferenceTextBox}"" HorizontalScrollBarVisibility=""Hidden"" PreviewKeyDown=""TextEditorPreviewKeyDown"" SyntaxHighlighting=""XML"" TextChanged=""OnEditorTextChanged"" VerticalScrollBarVisibility=""Auto"" WordWrap=""True""> <avalonEdit:TextEditor.Options> <avalonEdit:TextEditorOptions EnableHyperlinks=""False"" /> </avalonEdit:TextEditor.Options> </avalonEdit:TextEditor> <local:WarningTriangle x:Name=""EnumMemberOutputEntryWarning"" Margin=""2"" HorizontalAlignment=""Right"" VerticalAlignment=""Top"" Visibility=""Collapsed"" /> </Grid> </themes:ClassicBorderDecorator> <TextBlock Grid.Row=""5"" Grid.Column=""0"" ☆Grid.ColumnSpan=""2"" Margin=""0,6,0,0"" Text=""{x:Static strings:StringRes.Options_MappingsHeader}"" /> <Grid Grid.Row=""6"" Grid.ColumnSpan=""2""> <Grid.ColumnDefinitions> <ColumnDefinition Width=""*"" /> <ColumnDefinition Width=""Auto"" /> </Grid.ColumnDefinitions> <ScrollViewer AutomationProperties.Name=""{x:Static strings:StringRes.Options_MappingsHeader}""> <DataGrid x:Name=""DisplayedMappings"" CanUserAddRows=""False"" CanUserDeleteRows=""False"" CanUserReorderColumns=""False"" CanUserResizeColumns=""True"" CanUserResizeRows=""False"" CanUserSortColumns=""False"" IsReadOnly=""True"" ItemsSource=""{Binding Mappings}"" PreviewKeyDown=""GridPreviewKeyDown"" SelectedItem=""{Binding Path=SelectedMapping, Mode=TwoWay}"" SelectionMode=""Single"" SelectionUnit=""FullRow"" /> </ScrollViewer> <StackPanel Grid.Column=""1"" Margin=""6,0,0,0""> <StackPanel.Resources> <Style TargetType=""Button""> <Setter Property=""Height"" Value=""23"" /> <Setter Property=""Width"" Value=""75"" /> <Setter Property=""Margin"" Value=""0,0,0,6"" /> </Style> </StackPanel.Resources> <Button x:Name=""AddMappingButton"" Click=""AddClicked"" Content=""{x:Static strings:StringRes.Options_ButtonAdd}"" /> <Button Click=""CopyClicked"" Content=""{x:Static strings:StringRes.Options_ButtonCopy}"" /> <Button Click=""DeleteClicked"" Content=""{x:Static strings:StringRes.Options_ButtonDelete}"" /> </StackPanel> </Grid> <Grid Grid.Row=""7"" Grid.Column=""0"" Grid.ColumnSpan=""2"" Margin=""0,4,0,0""> <Grid.ColumnDefinitions> <ColumnDefinition Width=""Auto"" /> <ColumnDefinition Width=""*"" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height=""Auto"" /> <RowDefinition Height=""Auto"" /> <RowDefinition Height=""Auto"" /> <RowDefinition Height=""Auto"" /> </Grid.RowDefinitions> <TextBlock Grid.Row=""0"" Grid.Column=""0"" Margin=""0,4,10,0"" Text=""{x:Static strings:StringRes.Options_MappingType}"" ToolTip=""{x:Static strings:StringRes.Options_MappingTypeDescription}"" /> <TextBox Grid.Row=""0"" Grid.Column=""1"" Margin=""0,4,0,6"" AutomationProperties.HelpText=""{x:Static strings:StringRes.Options_MappingTypeDescription}"" AutomationProperties.Name=""{x:Static strings:StringRes.Options_MappingType}"" Text=""{Binding SelectedMapping.Type, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"" /> <TextBlock Grid.Row=""1"" Grid.Column=""0"" Margin=""0,0,10,0"" Text=""{x:Static strings:StringRes.Options_MappingNameFilter}"" ToolTip=""{x:Static strings:StringRes.Options_MappingNameFilterDescription}"" /> <TextBox Grid.Row=""1"" Grid.Column=""1"" Margin=""0,0,0,6"" AutomationProperties.HelpText=""{x:Static strings:StringRes.Options_MappingNameFilterDescription}"" AutomationProperties.Name=""{x:Static strings:StringRes.Options_MappingNameFilter}"" Text=""{Binding SelectedMapping.NameContains, Mode=TwoWay}"" /> <CheckBox Grid.Row=""2"" Grid.Column=""1"" Margin=""0,0,0,6"" IsChecked=""{Binding SelectedMapping.IfReadOnly, Mode=TwoWay}""> <TextBlock Text=""{x:Static strings:StringRes.Options_MappingIfReadOnly}"" ToolTip=""{x:Static strings:StringRes.Options_MappingIfReadOnlyDescription}"" /> </CheckBox> <TextBlock Grid.Row=""3"" Grid.Column=""0"" Margin=""0,0,10,0"" Text=""{x:Static strings:StringRes.Options_MappingOutput}"" ToolTip=""{x:Static strings:StringRes.Options_MappingOutputDescription}"" /> <themes:ClassicBorderDecorator x:Name=""SelectedMappingOutputBorder"" Grid.Row=""3"" Grid.Column=""1"" BorderStyle=""Sunken""> <Grid> <avalonEdit:TextEditor x:Name=""SelectedMappingOutputEntry"" MinHeight=""34"" AutomationProperties.HelpText=""{x:Static strings:StringRes.Options_MappingOutputDescription}"" AutomationProperties.Name=""{x:Static strings:StringRes.Options_MappingOutput}"" BorderBrush=""{Binding Path=BorderBrush, ElementName=ReferenceTextBox}"" BorderThickness=""{Binding Path=BorderThickness, ElementName=ReferenceTextBox}"" HorizontalScrollBarVisibility=""Hidden"" PreviewKeyDown=""TextEditorPreviewKeyDown"" SyntaxHighlighting=""XML"" TextChanged=""OnSelectedMappingOutputChanged"" VerticalScrollBarVisibility=""Auto"" WordWrap=""True""> <avalonEdit:TextEditor.Options> <avalonEdit:TextEditorOptions EnableHyperlinks=""False"" /> </avalonEdit:TextEditor.Options> </avalonEdit:TextEditor> <local:WarningTriangle x:Name=""SelectedMappingOutputEntryWarning"" Margin=""2"" HorizontalAlignment=""Right"" VerticalAlignment=""Top"" Visibility=""Collapsed"" /> </Grid> </themes:ClassicBorderDecorator> </Grid> </Grid>"; var offset = xaml.IndexOf('☆'); var element = XamlElementProcessor.GetSubElementAtPosition(ProjectType.Wpf, "testFile.xaml", new FakeTextSnapshot(), xaml.Replace("☆", string.Empty), offset, new DefaultTestLogger()); Assert.IsNotNull(element); }
public void IsNotSelfClosing() { Assert.IsFalse(XamlElementProcessor.IsSelfClosing("<Element></Element>".AsSpan())); }
public void IsSelfClosing() { Assert.IsTrue(XamlElementProcessor.IsSelfClosing("<Element />".AsSpan())); }
private string GetSubElementAtStar(string outerElement) { var offset = outerElement.IndexOf('☆'); return(XamlElementProcessor.GetSubElementAtPosition(ProjectType.Any, "testFile.xaml", new FakeTextSnapshot(), outerElement.Replace("☆", string.Empty), offset, new DefaultTestLogger(), string.Empty, new TestVisualStudioAbstraction())); }
public void IsNotSelfClosing_WithNestedSelfClosing() { Assert.IsFalse(XamlElementProcessor.IsSelfClosing("<Element><OtherElement /></Element>".AsSpan())); }
#pragma warning disable IDE0060 // Remove unused parameter - cancellationToken private void InnerExecute(VisualStudioTextManipulation vs, CustomAnalysisTag tag, CancellationToken cancellationToken) #pragma warning restore IDE0060 // Remove unused parameter { switch (tag.Action) { case RapidXaml.ActionType.AddAttribute: var lineNumber = tag.Snapshot.GetLineNumberFromPosition(tag.InsertPosition) + 1; // Can't rely on the original element name as this may be supplemental after it's been renamed if (XamlElementProcessor.IsSelfClosing(tag.AnalyzedElement.OriginalString.AsSpan())) { var before = $"/>"; var after = $"{tag.Name}=\"{tag.Value}\" />"; vs.ReplaceInActiveDocOnLine(before, after, lineNumber); } else { var before = $">"; var after = $"{tag.Name}=\"{tag.Value}\" /"; vs.ReplaceInActiveDocOnLine(before, after, lineNumber); } break; case RapidXaml.ActionType.AddChild: var origXaml = tag.AnalyzedElement.OriginalString; // Allow for self-closing elements if (origXaml.EndsWith("/>")) { var replacementXaml = $">{Environment.NewLine}{tag.Content}{Environment.NewLine}</{tag.ElementName}>"; var insertLine = tag.Snapshot.GetLineNumberFromPosition(tag.InsertPosition) + 1; vs.ReplaceInActiveDocOnLine("/>", replacementXaml, insertLine); } else { // Allows for opening and closing tags on same or different lines var insertLine = tag.Snapshot.GetLineNumberFromPosition(tag.InsertPosition) + 1; vs.InsertIntoActiveDocOnLineAfterClosingTag(insertLine, tag.Content); } break; case RapidXaml.ActionType.HighlightWithoutAction: // As the name implies, do nothing. break; case RapidXaml.ActionType.RemoveAttribute: if (tag.IsInlineAttribute ?? false) { var currentAttribute = $" {tag.Name}=\"{tag.Value}\""; vs.RemoveInActiveDocOnLine(currentAttribute, tag.GetDesignerLineNumber()); } else { var attrs = tag.AnalyzedElement.GetAttributes(tag.Name).ToList(); if (attrs.Count() == 1) { var attr = attrs.First(); var toRemove = tag.AnalyzedElement.OriginalString.Substring( attr.Location.Start - tag.InsertPosition, attr.Location.Length); vs.RemoveInActiveDocOnLine(toRemove, tag.GetDesignerLineNumber()); } } break; case RapidXaml.ActionType.RemoveChild: vs.RemoveInActiveDocOnLine(tag.Element.OriginalString, tag.GetDesignerLineNumber()); break; case RapidXaml.ActionType.ReplaceElement: vs.ReplaceInActiveDocOnLine( tag.AnalyzedElement.OriginalString, tag.Content, tag.Snapshot.GetLineNumberFromPosition(tag.AnalyzedElement.Location.Start)); break; case RapidXaml.ActionType.RenameElement: // Just change opening tags as Visual Studio will change closing tags automatically var renameLineNumber = tag.Snapshot.GetLineNumberFromPosition(tag.InsertPosition); vs.ReplaceInActiveDocOnLine(tag.ElementName, tag.Name, renameLineNumber); foreach (var childAttr in tag.AnalyzedElement.ChildAttributes) { renameLineNumber = tag.Snapshot.GetLineNumberFromPosition(childAttr.Location.Start); vs.ReplaceInActiveDocOnLine($"{tag.ElementName}.{childAttr.Name}", $"{tag.Name}.{childAttr.Name}", renameLineNumber); } break; } }
private string GetSubElementAtStar(string outerElement) { var offset = outerElement.IndexOf('☆'); return(XamlElementProcessor.GetSubElementAtPosition(outerElement.Replace("☆", string.Empty), offset)); }