Пример #1
0
        public void IsNotSelfClosing_MultipleLines()
        {
            var xaml = @"<Element>
</Element>";

            Assert.IsFalse(XamlElementProcessor.IsSelfClosing(xaml.AsSpan()));
        }
Пример #2
0
        public void IsSelfClosing_MultipleLines()
        {
            var xaml = @"<Element
/>";

            Assert.IsTrue(XamlElementProcessor.IsSelfClosing(xaml.AsSpan()));
        }
Пример #3
0
        public void GetElementName_SpaceSelfClosing_WithOffset()
        {
            var xaml = "<Ex><Foo />";

            var actual = XamlElementProcessor.GetElementName(xaml.AsSpan(), 4);

            Assert.AreEqual("Foo", actual);
        }
Пример #4
0
        public void GetElementName_Attribute_WithOffset()
        {
            var xaml = "<Ex><Foo Bar=\"True\"></Foo>";

            var actual = XamlElementProcessor.GetElementName(xaml.AsSpan(), 4);

            Assert.AreEqual("Foo", actual);
        }
Пример #5
0
        public void GetElementName_NotEmpty_WithOffset()
        {
            var xaml = "<Ex><Foo>Bar</Foo>";

            var actual = XamlElementProcessor.GetElementName(xaml.AsSpan(), 4);

            Assert.AreEqual("Foo", actual);
        }
Пример #6
0
        public void GetElementName_Empty_NoOffset()
        {
            var xaml = "<Foo></Foo>";

            var actual = XamlElementProcessor.GetElementName(xaml.AsSpan());

            Assert.AreEqual("Foo", actual);
        }
Пример #7
0
        public void IsNotSelfClosing_WithNestedSelfClosing_MultipleLines()
        {
            var xaml = @"<Element>
    <OtherElement />
</Element>";

            Assert.IsFalse(XamlElementProcessor.IsSelfClosing(xaml));
        }
Пример #8
0
        public void GetOpeningWithoutChildren_NoChildren()
        {
            var origin   = "<Foo Bar=\"123\"></Foo>";
            var expected = "<Foo Bar=\"123\">";

            var actual = XamlElementProcessor.GetOpeningWithoutChildren(origin);

            Assert.AreEqual(expected, actual);
        }
Пример #9
0
        public void GetOpeningWithoutChildren_SelfClosing()
        {
            var origin   = "<Foo Bar=\"123\" />";
            var expected = origin;

            var actual = XamlElementProcessor.GetOpeningWithoutChildren(origin);

            Assert.AreEqual(expected, actual);
        }
Пример #10
0
        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);
        }
Пример #11
0
        public void GetElementName_MultiLineSelfClosing_WithOffset()
        {
            var xaml = @"<Ex><Foo
ar=""True""
/>";

            var actual = XamlElementProcessor.GetElementName(xaml.AsSpan(), 4);

            Assert.AreEqual("Foo", actual);
        }
Пример #12
0
        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);
        }
Пример #13
0
 public void ClosingTag_IsSelfClosing()
 {
     Assert.IsTrue(XamlElementProcessor.IsSelfClosing("</Element>".AsSpan()));
 }
Пример #14
0
        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);
        }
Пример #15
0
 public void IsNotSelfClosing()
 {
     Assert.IsFalse(XamlElementProcessor.IsSelfClosing("<Element></Element>".AsSpan()));
 }
Пример #16
0
 public void IsSelfClosing()
 {
     Assert.IsTrue(XamlElementProcessor.IsSelfClosing("<Element />".AsSpan()));
 }
Пример #17
0
        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()));
        }
Пример #18
0
 public void IsNotSelfClosing_WithNestedSelfClosing()
 {
     Assert.IsFalse(XamlElementProcessor.IsSelfClosing("<Element><OtherElement /></Element>".AsSpan()));
 }
Пример #19
0
#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;
            }
        }
Пример #20
0
        private string GetSubElementAtStar(string outerElement)
        {
            var offset = outerElement.IndexOf('☆');

            return(XamlElementProcessor.GetSubElementAtPosition(outerElement.Replace("☆", string.Empty), offset));
        }