Example #1
0
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            if (element.ContainsDescendant("TwoPaneView"))
            {
                var invalidDescendants = element.GetDescendants("TwoPaneView");

                var result = AnalysisActions.EmptyList;

                foreach (var desc in invalidDescendants)
                {
                    result.HighlightDescendantWithoutAction(
                        RapidXamlErrorType.Error,
                        code: "WinUI-2PV",
                        description: "Do not put a TwoPaneView inside the pane of another TwoPaneview.",
                        descendant: desc,
                        moreInfoUrl: "https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/two-pane-view#dos-and-donts");
                }

                return(result);
            }
            else
            {
                return(AnalysisActions.None);
            }
        }
Example #2
0
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            if (!extraDetails.TryGet("framework", out ProjectFramework framework) ||
                framework != ProjectFramework.Uwp)
            {
                return(AnalysisActions.None);
            }

            var result = AnalysisActions.EmptyList;

            foreach (var attribute in element.Attributes)
            {
                if (attribute.HasStringValue)
                {
                    var attrValue = attribute.StringValue;

                    if (attrValue.StartsWith("{Binding"))
                    {
                        result.RemoveAttribute(RapidXamlErrorType.Suggestion, "RXTPOC", $"Use 'x:Bind' rather than 'Binding' for '{attribute.Name}'.", "Change to 'x:Bind'", attribute)
                        .AndAddAttribute(attribute.Name, attrValue.Replace("{Binding", "{x:Bind"));
                    }
                }
            }

            return(result);
        }
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            if (!extraDetails.TryGet("framework", out ProjectFramework framework) ||
                (framework != ProjectFramework.Uwp && framework != ProjectFramework.Wpf))
            {
                return(AnalysisActions.None);
            }

            var result = AnalysisActions.EmptyList;

            if (framework.Equals(ProjectFramework.Uwp))
            {
                // TODO: Issue#163 - check for hard-coded string for  Attributes.Content
                // Then remove CheckBoxProcessor, CheckBoxCheckedAndUncheckedEventsTag & MissingCheckBoxEvents
            }

            // If using one event, the recommendation is to use both
            var hasCheckedEvent   = element.HasAttribute(Attributes.CheckedEvent);
            var hasuncheckedEvent = element.HasAttribute(Attributes.UncheckedEvent);

            if (hasCheckedEvent && !hasuncheckedEvent)
            {
                var existingCheckedName = element.Attributes.FirstOrDefault(a => a.Name == Attributes.CheckedEvent).StringValue;

                var newEventName = existingCheckedName.ToLowerInvariant().Contains("checked")
                    ? existingCheckedName.Replace("Checked", "UnChecked").Replace("checked", "Unchecked")
                    : "OnCheckBoxUnchecked";

                result.AddAttribute(
                    RapidXamlErrorType.Warning,
                    "RXT401",
                    StringRes.UI_XamlAnalysisCheckBoxCheckedAndUncheckedEventsDescription,
                    StringRes.UI_XamlAnalysisCheckBoxCheckedAndUncheckedEventsToolTip,
                    Attributes.UncheckedEvent,
                    newEventName,
                    StringRes.UI_XamlAnalysisCheckBoxCheckedAndUncheckedEventsExtendedMessage,
                    "https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/checkbox#handle-click-and-checked-events");
            }

            if (!hasCheckedEvent && hasuncheckedEvent)
            {
                var existingUnheckedName = element.Attributes.FirstOrDefault(a => a.Name == Attributes.UncheckedEvent).StringValue;

                var newEventName = existingUnheckedName.ToLowerInvariant().Contains("unchecked")
                    ? existingUnheckedName.Replace("UnChecked", "Checked").Replace("unchecked", "checked")
                    : "OnCheckBoxChecked";

                result.AddAttribute(
                    RapidXamlErrorType.Warning,
                    "RXT401",
                    StringRes.UI_XamlAnalysisCheckBoxCheckedAndUncheckedEventsDescription,
                    StringRes.UI_XamlAnalysisCheckBoxCheckedAndUncheckedEventsToolTip,
                    Attributes.UncheckedEvent,
                    newEventName,
                    StringRes.UI_XamlAnalysisCheckBoxCheckedAndUncheckedEventsExtendedMessage,
                    "https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/checkbox#handle-click-and-checked-events");
            }

            return(result);
        }
