Ejemplo n.º 1
0
        private static IList <IDomElement <TDependencyObject> > UpdateMatchingStyles(
            StyleSheet styleSheet,
            IDomElement <TDependencyObject> startFromLogical,
            IDomElement <TDependencyObject> startFromVisual,
            Dictionary <TDependencyObject, StyleUpdateInfo> styleUpdateInfos,
            IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService,
            INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService)
        {
            // var requiredStyleInfos = new List<StyleMatchInfo>();
            IDomElement <TDependencyObject> root = null;

            IDomElement <TDependencyObject> visualTree  = null;
            IDomElement <TDependencyObject> logicalTree = null;

            var found = new List <IDomElement <TDependencyObject> >();

            if (startFromVisual?.StyleInfo.DoMatchCheck == SelectorType.None ||
                startFromLogical?.StyleInfo.DoMatchCheck == SelectorType.None)
            {
                return(new List <IDomElement <TDependencyObject> >());
            }

            return($"{startFromLogical?.GetPath() ?? startFromVisual?.GetPath() ?? "NULL!?!"}".Measure(() =>
            {
                foreach (var rule in styleSheet.Rules)
                {
                    $"{rule.SelectorString}".Measure(() =>
                    {
                        // // Debug.WriteLine($"--- RULE {rule.SelectorString} ----");
                        if (rule.SelectorType == SelectorType.VisualTree)
                        {
                            if (startFromVisual == null)
                            {
                                //continue;
                                return;
                            }
                            if (visualTree == null)
                            {
                                visualTree = startFromVisual;
                                visualTree?.XamlCssStyleSheets.Clear();
                                visualTree?.XamlCssStyleSheets.Add(styleSheet);
                            }

                            root = visualTree;
                        }
                        else
                        {
                            if (startFromLogical == null)
                            {
                                //continue;
                                return;
                            }
                            if (logicalTree == null)
                            {
                                logicalTree = startFromLogical;
                                logicalTree?.XamlCssStyleSheets.Clear();
                                logicalTree?.XamlCssStyleSheets.Add(styleSheet);
                            }

                            root = logicalTree;
                        }

                        if (root == null)
                        {
                            //continue;
                            return;
                        }

                        // apply our selector
                        var matchedNodes = "QuerySelectorAllWithSelf".Measure(() => root.QuerySelectorAllWithSelf(styleSheet, rule.Selectors[0])
                                                                              .Where(x => x != null)
                                                                              .Cast <IDomElement <TDependencyObject> >()
                                                                              .ToList());

                        var matchedElementTypes = matchedNodes
                                                  .Select(x => x.Element.GetType())
                                                  .Distinct()
                                                  .ToList();

                        $"foreach {matchedNodes.Count}".Measure(() =>
                        {
                            foreach (var matchingNode in matchedNodes)
                            {
                                var element = matchingNode.Element;

                                if (!found.Contains(matchingNode))
                                {
                                    found.Add(matchingNode);
                                }

                                var discriminator = "GetInitialStyle".Measure(() => dependencyPropertyService.GetInitialStyle(element) != null ? element.GetHashCode().ToString() : "");
                                var resourceKey = "GetStyleResourceKey".Measure(() => nativeStyleService.GetStyleResourceKey(styleSheet.Id + discriminator, element.GetType(), rule.SelectorString));
                                //var resourceKey = nativeStyleService.GetStyleResourceKey(rule.StyleSheetId, element.GetType(), rule.SelectorString);

                                if (!matchingNode.StyleInfo.CurrentMatchedSelectors.Contains(resourceKey))
                                {
                                    matchingNode.StyleInfo.CurrentMatchedSelectors.Add(resourceKey);
                                }
                            }
                        });
                    });
                }

                "found".Measure(() =>
                {
                    found = found.Distinct().ToList();

                    foreach (var f in found)
                    {
                        f.StyleInfo.DoMatchCheck = SelectorType.None;

                        f.StyleInfo.CurrentMatchedSelectors = f.StyleInfo.CurrentMatchedSelectors.Distinct().Select(x => new
                        {
                            key = x,
                            SpecificityResult = SpecificityCalculator.Calculate(x.Split('{')[1])
                        })
                                                              .OrderBy(x => x.SpecificityResult.IdSpecificity)
                                                              .ThenBy(x => x.SpecificityResult.ClassSpecificity)
                                                              .ThenBy(x => x.SpecificityResult.SimpleSpecificity)
                                                              .ToList()
                                                              .Select(x => x.key)
                                                              .ToList();
                    }
                });

                "SetDoMatchCheckToNoneInSubTree".Measure(() =>
                {
                    SetDoMatchCheckToNoneInSubTree(startFromLogical, styleSheet);
                    SetDoMatchCheckToNoneInSubTree(startFromVisual, styleSheet);
                });
                return found;
            }));
        }
