internal CssSelectorCombination(CssCombinator combinator, ICssSelectorChain leftOperand, ICssSelectorSequence rightOperand) : base(CalculateSpecificity(leftOperand, rightOperand)) { ArgChecker.AssertIsTrue <ArgumentException>(leftOperand.Subject.PseudoElement == null, "Pseudo-elements are only allowed in the right operand of a combinator"); _combinator = combinator; _leftOperand = leftOperand; _rightOperand = rightOperand; }
/// <summary> /// Inserts the given combinator. /// </summary> /// <param name="cssCombinator">The combinator to insert.</param> public void Insert(CssCombinator cssCombinator) { hasCombinator = true; if (cssCombinator != CssCombinator.Descendent) { combinator = cssCombinator; } }
public void AppendSelector(ISelector selector, CssCombinator combinator) { if (!IsReady) { _selectors.Add(new CombinatorSelector { Selector = combinator.Change(selector), Transform = combinator.Transform, Delimiter = combinator.Delimiter }); } }
/// <summary> /// Appends a selector to the complex of selectors. /// </summary> /// <param name="selector">The selector to append.</param> /// <param name="combinator">The combinator to use.</param> /// <returns>The current complex selector.</returns> public ComplexSelector AppendSelector(ISelector selector, CssCombinator combinator) { if (IsReady) { return(this); } selectors.Add(new CombinatorSelector { Selector = combinator.Change(selector), Transform = combinator.Transform, Delimiter = combinator.Delimiter }); return(this); }
/// <summary> /// Inserts the given selector. /// </summary> /// <param name="selector">The selector to insert.</param> public void Insert(Selector selector) { if (temp != null) { if (!hasCombinator) { var compound = temp as CompoundSelector; if (compound == null) { compound = new CompoundSelector(); compound.AppendSelector(temp); } compound.AppendSelector(selector); temp = compound; } else { if (complex == null) { complex = new ComplexSelector(); } complex.AppendSelector(temp, combinator); combinator = CssCombinator.Descendent; hasCombinator = false; temp = selector; } } else { combinator = CssCombinator.Descendent; hasCombinator = false; temp = selector; } }
/// <summary> /// Appends a selector to the complex of selectors. /// </summary> /// <param name="selector">The selector to append.</param> /// <param name="combinator">The combinator to use.</param> /// <returns>The current complex selector.</returns> public ComplexSelector AppendSelector(ISelector selector, CssCombinator combinator) { if (IsReady) { return(this); } Func <IElement, IEnumerable <IElement> > transform = null; char delim; switch (combinator) { case CssCombinator.Child: { delim = Specification.GreaterThan; transform = el => Single(el.ParentElement); break; } case CssCombinator.AdjacentSibling: { delim = Specification.Plus; transform = el => Single(el.PreviousElementSibling); break; } case CssCombinator.Descendent: { delim = Specification.Space; transform = el => { var parents = new List <IElement>(); var parent = el.ParentElement; while (parent != null) { parents.Add(parent); parent = parent.ParentElement; } return(parents); }; break; } case CssCombinator.Sibling: { delim = Specification.Tilde; transform = el => { var parent = el.ParentElement; if (parent == null) { return(new IElement[0]); } var kids = parent.Children; var siblings = new List <IElement>(); foreach (var kid in kids) { if (kid == el) { break; } siblings.Add(kid); } //var passed = false; //for (int i = kids.Length - 1; i >= 0; i--) //{ // if (kids[i] == el) // passed = true; // else if (passed) // siblings.Add(kids[i]); //} return(siblings); }; break; } default: return(this); } selectors.Add(new CombinatorSelector { selector = selector, transform = transform, delimiter = delim }); return(this); }
/// <summary> /// Appends a selector to the complex of selectors. /// </summary> /// <param name="selector">The selector to append.</param> /// <param name="combinator">The combinator to use.</param> /// <returns>The current complex selector.</returns> public ComplexSelector AppendSelector(ISelector selector, CssCombinator combinator) { if (IsReady) { return(this); } Func <IElement, IEnumerable <IElement> > transform = null; char delim; switch (combinator) { case CssCombinator.Child: { delim = Symbols.GreaterThan; transform = el => Single(el.ParentElement); break; } case CssCombinator.AdjacentSibling: { delim = Symbols.Plus; transform = el => Single(el.PreviousElementSibling); break; } case CssCombinator.Descendent: { delim = Symbols.Space; transform = el => { var parents = new List <IElement>(); var parent = el.ParentElement; while (parent != null) { parents.Add(parent); parent = parent.ParentElement; } return(parents); }; break; } case CssCombinator.Sibling: { delim = Symbols.Tilde; transform = el => { var parent = el.ParentElement; if (parent == null) { return(new IElement[0]); } var siblings = new List <IElement>(); foreach (var child in parent.ChildNodes) { var element = child as IElement; if (element == null) { continue; } else if (Object.ReferenceEquals(element, el)) { break; } else { siblings.Add(element); } } return(siblings); }; break; } case CssCombinator.Namespace: { var prefix = selector.Text; delim = Symbols.Pipe; transform = el => Single(el); selector = new SimpleSelector(el => MatchesCssNamespace(el, prefix), Priority.Zero, prefix); break; } case CssCombinator.Column: //TODO no real implementation yet //see: http://dev.w3.org/csswg/selectors-4/#the-column-combinator default: return(this); } selectors.Add(new CombinatorSelector { selector = selector, transform = transform, delimiter = delim }); return(this); }
/// <summary> /// Appends a selector to the complex of selectors. /// </summary> /// <param name="selector">The selector to append.</param> /// <param name="combinator">The combinator to use.</param> /// <returns>The current complex selector.</returns> public ComplexSelector AppendSelector(Selector selector, CssCombinator combinator) { if (IsReady) return this; Func<Element, IEnumerable<Element>> transform = null; char delim; switch (combinator) { case CssCombinator.Child: delim = Specification.GT; transform = el => Single(el.ParentElement); break; case CssCombinator.AdjacentSibling: delim = Specification.PLUS; transform = el => Single(el.PreviousElementSibling); break; case CssCombinator.Descendent: delim = Specification.SPACE; transform = el => { var parents = new List<Element>(); var parent = el.ParentElement; while(parent != null) { parents.Add(parent); parent = parent.ParentElement; } return parents; }; break; case CssCombinator.Sibling: delim = Specification.TILDE; transform = el => { var parent = el.ParentElement; if (parent == null) return new Element[0]; var kids = parent.Children; var passed = false; var siblings = new List<Element>(); for (int i = kids.Length - 1; i >= 0; i--) { if (kids[i] == el) passed = true; else if (passed) siblings.Add(kids[i]); } return siblings; }; break; default: return this; } selectors.Add(new CombinatorSelector { selector = selector, transform = transform, delimiter = delim }); return this; }
/// <summary> /// Creates a new constructor object. /// </summary> public CssSelectorConstructor() { combinator = CssCombinator.Descendent; hasCombinator = false; }
/// <summary> /// Creates a selector consisting of two selector sequences and a <see cref="CssCombinator"/>. /// </summary> /// <param name="leftSelector">The left operand of the combination operator.</param> /// <param name="combinator">The combination operator.</param> /// <param name="rightSelector">The right operand of the combination operator.</param> /// <returns>The newly created combined selector.</returns> public static ICssSelectorChain Combine(this ICssSelectorChain leftSelector, CssCombinator combinator, ICssSelectorSequence rightSelector) { return(new CssSelectorCombination(combinator, leftSelector, rightSelector)); }
/// <summary> /// Appends a selector to the complex of selectors. /// </summary> /// <param name="selector">The selector to append.</param> /// <param name="combinator">The combinator to use.</param> /// <returns>The current complex selector.</returns> public ComplexSelector AppendSelector(Selector selector, CssCombinator combinator) { if (IsReady) { return(this); } Func <Element, IEnumerable <Element> > transform = null; char delim; switch (combinator) { case CssCombinator.Child: delim = Specification.GT; transform = el => Single(el.ParentElement); break; case CssCombinator.AdjacentSibling: delim = Specification.PLUS; transform = el => Single(el.PreviousElementSibling); break; case CssCombinator.Descendent: delim = Specification.SPACE; transform = el => { var parents = new List <Element>(); var parent = el.ParentElement; while (parent != null) { parents.Add(parent); parent = parent.ParentElement; } return(parents); }; break; case CssCombinator.Sibling: delim = Specification.TILDE; transform = el => { var parent = el.ParentElement; if (parent == null) { return(new Element[0]); } var kids = parent.Children; var passed = false; var siblings = new List <Element>(); for (int i = kids.Length - 1; i >= 0; i--) { if (kids[i] == el) { passed = true; } else if (passed) { siblings.Add(kids[i]); } } return(siblings); }; break; default: return(this); } selectors.Add(new CombinatorSelector { selector = selector, transform = transform, delimiter = delim }); return(this); }
public CombinationTerm(CssCombinator combinator, ICssSelectorSequence rightOperand) { this.Combinator = combinator; this.RightOperand = rightOperand; }
public CombinationMatcher(CssCombinator combinator, ICssElementMatcher leftOperand, ICssElementMatcher rightOperand) { _combinator = combinator; _leftOperand = leftOperand; _rightOperand = rightOperand; }