Example #4
0
 public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     // Don't do anything.
     // Knowing this is called is enough as this exists only to know
     // that the parsed file can be turned into a RapidXamlElement.
     return(AnalysisActions.None);
 }
Example #5
0
            public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
            {
                var result = AutoFixAnalysisActions.RenameElement("WebView2");

                result.AndAddAttribute("Source", "https://rapidxaml.dev/");

                return(result);
            }
Example #6
0
            public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
            {
                var result = AutoFixAnalysisActions.RenameElement("newcontrols:WebView2");

                result.AndAddXmlns("newcontrols", "https://somenewdomain/newcontrols");

                return(result);
            }
Example #7
0
 public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     return(AnalysisActions.ReplaceElement(
                RapidXamlErrorType.Suggestion,
                "Test4",
                "Don't use `NewName` yet.",
                "Comment out NewName element",
                $"<!--{element.OriginalString}-->"));
 }
Example #8
0
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            var result = AnalysisActions.EmptyList;

            if (!element.Attributes.Any(a => a.Name == "Mode"))
            {
                result.HighlightWithoutAction(RapidXamlErrorType.Warning, "ISSUE364", $"Set binding mode.");
            }

            return(result);
        }
Example #9
0
 public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     if (!element.ContainsAttribute("OnLoaded"))
     {
         return(AutoFixAnalysisActions.AddAttribute("OnLoaded", "OnLoadedEventHandler"));
     }
     else
     {
         return(AutoFixAnalysisActions.None);
     }
 }
Example #10
0
 public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     if (element.ContainsChild("TextBlock"))
     {
         return(AutoFixAnalysisActions.RemoveChild(element.Children.First(c => c.Name == "TextBlock")));
     }
     else
     {
         return(AutoFixAnalysisActions.None);
     }
 }
        public override void Process(string fileName, int offset, string xamlElement, string linePadding, ITextSnapshot snapshot, TagList tags, List <TagSuppression> suppressions = null)
        {
            var rxElement = RapidXamlElementExtractor.GetElement(xamlElement, offset);

            var details = new ExtraAnalysisDetails(fileName, ProjectFrameworkHelper.FromType(this.ProjectType));

            var analysisActions = this.customProcessor.Analyze(rxElement, details);

            if (!analysisActions.IsNone)
            {
                foreach (var action in analysisActions.Actions)
                {
                    var tagDeps = new CustomAnalysisTagDependencies
                    {
                        AnalyzedElement = rxElement,
                        Action          = action,
                        ElementName     = GetElementName(xamlElement), // Do this to get any xmlns
                        ErrorCode       = action.Code,
                        ErrorType       = TagErrorTypeCreator.FromCustomAnalysisErrorType(action.ErrorType),
                        FileName        = fileName,
                        InsertPos       = offset,
                        Logger          = this.Logger,
                        Snapshot        = snapshot,
                    };

                    // Treat `NotReallyCustomAnalyzer` types as any other built-in type.
                    // Track additional information about 3rd party custom analyzers.
                    if (this.customProcessor is CustomAnalysis.NotReallyCustomAnalyzer)
                    {
                        tagDeps.CustomFeatureUsageValue = this.customProcessor.GetType().Name;
                    }
                    else
                    {
                        tagDeps.CustomFeatureUsageValue = $"{this.customProcessor} {action.Code}";
                    }

                    if (action.Location == null)
                    {
                        // Add one to allow for opening angle bracket
                        tagDeps.Span = new Span(offset + 1, tagDeps.ElementName.Length); // Highlight only the opening element name
                    }
                    else
                    {
                        tagDeps.Span = action.Location.ToSpanPlusStartPos(offset);
                    }

                    tags.TryAdd(
                        new CustomAnalysisTag(tagDeps),
                        xamlElement,
                        suppressions);
                }
            }
        }
            public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
            {
                if (extraDetails.TryGet("xmlns", out Dictionary <string, string> xmlns))
                {
                    this.Count = xmlns.Count();
                    this.Xmlns = xmlns;
                }
                else
                {
                    this.Count = 0;
                }

                return(AnalysisActions.EmptyList);
            }
        public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            // If a namespace alias is defined use the same one for the replacement element name.
            var replacementName = element.Name.Contains(":")
                ? $"{element.Name.Split(':')[0]}:NewName"
                : "NewName";

            return(AnalysisActions.RenameElement(
                       RapidXamlErrorType.Error,
                       "Test3",
                       "OldName is deprecated. Use 'NewName' instead.",
                       "Replace OldName with NewName",
                       replacementName));
        }
        internal AnalysisActions GetActions <T>(string xaml, ProjectType projectType = ProjectType.Any)
            where T : ICustomAnalyzer
        {
            var sut = (T)Activator.CreateInstance(typeof(T));

            var element = RapidXamlElementExtractor.GetElement(xaml);

            var details = new ExtraAnalysisDetails(
                "test.xaml",
                ProjectFrameworkHelper.FromType(projectType));

            var result = sut.Analyze(element, details);

            return(result);
        }