Ejemplo n.º 2
0
        private static void ApplyMatchingStyles(IDomElement <TDependencyObject> domElement, StyleSheet styleSheet,
                                                IStyleResourcesService applicationResourcesService,
                                                INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService)
        {
            var visualElement = domElement.Element;

            if (domElement.StyleInfo == null)
            {
                throw new Exception($"StyleInfo null {domElement.GetType().Name.Replace("DomElement", "")} {domElement.GetPath()}");
            }

            var matchingStyles        = domElement.StyleInfo.CurrentMatchedSelectors;
            var appliedMatchingStyles = domElement.StyleInfo.OldMatchedSelectors;

            var styledBy = domElement.StyleInfo.CurrentStyleSheet;

            if (styledBy != null &&
                styledBy != styleSheet)
            {
                // Debug.WriteLine("    Another Stylesheet");
                return;
            }

            domElement.StyleInfo.CurrentStyleSheet = styleSheet;

            if (!AppliedStyleIdsAreMatchedStyleIds(appliedMatchingStyles, matchingStyles))
            {
                object styleToApply = null;

                if (matchingStyles == null)
                {
                    // RemoveOutdatedStylesFromElementInternal(visualElement, styleSheet, true, true);
                }
                else if (matchingStyles?.Count == 1)
                {
                    if (applicationResourcesService.Contains(matchingStyles[0]) == true)
                    {
                        styleToApply = applicationResourcesService.GetResource(matchingStyles[0]);
                    }

                    if (styleToApply != null)
                    {
                        nativeStyleService.SetStyle(visualElement, (TStyle)styleToApply);
                    }
                    else
                    {
                        nativeStyleService.SetStyle(visualElement, null);
                        // Debug.WriteLine("    Style not found! " + matchingStyles[0]);
                    }
                }
                else if (matchingStyles?.Count > 1)
                {
                    var dict         = new Dictionary <TDependencyProperty, object>();
                    var listTriggers = new List <TDependencyObject>();

                    foreach (var matchingStyle in matchingStyles)
                    {
                        TStyle s = null;
                        if (applicationResourcesService.Contains(matchingStyle) == true)
                        {
                            s = (TStyle)applicationResourcesService.GetResource(matchingStyle);
                        }
                        else
                        {
                            // Debug.WriteLine("    Style not found! " + matchingStyle);
                        }

                        if (s != null)
                        {
                            var subDict = nativeStyleService.GetStyleAsDictionary(s as TStyle);

                            foreach (var i in subDict)
                            {
                                dict[i.Key] = i.Value;
                            }

                            var triggers = nativeStyleService.GetTriggersAsList(s as TStyle);
                            listTriggers.AddRange(triggers);
                        }
                    }

                    if (dict.Keys.Count > 0 ||
                        listTriggers.Count > 0)
                    {
                        styleToApply = nativeStyleService.CreateFrom(dict, listTriggers, visualElement.GetType());
                    }

                    if (styleToApply != null)
                    {
                        nativeStyleService.SetStyle(visualElement, (TStyle)styleToApply);
                    }
                    else
                    {
                        nativeStyleService.SetStyle(visualElement, null);
                    }
                }

                domElement.StyleInfo.OldMatchedSelectors = matchingStyles.ToList();
            }

            foreach (var child in domElement.ChildNodes)
            {
                ApplyMatchingStyles(child, styleSheet, applicationResourcesService, nativeStyleService);
            }
        }