protected void UnapplyMatchingStylesInternal(TDependencyObject bindableObject, StyleSheet styleSheet) { if (bindableObject == null) { return; } var currentStyleSheet = dependencyPropertyService.GetStyleSheet(bindableObject); if (currentStyleSheet != null && currentStyleSheet != styleSheet) { return; } foreach (var child in treeNodeProvider.GetChildren(bindableObject).ToList()) { UnapplyMatchingStylesInternal(child, styleSheet); } /*var matchingStyles = dependencyPropertyService.GetMatchingStyles(bindableObject) ?? new string[0]; * if (matchingStyles.Length > 0) * { * Debug.WriteLine($"Unapply: {string.Join(", ", dependencyPropertyService.GetMatchingStyles(bindableObject) ?? new string[0])}"); * }*/ dependencyPropertyService.SetHandledCss(bindableObject, false); dependencyPropertyService.SetMatchingStyles(bindableObject, null); dependencyPropertyService.SetAppliedMatchingStyles(bindableObject, null); nativeStyleService.SetStyle(bindableObject, dependencyPropertyService.GetInitialStyle(bindableObject)); }
public MatchResult Match <TDependencyObject, TDependencyProperty>(StyleSheet styleSheet, IDomElement <TDependencyObject, TDependencyProperty> domElement) where TDependencyObject : class { return(Match(styleSheet, domElement, -1, 0)); }
protected void RemoveStyleResourcesInternal(TUIElement styleResourceReferenceHolder, StyleSheet styleSheet) { // Debug.WriteLine("----------------"); // Debug.WriteLine("RemoveStyleResourcesInternal"); var resourceKeys = applicationResourcesService.GetKeys() .OfType <string>() .Where(x => x.StartsWith(nativeStyleService.BaseStyleResourceKey + "_" + styleSheet.Id, StringComparison.Ordinal)) .ToList(); // Debug.WriteLine(" - remove resourceKeys: " + string.Join(", ", resourceKeys)); foreach (var key in resourceKeys) { applicationResourcesService.RemoveResource(key); } }
private void ApplyMatchingStyles(TUIElement visualElement, StyleSheet styleSheet) { if (visualElement == null || dependencyPropertyService.GetHandledCss(visualElement)) { return; } var currentStyleSheet = dependencyPropertyService.GetStyleSheet(visualElement); if (currentStyleSheet != null && currentStyleSheet != styleSheet) { return; } foreach (var child in treeNodeProvider.GetChildren(visualElement).ToList()) { ApplyMatchingStyles(child as TUIElement, styleSheet); } var matchingStyles = dependencyPropertyService.GetMatchingStyles(visualElement); var appliedMatchingStyles = dependencyPropertyService.GetAppliedMatchingStyles(visualElement); if (matchingStyles == appliedMatchingStyles || ( matchingStyles != null && appliedMatchingStyles != null && matchingStyles.SequenceEqual(appliedMatchingStyles) )) { return; } object styleToApply = null; if (matchingStyles?.Length == 1) { if (applicationResourcesService.Contains(matchingStyles[0]) == true) { styleToApply = applicationResourcesService.GetResource(matchingStyles[0]); } if (styleToApply != null) { nativeStyleService.SetStyle(visualElement, (TStyle)styleToApply); } } else if (matchingStyles?.Length > 1) { var dict = new Dictionary <TDependencyProperty, object>(); foreach (var matchingStyle in matchingStyles) { object s = null; if (applicationResourcesService.Contains(matchingStyle) == true) { s = applicationResourcesService.GetResource(matchingStyle); } var subDict = nativeStyleService.GetStyleAsDictionary(s as TStyle); if (subDict != null) { foreach (var i in subDict) { dict[i.Key] = i.Value; } } } if (dict.Keys.Count > 0) { styleToApply = nativeStyleService.CreateFrom(dict, visualElement.GetType()); } if (styleToApply != null) { nativeStyleService.SetStyle(visualElement, (TStyle)styleToApply); } } dependencyPropertyService.SetHandledCss(visualElement, true); dependencyPropertyService.SetAppliedMatchingStyles(visualElement, matchingStyles); // Debug.WriteLine($"Applying: {string.Join(", ", dependencyPropertyService.GetMatchingStyles(visualElement) ?? new string[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); } }
public void RemoveStyleResources(TUIElement styleResourceReferenceHolder, StyleSheet styleSheet) { EnqueueRemoveStyleSheet(styleResourceReferenceHolder, styleSheet, null); }
public override MatchResult Match <TDependencyObject, TDependencyProperty>(StyleSheet styleSheet, ref IDomElement <TDependencyObject, TDependencyProperty> domElement, SelectorMatcher[] fragments, ref int currentIndex) { return(domElement.Id == Text ? MatchResult.Success : MatchResult.ItemFailed); }
private static void SetDoMatchCheckToNoneInSubTree(IDomElement <TDependencyObject, TDependencyProperty> domElement, StyleSheet styleSheet, SelectorType type) { if (domElement == null || !domElement.IsReady || !ReferenceEquals(domElement.StyleInfo.CurrentStyleSheet, styleSheet)) { return; } domElement.StyleInfo.DoMatchCheck = SelectorType.None; var children = type == SelectorType.VisualTree ? domElement.ChildNodes : domElement.LogicalChildNodes; foreach (var child in children) { SetDoMatchCheckToNoneInSubTree(child, styleSheet, type); } }
private static MatchResult GeneralVisualDescendantCombinator <TDependencyObject, TDependencyProperty>(StyleSheet styleSheet, ref IDomElement <TDependencyObject, TDependencyProperty> domElement, SelectorMatcher[] fragments, ref int currentIndex) { currentIndex--; var fragment = fragments[currentIndex]; var current = domElement.Parent; while (current != null) { if (fragment.Match(styleSheet, ref current, fragments, ref currentIndex).IsSuccess) { domElement = current; return(MatchResult.Success); } current = current.Parent; } return(MatchResult.GeneralParentFailed); }
public virtual MatchResult Match <TDependencyObject, TDependencyProperty>(StyleSheet styleSheet, ref IDomElement <TDependencyObject, TDependencyProperty> domElement, SelectorMatcher[] fragments, ref int currentIndex) { if (Type == CssNodeType.GeneralDescendantCombinator) { currentIndex--; var savedIndex = currentIndex; var fragment = fragments[currentIndex]; var current = fragment.Type == CssNodeType.PseudoSelector && fragment.Text == ":visualtree" ? domElement.Parent : domElement.LogicalParent; while (current != null) { MatchResult res = null; while (currentIndex >= 0) { fragment = fragments[currentIndex]; res = fragment.Match(styleSheet, ref current, fragments, ref currentIndex); if (!res.IsSuccess) { break; } currentIndex--; } currentIndex++; if (res.IsSuccess) { domElement = current; return(MatchResult.Success); } currentIndex = savedIndex; fragment = fragments[currentIndex]; current = fragment.Type == CssNodeType.PseudoSelector && fragment.Text == ":visualtree" ? current.Parent : current.LogicalParent; } return(MatchResult.GeneralParentFailed); } else if (Type == CssNodeType.DirectDescendantCombinator) { var result = domElement.LogicalParent?.LogicalChildNodes.Contains(domElement) == true; domElement = domElement.LogicalParent; return(result ? MatchResult.Success : MatchResult.DirectParentFailed); } else if (Type == CssNodeType.GeneralSiblingCombinator) { var thisIndex = domElement.LogicalParent?.LogicalChildNodes.IndexOf(domElement) ?? -1; if (thisIndex == 0) { return(MatchResult.ItemFailed); } currentIndex--; if ((domElement.LogicalParent?.LogicalChildNodes.Count > 0) == true) { foreach (var sibling in domElement.LogicalParent.LogicalChildNodes.Take(thisIndex)) { var refSibling = sibling; if (fragments[currentIndex].Match(styleSheet, ref refSibling, fragments, ref currentIndex).IsSuccess) { domElement = sibling; return(MatchResult.Success); } } } return(MatchResult.ItemFailed); } else if (Type == CssNodeType.DirectSiblingCombinator) { var thisIndex = domElement.LogicalParent?.LogicalChildNodes.IndexOf(domElement) ?? -1; if (thisIndex <= 0) { return(MatchResult.ItemFailed); } var sibling = domElement.LogicalParent?.LogicalChildNodes[thisIndex - 1]; if (sibling == null) { return(MatchResult.ItemFailed); } currentIndex--; var result = fragments[currentIndex].Match(styleSheet, ref sibling, fragments, ref currentIndex); domElement = sibling; return(result); } else if (Type == CssNodeType.PseudoSelector) { if (Text == ":visualtree") { if (domElement.IsInVisualTree == false) { return(MatchResult.ItemFailed); } return(MatchResult.Success); } } return(MatchResult.ItemFailed); }
private static void GenerateStyles(StyleSheet styleSheet, IDictionary <TDependencyObject, StyleUpdateInfo> styleMatchInfos, IStyleResourcesService applicationResourcesService, IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService, INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService, CssTypeHelper <TDependencyObject, TDependencyProperty, TStyle> cssTypeHelper) { applicationResourcesService.EnsureResources(); foreach (var styleMatchInfoKeyValue in styleMatchInfos) { var styleMatchInfo = styleMatchInfoKeyValue.Value; var matchedElementType = styleMatchInfo.MatchedType; foreach (var resourceKey in styleMatchInfo.CurrentMatchedSelectors) { if (applicationResourcesService.Contains(resourceKey)) { continue; } var s = resourceKey.Split('{')[1]; var rule = styleMatchInfo.CurrentStyleSheet.Rules.Where(x => x.SelectorString == s).First(); // // Debug.WriteLine("Generate Style " + resourceKey); CreateStyleDictionaryFromDeclarationBlockResult <TDependencyProperty> result = null; try { result = "CreateStyleDictionaryFromDeclarationBlock".Measure(() => CreateStyleDictionaryFromDeclarationBlock( styleSheet.Namespaces, rule.DeclarationBlock, matchedElementType, (TDependencyObject)styleSheet.AttachedTo, cssTypeHelper)); var propertyStyleValues = result.PropertyStyleValues; foreach (var error in result.Errors) { Debug.WriteLine($@" ERROR (normal) in Selector ""{rule.SelectorString}"": {error}"); styleSheet.AddError($@"ERROR in Selector ""{rule.SelectorString}"": {error}"); } var nativeTriggers = $"CreateTriggers ({rule.DeclarationBlock.Triggers.Count})".Measure(() => rule.DeclarationBlock.Triggers .Select(x => nativeStyleService.CreateTrigger(styleSheet, x, styleMatchInfo.MatchedType, (TDependencyObject)styleSheet.AttachedTo)) .ToList()); var initalStyle = dependencyPropertyService.GetInitialStyle(styleMatchInfoKeyValue.Key); if (initalStyle != null) { var subDict = nativeStyleService.GetStyleAsDictionary(initalStyle as TStyle); foreach (var i in subDict) { propertyStyleValues[i.Key] = i.Value; } var triggers = nativeStyleService.GetTriggersAsList(initalStyle as TStyle); nativeTriggers.AddRange(triggers); } foreach (var item in propertyStyleValues) { if (item.Value == null) { } } var style = "Create Style".Measure(() => nativeStyleService.CreateFrom(propertyStyleValues, nativeTriggers, matchedElementType)); applicationResourcesService.SetResource(resourceKey, style); // // Debug.WriteLine("Finished generate Style " + resourceKey); } catch (Exception e) { Debug.WriteLine($@" ERROR (exception) in Selector ""{rule.SelectorString}"": {e.Message}"); styleSheet.AddError($@"ERROR in Selector ""{rule.SelectorString}"": {e.Message}"); } } } }
private static void SetDoMatchCheckToNoneInSubTree(IDomElement <TDependencyObject> domElement, StyleSheet styleSheet) { if (domElement == null || domElement.StyleInfo.CurrentStyleSheet != styleSheet) { return; } domElement.StyleInfo.DoMatchCheck = SelectorType.None; foreach (var child in domElement.ChildNodes) { SetDoMatchCheckToNoneInSubTree(child, styleSheet); } }
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; })); }
private static void ReevaluateStylesheetInSubTree(IDomElement <TDependencyObject, TDependencyProperty> domElement, StyleSheet oldStyleSheet, IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService, INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService) { if (domElement.StyleInfo == null) { return; } if (domElement == null || !ReferenceEquals(domElement.StyleInfo.CurrentStyleSheet, oldStyleSheet)) { return; } domElement.StyleInfo.CurrentStyleSheet = GetStyleSheetFromTree(domElement, dependencyPropertyService); domElement.ClearAttributeWatcher(); foreach (var child in domElement.LogicalChildNodes.Concat(domElement.ChildNodes).Distinct().ToList()) { ReevaluateStylesheetInSubTree(child, oldStyleSheet, dependencyPropertyService, nativeStyleService); } }
protected void CalculateStylesInternal(TUIElement styleResourceReferenceHolder, StyleSheet styleSheet, TUIElement startFrom) { if (styleResourceReferenceHolder == null || styleSheet == null) { return; } // PrintHerarchyDebugInfo(styleResourceReferenceHolder, startFrom); UnapplyMatchingStylesInternal(startFrom ?? styleResourceReferenceHolder, styleSheet); var requiredStyleInfos = UpdateMatchingStyles(styleResourceReferenceHolder, styleSheet, startFrom); GenerateStyles(styleResourceReferenceHolder, styleSheet, startFrom, requiredStyleInfos); }
private static IList <IDomElement <TDependencyObject, TDependencyProperty> > UpdateMatchingStyles( StyleSheet styleSheet, IDomElement <TDependencyObject, TDependencyProperty> startFrom, Dictionary <TDependencyObject, StyleUpdateInfo> styleUpdateInfos, IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService, INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService) { // var requiredStyleInfos = new List<StyleMatchInfo>(); var found = new HashSet <IDomElement <TDependencyObject, TDependencyProperty> >(); if (startFrom == null || !startFrom.IsReady) { return(found.ToList()); } if (startFrom.StyleInfo.DoMatchCheck == SelectorType.None) { return(new List <IDomElement <TDependencyObject, TDependencyProperty> >()); } startFrom.XamlCssStyleSheets.Clear(); startFrom.XamlCssStyleSheets.Add(styleSheet); var traversed = SelectorType.None; foreach (var rule in styleSheet.Rules) { // // Debug.WriteLine($"--- RULE {rule.SelectorString} ----"); // apply our selector var type = SelectorType.LogicalTree; if (rule.Selectors[0].StartOnVisualTree()) { type = SelectorType.VisualTree; } if ((type == SelectorType.LogicalTree && !startFrom.IsInLogicalTree) || (type == SelectorType.VisualTree && !startFrom.IsInVisualTree) ) { continue; } traversed |= type; var matchedNodes = startFrom.QuerySelectorAllWithSelf(styleSheet, rule.Selectors[0], type) .Where(x => x != null) .Cast <IDomElement <TDependencyObject, TDependencyProperty> >() .ToList(); var matchedElementTypes = matchedNodes .Select(x => x.Element.GetType()) .Distinct() .ToList(); foreach (var matchingNode in matchedNodes) { var element = matchingNode.Element; if (!found.Contains(matchingNode)) { found.Add(matchingNode); } matchingNode.StyleInfo.CurrentMatchedSelectors.Add(rule.Selectors[0]); var initialStyle = dependencyPropertyService.GetInitialStyle(element); var discriminator = initialStyle != null?initialStyle.GetHashCode().ToString() : ""; var resourceKey = nativeStyleService.GetStyleResourceKey(styleSheet.Id + discriminator, element.GetType(), rule.SelectorString); //var resourceKey = nativeStyleService.GetStyleResourceKey(rule.StyleSheetId, element.GetType(), rule.SelectorString); if (!matchingNode.StyleInfo.CurrentMatchedResourceKeys.Contains(resourceKey)) { matchingNode.StyleInfo.CurrentMatchedResourceKeys.Add(resourceKey); } } } foreach (var f in found) { f.StyleInfo.DoMatchCheck = SelectorType.None; f.StyleInfo.CurrentMatchedSelectors = f.StyleInfo.CurrentMatchedSelectors.Distinct() .OrderBy(x => x.IdSpecificity) .ThenBy(x => x.ClassSpecificity) .ThenBy(x => x.SimpleSpecificity) .ToList() .ToLinkedHashSet(); } if ((traversed & SelectorType.VisualTree) > 0) { SetDoMatchCheckToNoneInSubTree(startFrom, styleSheet, SelectorType.VisualTree); } if ((traversed & SelectorType.LogicalTree) > 0) { SetDoMatchCheckToNoneInSubTree(startFrom, styleSheet, SelectorType.LogicalTree); } return(found.ToList()); }
private List <StyleMatchInfo> UpdateMatchingStyles(TUIElement styleResourceReferenceHolder, StyleSheet styleSheet, TUIElement startFrom) { var requiredStyleInfos = new List <StyleMatchInfo>(); IDomElement <TDependencyObject> root = null; IDomElement <TDependencyObject> visualTree = null; IDomElement <TDependencyObject> logicalTree = null; foreach (var rule in styleSheet.Rules) { if (rule.SelectorType == SelectorType.VisualTree) { if (visualTree == null) { visualTree = treeNodeProvider.GetDomElement(startFrom ?? styleResourceReferenceHolder); visualTree.XamlCssStyleSheets.Clear(); visualTree.XamlCssStyleSheets.Add(styleSheet); } root = visualTree; } else { if (logicalTree == null) { logicalTree = treeNodeProvider.GetDomElement(startFrom ?? styleResourceReferenceHolder); logicalTree.XamlCssStyleSheets.Clear(); logicalTree.XamlCssStyleSheets.Add(styleSheet); } root = logicalTree; } // apply our selector var matchedNodes = root.QuerySelectorAllWithSelf(rule.SelectorString) .Where(x => x != null) .Cast <IDomElement <TDependencyObject> >() .ToList(); var otherStyleElements = matchedNodes .Where(x => { var s = dependencyPropertyService.GetStyleSheet(GetStyleSheetParent(x.Element)); return(s != null && s != styleSheet); }).ToList(); matchedNodes = matchedNodes.Except(otherStyleElements).ToList(); // Debug.WriteLine($"matchedNodes: ({matchedNodes.Count}) " + string.Join(", ", matchedNodes.Select(x => x.Id))); var matchedElementTypes = matchedNodes .Select(x => x.Element.GetType()) .Distinct() .ToList(); // Debug.WriteLine($"Matched Types: ({matchedElementTypes.Count}) " + string.Join(", ", matchedElementTypes.Select(x => x.Name))); foreach (var matchingNode in matchedNodes) { var element = matchingNode.Element; var matchingStyles = dependencyPropertyService.GetMatchingStyles(element) ?? new string[0]; var resourceKey = nativeStyleService.GetStyleResourceKey(styleSheet.Id, element.GetType(), rule.SelectorString); dependencyPropertyService.SetMatchingStyles(element, matchingStyles.Concat(new[] { resourceKey }).Distinct().ToArray()); if (requiredStyleInfos.Any(x => x.Rule == rule && x.MatchedType == element.GetType()) == false) { requiredStyleInfos.Add(new StyleMatchInfo { Rule = rule, MatchedType = element.GetType() }); } } } return(requiredStyleInfos); }
private static void GenerateStyles(StyleSheet styleSheet, IDictionary <TDependencyObject, StyleUpdateInfo> styleMatchInfos, IStyleResourcesService applicationResourcesService, IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService, INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService, CssTypeHelper <TDependencyObject, TDependencyProperty, TStyle> cssTypeHelper) { applicationResourcesService.EnsureResources(); foreach (var styleMatchInfoKeyValue in styleMatchInfos) { var styleMatchInfo = styleMatchInfoKeyValue.Value; var matchedElementType = styleMatchInfo.MatchedType; for (var i = 0; i < styleMatchInfo.CurrentMatchedSelectors.Count; i++) { var selector = styleMatchInfo.CurrentMatchedSelectors.ElementAt(i); var resourceKey = styleMatchInfo.CurrentMatchedResourceKeys.ElementAt(i); if (applicationResourcesService.Contains(resourceKey)) { // Debug.WriteLine($"GenerateStyles: Already contains '{s}' ({matchedElementType.Name})"); continue; } // Debug.WriteLine($"GenerateStyles: Generating '{s}' ({matchedElementType.Name})"); var rule = styleMatchInfo.CurrentStyleSheet.Rules.Where(x => x.SelectorString == selector.Value).First(); CreateStyleDictionaryFromDeclarationBlockResult <TDependencyProperty> result = null; try { result = CreateStyleDictionaryFromDeclarationBlock( styleSheet.Namespaces, rule.DeclarationBlock, matchedElementType, (TDependencyObject)styleSheet.AttachedTo, cssTypeHelper); var propertyStyleValues = result.PropertyStyleValues; foreach (var error in result.Errors) { // Debug.WriteLine($@" ERROR (normal) in Selector ""{rule.SelectorString}"": {error}"); styleSheet.AddError($@"ERROR in Selector ""{rule.SelectorString}"": {error}"); } var nativeTriggers = rule.DeclarationBlock.Triggers .Select(x => nativeStyleService.CreateTrigger(styleSheet, x, styleMatchInfo.MatchedType, (TDependencyObject)styleSheet.AttachedTo)) .ToList(); var initalStyle = dependencyPropertyService.GetInitialStyle(styleMatchInfoKeyValue.Key); if (initalStyle != null) { var subDict = nativeStyleService.GetStyleAsDictionary(initalStyle as TStyle); foreach (var item in subDict) { // only set not-overridden properties if (!propertyStyleValues.ContainsKey(item.Key)) { propertyStyleValues[item.Key] = item.Value; } } var triggers = nativeStyleService.GetTriggersAsList(initalStyle as TStyle); nativeTriggers.InsertRange(0, triggers); } //Debug.WriteLine(" Values: " + string.Join(", ", propertyStyleValues.Select(x => ((dynamic)x.Key).PropertyName + ": " + x.Value.ToString()))); var style = nativeStyleService.CreateFrom(propertyStyleValues, nativeTriggers, matchedElementType); applicationResourcesService.SetResource(resourceKey, style); // Debug.WriteLine("Finished generate Style " + resourceKey); } catch (Exception e) { // Debug.WriteLine($@" ERROR (exception) in Selector ""{rule.SelectorString}"": {e.Message}"); styleSheet.AddError($@"ERROR in Selector ""{rule.SelectorString}"": {e.Message}"); } } } }
private static void ReevaluateStylesheetInSubTree(IDomElement <TDependencyObject> domElement, StyleSheet oldStyleSheet, IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService, INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService) { if (domElement.StyleInfo == null) { return; } if (domElement == null || domElement.StyleInfo.CurrentStyleSheet != oldStyleSheet) { return; } domElement.StyleInfo.CurrentStyleSheet = GetStyleSheetFromTree(domElement, dependencyPropertyService); foreach (var child in domElement.ChildNodes) { ReevaluateStylesheetInSubTree(child, oldStyleSheet, dependencyPropertyService, nativeStyleService); } }