Example #15
0
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            if (!extraDetails.TryGet("framework", out ProjectFramework framework) ||
                framework != ProjectFramework.XamarinForms)
            {
                return(AnalysisActions.None);
            }

            return(AnalysisActions.HighlightWithoutAction(
                       errorType: RapidXamlErrorType.Suggestion,
                       code: "RXT330",
                       description: "CollectionView is a more flexible, and performant alternative to ListView. Consider changing it.",
                       moreInfoUrl: "https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/",
                       descendant: element));
        }
 public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     if (!element.ContainsAttribute("Bar"))
     {
         return(AnalysisActions.AddAttribute(
                    RapidXamlErrorType.Warning,
                    code: "CRXT888",
                    description: "Always specify the 'Bar' attribute",
                    actionText: "Add missing 'Bar' attribute",
                    addAttributeName: "Bar",
                    addAttributeValue: "TODO-SET-THIS"));
     }
     else
     {
         return(AnalysisActions.None);
     }
 }
Example #17
0
        public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            var firstChild = element.Children.FirstOrDefault();

            if (firstChild != null)
            {
                return(AnalysisActions.RemoveChild(
                           RapidXamlErrorType.Warning,
                           "Test7",
                           "First child can be removed",
                           $"Remove {firstChild.Name}",
                           firstChild));
            }
            else
            {
                return(AnalysisActions.None);
            }
        }
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            var defaultAlias = "newns";
            var nsvalue      = "using:mynewnamespace";

            var aliasToUse = defaultAlias;

            extraDetails.TryGet("xmlns", out Dictionary <string, string> xmlns);

            if (xmlns != null)
            {
                if (xmlns.ContainsKey(defaultAlias))
                {
                    if (xmlns[defaultAlias] == nsvalue)
                    {
                        // What would be added is already there
                        return(AnalysisActions.EmptyList);
                    }
                    else
                    {
                        if (xmlns.ContainsValue(nsvalue))
                        {
                            // It already exists with a different alias
                            // In other scenarios, this might affect what is used in other operations
                        }

                        var suffix = 1;
                        while (xmlns.ContainsKey(aliasToUse))
                        {
                            aliasToUse = defaultAlias + suffix++.ToString();
                        }
                    }
                }
            }

            return(AnalysisActions.AddXmlns(
                       RapidXamlErrorType.Warning,
                       "addns",
                       $"add xmlns ({aliasToUse})",
                       "add xmlns",
                       aliasToUse,
                       nsvalue));
        }
