public static bool ParseSelector(string selector, out StyleSelectorPart[] parts) { var matches = rgx.Matches(selector); int count = matches.Count; if (count < 1) { parts = null; return(false); } parts = new StyleSelectorPart[count]; for (int i = 0; i < count; i++) { Match match = matches[i]; StyleSelectorType type = StyleSelectorType.Unknown; string value = string.Empty; if (!string.IsNullOrEmpty(match.Groups["wildcard"].Value)) { value = "*"; type = StyleSelectorType.Wildcard; } else if (!string.IsNullOrEmpty(match.Groups["id"].Value)) { value = match.Groups["id"].Value.Substring(1); type = StyleSelectorType.ID; } else if (!string.IsNullOrEmpty(match.Groups["class"].Value)) { value = match.Groups["class"].Value.Substring(1); type = StyleSelectorType.Class; } else if (!string.IsNullOrEmpty(match.Groups["pseudoclass"].Value)) { var pseudoClassParam = match.Groups["param"].Value; if (!string.IsNullOrEmpty(pseudoClassParam)) { value = pseudoClassParam; type = StyleSelectorType.RecursivePseudoClass; } else { value = match.Groups["pseudoclass"].Value.Substring(1); type = StyleSelectorType.PseudoClass; } } else if (!string.IsNullOrEmpty(match.Groups["type"].Value)) { value = match.Groups["type"].Value; type = StyleSelectorType.Type; } parts[i] = new StyleSelectorPart() { type = type, value = value }; } return(true); }
public static bool ParseSelector(string selector, out StyleSelectorPart[] parts) { MatchCollection matchCollection = CSSSpec.rgx.Matches(selector); int count = matchCollection.Count; bool flag = count < 1; bool result; if (flag) { parts = null; result = false; } else { parts = new StyleSelectorPart[count]; for (int i = 0; i < count; i++) { Match match = matchCollection[i]; StyleSelectorType type = StyleSelectorType.Unknown; string value = string.Empty; bool flag2 = !string.IsNullOrEmpty(match.Groups["wildcard"].Value); if (flag2) { value = "*"; type = StyleSelectorType.Wildcard; } else { bool flag3 = !string.IsNullOrEmpty(match.Groups["id"].Value); if (flag3) { value = match.Groups["id"].Value.Substring(1); type = StyleSelectorType.ID; } else { bool flag4 = !string.IsNullOrEmpty(match.Groups["class"].Value); if (flag4) { value = match.Groups["class"].Value.Substring(1); type = StyleSelectorType.Class; } else { bool flag5 = !string.IsNullOrEmpty(match.Groups["pseudoclass"].Value); if (flag5) { string value2 = match.Groups["param"].Value; bool flag6 = !string.IsNullOrEmpty(value2); if (flag6) { value = value2; type = StyleSelectorType.RecursivePseudoClass; } else { value = match.Groups["pseudoclass"].Value.Substring(1); type = StyleSelectorType.PseudoClass; } } else { bool flag7 = !string.IsNullOrEmpty(match.Groups["type"].Value); if (flag7) { value = match.Groups["type"].Value; type = StyleSelectorType.Type; } } } } } parts[i] = new StyleSelectorPart { type = type, value = value }; } result = true; } return(result); }
unsafe internal void CalculateHashes() { if (isSimple) { return; } // Collect all selector parts except for the last selector, as a visual element was already // matched against the last selector when the time comes to query the Bloom filter. for (int i = selectors.Length - 2; i > -1; i--) { m_HashList.AddRange(selectors[i].parts); } m_HashList.RemoveAll(p => p.type != StyleSelectorType.Class && p.type != StyleSelectorType.ID && p.type != StyleSelectorType.Type); // The ancestorHashes member contains up to 4 hash keys that will be used to query the Bloom // filter during a hierarchical Visual Element traversal. The Bloom filter contains the hash // values of all the ID, Class and Type strings of visited Visual Elements. In order for any // complex selector to match, all of its hash keys must be found in the Bloom filter. We use // the most relevant parts for the search for performance reasons and it can't produce false // rejections. // Sort parts in decreasing type order, then value order, i.e. in ID, Class, Type order. m_HashList.Sort(StyleSelectorPartCompare); // Add unique parts from left to right. bool isFirstEntry = true; StyleSelectorType lastType = StyleSelectorType.Unknown; string lastValue = ""; int partIndex = 0; int max = Math.Min(Hashes.kSize, m_HashList.Count); for (int i = 0; i < max; i++) { if (isFirstEntry) { isFirstEntry = false; } else { // Skip duplicate parts while ((partIndex < m_HashList.Count) && m_HashList[partIndex].type == lastType && m_HashList[partIndex].value == lastValue) { partIndex++; } if (partIndex == m_HashList.Count) { break; } } lastType = m_HashList[partIndex].type; lastValue = m_HashList[partIndex].value; Salt salt; if (lastType == StyleSelectorType.ID) { salt = Salt.IdSalt; } else if (lastType == StyleSelectorType.Class) { salt = Salt.ClassSalt; } else { salt = Salt.TagNameSalt; } ancestorHashes.hashes[i] = lastValue.GetHashCode() * (int)salt; } m_HashList.Clear(); }