Exemplo n.º 1
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}-->"));
 }
        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));
        }
Exemplo n.º 3
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));
        }
Exemplo n.º 4
0
 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);
     }
 }
Exemplo n.º 5
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));
        }
        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);
        }
Exemplo n.º 8
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}") })));
Exemplo n.º 9
0
 public AnalysisActions Analyze(RapidXamlElement element)
 {
     // TODO: Implement this analyzer as per your needs.
     // More details at https://github.com/mrlacey/Rapid-XAML-Toolkit/blob/master/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"
                    ));
     }
 }
Exemplo n.º 10
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);
        }
        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);
     }
 }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
0
        private void CheckForXmlns(string alias, RapidXamlElement element, RapidXamlAttribute ignorable, ref AnalysisActions actions)
        {
            var ns = element.Attributes.FirstOrDefault(a => a.ToString() == $"xmlns:{alias}=\"http:/uno.ui/{alias}\"");

            if (ns != null && !ignorable.StringValue.Contains(alias))
            {
                actions.RemoveAttribute(
                    RapidXamlErrorType.Warning,
                    "RXT700",
                    "xmlns '{0}' should be marked as ignorable.".WithParams(alias),
                    "Mark {0} as ignorable".WithParams(alias),
                    ignorable)
                .AndAddAttribute("mc:Ignorable", $"{ignorable.StringValue} {alias}");
            }
        }
Exemplo n.º 15
0
 public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
 {
     return(AnalysisActions.HighlightWithoutAction(RapidXamlErrorType.Warning, "ANYOF01", "just a test. carry on"));
 }
        // Note. Not handled: Col & Row defs of different formats
        // Also, should not return an option to switch to the shorter format if using Min/Max Width/Height properties.
        public AnalysisActions Analyze(RapidXamlElement element, ExtraAnalysisDetails extraDetails)
        {
            var colDef = element.GetAttributes("ColumnDefinitions")?.FirstOrDefault();
            var rowDef = element.GetAttributes("RowDefinitions")?.FirstOrDefault();

            bool isOldFormat = true;

            var newColDefXaml = new System.Text.StringBuilder();
            var newRowDefXaml = new System.Text.StringBuilder();

            if (colDef != null)
            {
                if (colDef.HasStringValue)
                {
                    isOldFormat = false;

                    var shortValue = colDef.StringValue;

                    var colValues = shortValue.Split(',');

                    newColDefXaml.AppendLine("<Grid.ColumnDefinitions>");
                    foreach (var colValue in colValues)
                    {
                        newColDefXaml.AppendLine($"<ColumnDefinition Width=\"{colValue.Trim()}\" />");
                    }

                    newColDefXaml.AppendLine("</Grid.ColumnDefinitions>");
                }
                else
                {
                    foreach (var oldColDef in colDef.Children)
                    {
                        if (oldColDef.Name == "ColumnDefinition")
                        {
                            // Allow for width being optional and defaulting to Star
                            var width = oldColDef.GetAttributes("Width")?.First()?.StringValue ?? "*";

                            if (newColDefXaml.Length > 0)
                            {
                                newColDefXaml.Append(", ");
                            }

                            newColDefXaml.Append(width);
                        }
                    }
                }
            }

            if (rowDef != null)
            {
                if (rowDef.HasStringValue)
                {
                    isOldFormat = false;

                    var shortValue = rowDef.StringValue;

                    var rowValues = shortValue.Split(',');

                    newRowDefXaml.AppendLine("<Grid.RowDefinitions>");
                    foreach (var rowValue in rowValues)
                    {
                        newRowDefXaml.AppendLine($"<RowDefinition Height=\"{rowValue.Trim()}\" />");
                    }

                    newRowDefXaml.AppendLine("</Grid.RowDefinitions>");
                }
                else
                {
                    foreach (var oldRowDef in rowDef.Children)
                    {
                        if (oldRowDef.Name == "RowDefinition")
                        {
                            // Allow for width being optional and defaulting to Star
                            var height = oldRowDef.GetAttributes("Height")?.First()?.StringValue ?? "*";

                            if (newRowDefXaml.Length > 0)
                            {
                                newRowDefXaml.Append(", ");
                            }

                            newRowDefXaml.Append(height);
                        }
                    }
                }
            }

            if (colDef != null || rowDef != null)
            {
                if (isOldFormat)
                {
                    // Offer option to use shorter (new) syntax.
                    return(AnalysisActions
                           .RemoveAttribute(
                               RapidXamlErrorType.Warning,
                               "WINUI673A",
                               description: "Can change to other syntax.",
                               actionText: "Use shorter definition syntax",
                               attribute: colDef,
                               moreInfoUrl: "https://github.com/microsoft/microsoft-ui-xaml/issues/673")
                           .AndAddAttribute("ColumnDefinitions", newColDefXaml.ToString().TrimEnd(',', ' '))
                           .AndRemoveAttribute(rowDef)
                           .AndAddAttribute("RowDefinitions", newRowDefXaml.ToString().TrimEnd(',', ' ')));
                }
                else
                {
                    // Offer option to use longer (old) syntax.
                    return(AnalysisActions
                           .RemoveAttribute(
                               RapidXamlErrorType.Warning,
                               "WINUI673B",
                               description: "Can change to other syntax.",
                               actionText: "Use old definition syntax",
                               attribute: colDef,
                               moreInfoUrl: "https://github.com/microsoft/microsoft-ui-xaml/issues/673")
                           .AndAddChildString(newColDefXaml.ToString())
                           .AndRemoveAttribute(rowDef)
                           .AndAddChildString(newRowDefXaml.ToString()));
                }
            }

            // If not returned an action
            return(AnalysisActions.None);
        }
Exemplo n.º 17
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);
        }