Example #19
0
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            var result = AnalysisActions.EmptyList;

            foreach (var attribute in element.Attributes)
            {
                if (attribute.HasStringValue)
                {
                    var attrValue = attribute.StringValue;

                    if (attrValue.StartsWith("{Binding ") && !attrValue.Contains(" Mode="))
                    {
                        result.HighlightAttributeWithoutAction(RapidXamlErrorType.Warning, "ISSUE364", $"Set binding mode for '{attribute.Name}'.", attribute);
                    }
                }
            }

            return(result);
        }
        public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            var defaultAllias = "controls";
            var xmlnamespace  = "using:Microsoft.UI.Xaml.Controls";
            var aliasToUse    = defaultAllias;
            var addAlias      = true;

            extraDetails.TryGet("xmlns", out Dictionary <string, string> xmlns);

            // Check to see if there is already an alias for the desired namespace
            var xns = xmlns.FirstOrDefault(x => x.Value == xmlnamespace);

            if (xns.Equals(default(KeyValuePair <string, string>)))
            {
                // Make the default alias unique (if already in use) by adding a number to the end
                var numericSuffix = 1;
                while (xmlns.ContainsKey(aliasToUse))
                {
                    aliasToUse = defaultAllias + numericSuffix++.ToString();
                }
            }
            else
            {
                aliasToUse = xns.Key;
                addAlias   = false;
            }

            // var result = AutoFixAnalysisActions.RenameElement($"{aliasToUse}:WebView2");
            var result = AnalysisActions.RenameElement(
                RapidXamlErrorType.Warning,
                "WEBV2",
                "Replace WebView with, the new and improved, WebView2",
                "Replace WebView with WebView2",
                $"{aliasToUse}:WebView2");

            if (addAlias)
            {
                result.AndAddXmlns(aliasToUse, xmlnamespace);
            }

            return(result);
        }
Example #21
0
 public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     // TODO: Implement this analyzer as per your needs.
     // More details at https://github.com/mrlacey/Rapid-XAML-Toolkit/blob/main/docs/custom-analysis.md
     if (element.ContainsAttribute("IsEnabled"))
     {
         return(AnalysisActions.None);
     }
     else
     {
         return(AnalysisActions.AddAttribute(
                    errorType: RapidXamlErrorType.Warning,
                    code: "XMPL01",
                    description: "Always set the 'IsEnabled' property on 'MyElement'.",
                    actionText: "Add 'IsEnabled' attribute",
                    addAttributeName: "IsEnabled",
                    addAttributeValue: "True"
                    ));
     }
 }
Example #22
0
 public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     if (element.Children.Count % 2 == 1)
     {
         return(AnalysisActions.AddChildString(
                    RapidXamlErrorType.Suggestion,
                    "Test5",
                    "Add more children.",
                    "Add child element",
                    "<Child />"));
     }
     else
     {
         return(AnalysisActions.AddChild(
                    RapidXamlErrorType.Suggestion,
                    "Test5",
                    "Add more children.",
                    "Add child element",
                    "Child",
                    new List <(string name, string value)>(new[] { ("Name", $"Junior-{element.Children.Count}") })));
Example #23
0
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            var ttlAttr = element.GetAttributes(Attributes.Title).FirstOrDefault();

            if (ttlAttr != null && ttlAttr.HasStringValue)
            {
                var value = ttlAttr.StringValue;

                // TODO: ISSUE#163 change this to an RXT200 when can handle localization of Xamarin.Forms apps
                if (!string.IsNullOrWhiteSpace(value) && char.IsLetterOrDigit(value[0]))
                {
                    return(AnalysisActions.HighlightAttributeWithoutAction(
                               errorType: RapidXamlErrorType.Warning,
                               code: "RXT201",
                               description: StringRes.UI_XamlAnalysisGenericHardCodedStringDescription.WithParams(Elements.Picker, Attributes.Title, value),
                               attribute: ttlAttr));
                }
            }

            return(AnalysisActions.None);
        }
