public static bool MatchRightToLeft(VisualElement element, StyleComplexSelector complexSelector, Action <VisualElement, MatchResultInfo> processResult) { VisualElement visualElement = element; int i = complexSelector.selectors.Length - 1; VisualElement visualElement2 = null; int num = -1; bool result; while (i >= 0) { bool flag = visualElement == null; if (flag) { break; } MatchResultInfo matchResultInfo = StyleSelectorHelper.MatchesSelector(visualElement, complexSelector.selectors[i]); processResult(visualElement, matchResultInfo); bool flag2 = !matchResultInfo.success; if (flag2) { bool flag3 = i < complexSelector.selectors.Length - 1 && complexSelector.selectors[i + 1].previousRelationship == StyleSelectorRelationship.Descendent; if (flag3) { visualElement = visualElement.parent; } else { bool flag4 = visualElement2 != null; if (!flag4) { break; } visualElement = visualElement2; i = num; } } else { bool flag5 = i < complexSelector.selectors.Length - 1 && complexSelector.selectors[i + 1].previousRelationship == StyleSelectorRelationship.Descendent; if (flag5) { visualElement2 = visualElement.parent; num = i; } bool flag6 = --i < 0; if (flag6) { result = true; return(result); } visualElement = visualElement.parent; } } result = false; return(result); }
public static bool MatchRightToLeft(VisualElement element, StyleComplexSelector complexSelector, Action <VisualElement, MatchResultInfo> processResult) { // see https://speakerdeck.com/constellation/css-jit-just-in-time-compiled-css-selectors-in-webkit for // a detailed explaination of the algorithm var current = element; int nextIndex = complexSelector.selectors.Length - 1; VisualElement saved = null; int savedIdx = -1; // go backward while (nextIndex >= 0) { if (current == null) { break; } MatchResultInfo matchInfo = MatchesSelector(current, complexSelector.selectors[nextIndex]); processResult(current, matchInfo); if (!matchInfo.success) { // if we have a descendent relationship, keep trying on the parent // ie. "div span", div failed on this element, try on the parent // happens earlier than the backtracking saving below if (nextIndex < complexSelector.selectors.Length - 1 && complexSelector.selectors[nextIndex + 1].previousRelationship == StyleSelectorRelationship.Descendent) { current = current.parent; continue; } // otherwise, if there's a previous relationship, it's a 'child' one. backtrack from the saved point and try again // ie. for "#x > .a .b", #x failed, backtrack to .a on the saved element if (saved != null) { current = saved; nextIndex = savedIdx; continue; } break; } // backtracking save // for "a > b c": we're considering the b matcher. c's previous relationship is Descendent // save the current element parent to try to match b again if (nextIndex < complexSelector.selectors.Length - 1 && complexSelector.selectors[nextIndex + 1].previousRelationship == StyleSelectorRelationship.Descendent) { saved = current.parent; savedIdx = nextIndex; } // from now, the element is a match if (--nextIndex < 0) { return(true); } current = current.parent; } return(false); }