Example #24
0
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            if (!extraDetails.TryGet("framework", out ProjectFramework framework) ||
                framework != ProjectFramework.Uwp)
            {
                return(AnalysisActions.None);
            }

            var result = AnalysisActions.EmptyList;

            var ignorable = element.Attributes.FirstOrDefault(a => a.Name == "mc:Ignorable");

            this.CheckForXmlns("xamarin", element, ignorable, ref result);
            this.CheckForXmlns("not_win", element, ignorable, ref result);
            this.CheckForXmlns("android", element, ignorable, ref result);
            this.CheckForXmlns("ios", element, ignorable, ref result);
            this.CheckForXmlns("wasm", element, ignorable, ref result);
            this.CheckForXmlns("macos", element, ignorable, ref result);

            return(result);
        }
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            AnalysisActions result = AnalysisActions.None;

            var txtAttr = element.GetAttributes(Attributes.Text).FirstOrDefault();

            if (txtAttr != null && txtAttr.HasStringValue)
            {
                var value = txtAttr.StringValue;

                // TODO: ISSUE#163 change this to an RXT200 when can handle localization of Xamarin.Forms apps
                if (!string.IsNullOrWhiteSpace(value) && char.IsLetterOrDigit(value[0]))
                {
                    result.HighlightAttributeWithoutAction(
                        errorType: RapidXamlErrorType.Warning,
                        code: "RXT201",
                        description: StringRes.UI_XamlAnalysisGenericHardCodedStringDescription.WithParams(Elements.EntryCell, Attributes.Text, value),
                        attribute: txtAttr);
                }
            }

            var phAttr = element.GetAttributes("Placeholder").FirstOrDefault();

            if (phAttr != null && phAttr.HasStringValue)
            {
                var value = phAttr.StringValue;

                // TODO: ISSUE#163 change this to an RXT200 when can handle localization of Xamarin.Forms apps
                if (!string.IsNullOrWhiteSpace(value) && char.IsLetterOrDigit(value[0]))
                {
                    result.HighlightAttributeWithoutAction(
                        errorType: RapidXamlErrorType.Warning,
                        code: "RXT201",
                        description: "Entry contains hard-coded Placeholder value '{0}'.".WithParams(value),
                        attribute: phAttr);
                }
            }

            return(result);
        }
 public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     // Don't report anything if the source hasn't been set.
     // Allow for multiple possible values that could be used by accesibility tools.
     if (element.HasAttribute(Attributes.Source) &&
         !element.HasAttribute(Attributes.AutomationId) &&
         !element.HasAttribute(Attributes.APName) &&
         !element.HasAttribute(Attributes.APHelpText) &&
         !element.HasAttribute(Attributes.APLabeledBy))
     {
         return(AnalysisActions.AddAttribute(
                    RapidXamlErrorType.Warning,
                    code: "RXT351",
                    description: StringRes.UI_XamlAnalysisImageButtonAccessibilityDescription,
                    actionText: StringRes.UI_UndoContextAddAutomationDescription,
                    addAttributeName: Attributes.APName,
                    addAttributeValue: "Set this to something meaningful"));
     }
     else
     {
         return(AnalysisActions.None);
     }
 }
Example #27
0
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            if (!extraDetails.TryGet("framework", out ProjectFramework framework) ||
                framework != ProjectFramework.XamarinForms)
            {
                return(AnalysisActions.None);
            }

            // Don't report anything if the source hasn't been set.
            // Allow for multiple possible values that could be used by accesibility tools.
            if (element.HasAttribute(Attributes.Source) &&
                !element.HasAttribute(Attributes.AutomationId) &&
                !element.HasAttribute(Attributes.APName) &&
                !element.HasAttribute(Attributes.APHelpText) &&
                !element.HasAttribute(Attributes.APLabeledBy))
            {
                if (!element.TryGetAttributeStringValue(Attributes.APIsInAccessibleTree, out string inTree) ||
                    inTree.Equals("true", System.StringComparison.InvariantCultureIgnoreCase))
                {
                    return(AnalysisActions.AddAttribute(
                               RapidXamlErrorType.Warning,
                               code: "RXT350",
                               description: StringRes.UI_XamlAnalysisImageAccessibilityDescription,
                               actionText: StringRes.UI_UndoContextAddAutomationDescription,
                               addAttributeName: Attributes.APName,
                               addAttributeValue: "Set this to something meaningful",
                               moreInfoUrl: null,
                               extendedMessage: StringRes.UI_XamlAnalysisImageAccessibilityExtendedMessage)
                           .OrAddAttribute(
                               actionText: StringRes.UI_UndoContextExcludeFromAutomation,
                               addAttributeName: Attributes.APIsInAccessibleTree,
                               addAttributeValue: "false"));
                }
            }

            return(AnalysisActions.None);
        }
Example #28
0
        public override AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            AnalysisActions result = AnalysisActions.None;

            if (!element.HasAttribute(Attributes.Keyboard))
            {
                string nonDefaultSuggestion = null;
                var    xaml = element.OriginalString.ToLowerInvariant();
                if (xaml.Contains("email"))
                {
                    nonDefaultSuggestion = "Email";
                }
                else if (xaml.Contains("phone") || xaml.Contains("cell") || xaml.Contains("mobile"))
                {
                    nonDefaultSuggestion = "Telephone";
                }
                else if (xaml.Contains("url"))
                {
                    nonDefaultSuggestion = "Url";
                }

                result.AddAttribute(
                    RapidXamlErrorType.Suggestion,
                    "RXT300",
                    description: StringRes.UI_XamlAnalysisEntryWithoutKeyboardDescription,
                    actionText: StringRes.UI_UndoContextAddEntryKeyboard,
                    addAttributeName: Attributes.Keyboard,
                    addAttributeValue: "Default",
                    extendedMessage: StringRes.UI_XamlAnalysisEntryWithoutKeyboardExtendedMessage);

                if (!string.IsNullOrEmpty(nonDefaultSuggestion))
                {
                    result.OrAddAttribute(
                        actionText: StringRes.UI_AddEntryKeyboard.WithParams(nonDefaultSuggestion),
                        addAttributeName: Attributes.Keyboard,
                        addAttributeValue: nonDefaultSuggestion);
                }
            }

            var txtAttr = element.GetAttributes(Attributes.Text).FirstOrDefault();

            if (txtAttr != null && txtAttr.HasStringValue)
            {
                var value = txtAttr.StringValue;

                // TODO: ISSUE#163 change this to an RXT200 when can handle localization of Xamarin.Forms apps
                if (!string.IsNullOrWhiteSpace(value) && char.IsLetterOrDigit(value[0]))
                {
                    result.HighlightAttributeWithoutAction(
                        errorType: RapidXamlErrorType.Warning,
                        code: "RXT201",
                        description: StringRes.UI_XamlAnalysisGenericHardCodedStringDescription.WithParams(Elements.Entry, Attributes.Text, value),
                        attribute: txtAttr);
                }
            }

            var phAttr = element.GetAttributes(Attributes.Placeholder).FirstOrDefault();

            if (phAttr != null && phAttr.HasStringValue)
            {
                var value = phAttr.StringValue;

                // TODO: ISSUE#163 change this to an RXT200 when can handle localization of Xamarin.Forms apps
                if (!string.IsNullOrWhiteSpace(value) && char.IsLetterOrDigit(value[0]))
                {
                    result.HighlightAttributeWithoutAction(
                        errorType: RapidXamlErrorType.Warning,
                        code: "RXT201",
                        description: StringRes.UI_XamlAnalysisGenericHardCodedStringDescription.WithParams(Elements.Entry, Attributes.Placeholder, value),
                        attribute: phAttr);
                }
            }

            var isPwdAttr = element.GetAttributes(Attributes.IsPassword).FirstOrDefault();

            if (isPwdAttr != null && isPwdAttr.HasStringValue)
            {
                var value = isPwdAttr.StringValue;

                if (value.Equals("true", StringComparison.InvariantCultureIgnoreCase))
                {
                    if (!element.ContainsAttribute(Attributes.MaxLength))
                    {
                        result.AddAttribute(
                            errorType: RapidXamlErrorType.Suggestion,
                            code: "RXT301",
                            description: StringRes.UI_XamlAnalysisPasswordWithoutMaxLengthDescription,
                            extendedMessage: StringRes.UI_XamlAnalysisPasswordWithoutMaxLengthExtendedMessage,
                            actionText: StringRes.UI_UndoContextAddMaxLangthProperty,
                            addAttributeName: Attributes.MaxLength,
                            addAttributeValue: "100");
                    }
                }
            }

            return(result);
        }
            public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
            {
                AnalyzeCallCount += 1;

                return(AnalysisActions.None);
            }
Example #30
0
 public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     return(AutoFixAnalysisActions.RenameElement("WebView2"));
 }