public override ISelector Produce() { var valid = _nested.IsValid; var sel = _nested.ToPool(); if (!valid) { return(null); } return(SimpleSelector.PseudoClass(el => { var host = default(IElement); var shadowRoot = el.Parent as IShadowRoot; if (shadowRoot != null) { host = shadowRoot.Host; } while (host != null) { if (sel.Match(host)) { return true; } host = host.ParentElement; } return false; }, String.Concat(PseudoClassNames.HostContext, "(", sel.Text, ")"))); }
public override ISelector Produce() { var valid = _selector.IsValid; var sel = _selector.GetResult(); if (valid) { var code = PseudoClassNames.HostContext.CssFunction(sel.Text); return(SimpleSelector.PseudoClass(el => { var host = default(IElement); var shadowRoot = el.Parent as IShadowRoot; if (shadowRoot != null) { host = shadowRoot.Host; } while (host != null) { if (sel.Match(host)) { return true; } host = host.ParentElement; } return false; }, code)); } return(null); }
static CssSelectorConstructor() { pseudoClassSelectors.Add(PseudoClassNames.Root, SimpleSelector.PseudoClass(el => el.Owner.DocumentElement == el, PseudoClassNames.Root)); pseudoClassSelectors.Add(PseudoClassNames.OnlyType, SimpleSelector.PseudoClass(el => el.IsOnlyOfType(), PseudoClassNames.OnlyType)); pseudoClassSelectors.Add(PseudoClassNames.FirstOfType, SimpleSelector.PseudoClass(el => el.IsFirstOfType(), PseudoClassNames.FirstOfType)); pseudoClassSelectors.Add(PseudoClassNames.LastOfType, SimpleSelector.PseudoClass(el => el.IsLastOfType(), PseudoClassNames.LastOfType)); pseudoClassSelectors.Add(PseudoClassNames.OnlyChild, SimpleSelector.PseudoClass(el => el.IsOnlyChild(), PseudoClassNames.OnlyChild)); pseudoClassSelectors.Add(PseudoClassNames.FirstChild, SimpleSelector.PseudoClass(el => el.IsFirstChild(), PseudoClassNames.FirstChild)); pseudoClassSelectors.Add(PseudoClassNames.LastChild, SimpleSelector.PseudoClass(el => el.IsLastChild(), PseudoClassNames.LastChild)); pseudoClassSelectors.Add(PseudoClassNames.Empty, SimpleSelector.PseudoClass(el => el.ChildElementCount == 0 && el.TextContent.Equals(String.Empty), PseudoClassNames.Empty)); pseudoClassSelectors.Add(PseudoClassNames.AnyLink, SimpleSelector.PseudoClass(el => el.IsLink() || el.IsVisited(), PseudoClassNames.AnyLink)); pseudoClassSelectors.Add(PseudoClassNames.Link, SimpleSelector.PseudoClass(el => el.IsLink(), PseudoClassNames.Link)); pseudoClassSelectors.Add(PseudoClassNames.Visited, SimpleSelector.PseudoClass(el => el.IsVisited(), PseudoClassNames.Visited)); pseudoClassSelectors.Add(PseudoClassNames.Active, SimpleSelector.PseudoClass(el => el.IsActive(), PseudoClassNames.Active)); pseudoClassSelectors.Add(PseudoClassNames.Hover, SimpleSelector.PseudoClass(el => el.IsHovered(), PseudoClassNames.Hover)); pseudoClassSelectors.Add(PseudoClassNames.Focus, SimpleSelector.PseudoClass(el => el.IsFocused, PseudoClassNames.Focus)); pseudoClassSelectors.Add(PseudoClassNames.Target, SimpleSelector.PseudoClass(el => el.IsTarget(), PseudoClassNames.Target)); pseudoClassSelectors.Add(PseudoClassNames.Enabled, SimpleSelector.PseudoClass(el => el.IsEnabled(), PseudoClassNames.Enabled)); pseudoClassSelectors.Add(PseudoClassNames.Disabled, SimpleSelector.PseudoClass(el => el.IsDisabled(), PseudoClassNames.Disabled)); pseudoClassSelectors.Add(PseudoClassNames.Default, SimpleSelector.PseudoClass(el => el.IsDefault(), PseudoClassNames.Default)); pseudoClassSelectors.Add(PseudoClassNames.Checked, SimpleSelector.PseudoClass(el => el.IsChecked(), PseudoClassNames.Checked)); pseudoClassSelectors.Add(PseudoClassNames.Indeterminate, SimpleSelector.PseudoClass(el => el.IsIndeterminate(), PseudoClassNames.Indeterminate)); pseudoClassSelectors.Add(PseudoClassNames.PlaceholderShown, SimpleSelector.PseudoClass(el => el.IsPlaceholderShown(), PseudoClassNames.PlaceholderShown)); pseudoClassSelectors.Add(PseudoClassNames.Unchecked, SimpleSelector.PseudoClass(el => el.IsUnchecked(), PseudoClassNames.Unchecked)); pseudoClassSelectors.Add(PseudoClassNames.Valid, SimpleSelector.PseudoClass(el => el.IsValid(), PseudoClassNames.Valid)); pseudoClassSelectors.Add(PseudoClassNames.Invalid, SimpleSelector.PseudoClass(el => el.IsInvalid(), PseudoClassNames.Invalid)); pseudoClassSelectors.Add(PseudoClassNames.Required, SimpleSelector.PseudoClass(el => el.IsRequired(), PseudoClassNames.Required)); pseudoClassSelectors.Add(PseudoClassNames.ReadOnly, SimpleSelector.PseudoClass(el => el.IsReadOnly(), PseudoClassNames.ReadOnly)); pseudoClassSelectors.Add(PseudoClassNames.ReadWrite, SimpleSelector.PseudoClass(el => el.IsEditable(), PseudoClassNames.ReadWrite)); pseudoClassSelectors.Add(PseudoClassNames.InRange, SimpleSelector.PseudoClass(el => el.IsInRange(), PseudoClassNames.InRange)); pseudoClassSelectors.Add(PseudoClassNames.OutOfRange, SimpleSelector.PseudoClass(el => el.IsOutOfRange(), PseudoClassNames.OutOfRange)); pseudoClassSelectors.Add(PseudoClassNames.Optional, SimpleSelector.PseudoClass(el => el.IsOptional(), PseudoClassNames.Optional)); pseudoElementSelectors.Add(PseudoElementNames.Before, SimpleSelector.PseudoElement(el => el.IsPseudo("::" + PseudoElementNames.Before), PseudoElementNames.Before)); pseudoElementSelectors.Add(PseudoElementNames.After, SimpleSelector.PseudoElement(el => el.IsPseudo("::" + PseudoElementNames.After), PseudoElementNames.After)); pseudoElementSelectors.Add(PseudoElementNames.Selection, SimpleSelector.PseudoElement(el => false, PseudoElementNames.Selection)); pseudoElementSelectors.Add(PseudoElementNames.FirstLine, SimpleSelector.PseudoElement(el => el.HasChildNodes && el.ChildNodes[0].NodeType == NodeType.Text, PseudoElementNames.FirstLine)); pseudoElementSelectors.Add(PseudoElementNames.FirstLetter, SimpleSelector.PseudoElement(el => el.HasChildNodes && el.ChildNodes[0].NodeType == NodeType.Text && el.ChildNodes[0].TextContent.Length > 0, PseudoElementNames.FirstLetter)); // LEGACY STYLE OF DEFINING PSEUDO ELEMENTS - AS PSEUDO CLASS! pseudoClassSelectors.Add(PseudoElementNames.Before, pseudoElementSelectors[PseudoElementNames.Before]); pseudoClassSelectors.Add(PseudoElementNames.After, pseudoElementSelectors[PseudoElementNames.After]); pseudoClassSelectors.Add(PseudoElementNames.FirstLine, pseudoElementSelectors[PseudoElementNames.FirstLine]); pseudoClassSelectors.Add(PseudoElementNames.FirstLetter, pseudoElementSelectors[PseudoElementNames.FirstLetter]); pseudoClassFunctions.Add(PseudoClassNames.NthChild, () => new ChildFunctionState <NthFirstChildSelector>(withOptionalSelector: true)); pseudoClassFunctions.Add(PseudoClassNames.NthLastChild, () => new ChildFunctionState <NthLastChildSelector>(withOptionalSelector: true)); pseudoClassFunctions.Add(PseudoClassNames.NthOfType, () => new ChildFunctionState <NthFirstTypeSelector>(withOptionalSelector: false)); pseudoClassFunctions.Add(PseudoClassNames.NthLastOfType, () => new ChildFunctionState <NthLastTypeSelector>(withOptionalSelector: false)); pseudoClassFunctions.Add(PseudoClassNames.NthColumn, () => new ChildFunctionState <NthFirstColumnSelector>(withOptionalSelector: false)); pseudoClassFunctions.Add(PseudoClassNames.NthLastColumn, () => new ChildFunctionState <NthLastColumnSelector>(withOptionalSelector: false)); pseudoClassFunctions.Add(PseudoClassNames.Not, () => new NotFunctionState()); pseudoClassFunctions.Add(PseudoClassNames.Dir, () => new DirFunctionState()); pseudoClassFunctions.Add(PseudoClassNames.Lang, () => new LangFunctionState()); pseudoClassFunctions.Add(PseudoClassNames.Contains, () => new ContainsFunctionState()); pseudoClassFunctions.Add(PseudoClassNames.Has, () => new HasFunctionState()); pseudoClassFunctions.Add(PseudoClassNames.Matches, () => new MatchesFunctionState()); }
public override ISelector Produce() { if (_valid && _value != null) { var code = PseudoClassNames.Contains.CssFunction(_value); return(SimpleSelector.PseudoClass(el => el.TextContent.Contains(_value), code)); } return(null); }
public override ISelector Produce() { if (_valid && _value != null) { var code = PseudoClassNames.Dir.CssFunction(_value); return(SimpleSelector.PseudoClass(el => el is IHtmlElement && _value.Isi(((IHtmlElement)el).Direction), code)); } return(null); }
public override ISelector Produce() { if (valid && value != null) { var code = PseudoClassNames.Lang.CssFunction(value); return(SimpleSelector.PseudoClass(el => el is IHtmlElement && ((IHtmlElement)el).Language.StartsWith(value, StringComparison.OrdinalIgnoreCase), code)); } return(null); }
public override ISelector Produce() { if (!valid || value == null) { return(null); } var code = String.Concat(PseudoClassNames.Contains, "(", value, ")"); return(SimpleSelector.PseudoClass(el => el.TextContent.Contains(value), code)); }
public override ISelector Produce() { var sel = _nested.ToPool(); if (sel == null) { return(null); } return(SimpleSelector.PseudoClass(el => sel.Match(el), String.Concat(PseudoClassNames.Matches, "(", sel.Text, ")"))); }
public override ISelector Produce() { if (!valid || value == null) { return(null); } var code = String.Concat(PseudoClassNames.Lang, "(", value, ")"); return(SimpleSelector.PseudoClass(el => el is IHtmlElement && ((IHtmlElement)el).Language.StartsWith(value, StringComparison.OrdinalIgnoreCase), code)); }
/// <summary> /// Creates or gets the associated CSS pseudo class selector. /// </summary> /// <param name="name">The name of the CSS pseudo class.</param> /// <returns>The associated selector.</returns> public ISelector Create(String name) { var selector = default(ISelector); if (selectors.TryGetValue(name, out selector)) { return(selector); } return(SimpleSelector.PseudoClass(el => false, name)); }
public override ISelector Produce() { if (!valid || value == null) { return(null); } var code = String.Concat(PseudoClassNames.Dir, "(", value, ")"); return(SimpleSelector.PseudoClass(el => el is IHtmlElement && value.Isi(((IHtmlElement)el).Direction), code)); }
public override ISelector Produce() { var sel = _nested.ToPool(); if (sel == null) { return(null); } return(SimpleSelector.PseudoClass(el => el.ChildNodes.QuerySelector(sel) != null, String.Concat(PseudoClassNames.Has, "(", sel.Text, ")"))); }
public override ISelector Produce() { var valid = _nested.IsValid; var sel = _nested.ToPool(); if (!valid) { return(null); } return(SimpleSelector.PseudoClass(el => !sel.Match(el), String.Concat(PseudoClassNames.Not, "(", sel.Text, ")"))); }
public override ISelector Produce() { var valid = _selector.IsValid; var sel = _selector.GetResult(); if (valid) { var code = PseudoClassNames.Matches.CssFunction(sel.Text); return(SimpleSelector.PseudoClass(el => sel.Match(el), code)); } return(null); }
public override ISelector Produce() { var valid = _nested.IsValid; var sel = _nested.GetResult(); if (valid) { var code = PseudoClassNames.Has.CssFunction(sel.Text); return(SimpleSelector.PseudoClass(el => el.ChildNodes.QuerySelector(sel) != null, code)); } return(null); }
public override ISelector Produce() { var valid = _nested.IsValid; var sel = _nested.ToPool(); if (!valid) { return(null); } var code = PseudoClassNames.Matches.CssFunction(sel.Text); return(SimpleSelector.PseudoClass(el => sel.Match(el), code)); }
/// <summary> /// Invoked once a colon with an identifier has been found in the token enumerator. /// </summary> /// <returns>The created selector.</returns> ISelector GetPseudoSelector(CssToken token) { switch (token.Data) { case pseudoClassRoot: return(SimpleSelector.PseudoClass(el => el.Owner.DocumentElement == el, pseudoClassRoot)); case pseudoClassFirstOfType: return(SimpleSelector.PseudoClass(el => { var parent = el.ParentElement; if (parent == null) { return true; } for (int i = 0; i < parent.ChildNodes.Length; i++) { if (parent.ChildNodes[i].NodeName == el.NodeName) { return parent.ChildNodes[i] == el; } } return false; }, pseudoClassFirstOfType)); case pseudoClassLastOfType: return(SimpleSelector.PseudoClass(el => { var parent = el.ParentElement; if (parent == null) { return true; } for (int i = parent.ChildNodes.Length - 1; i >= 0; i--) { if (parent.ChildNodes[i].NodeName == el.NodeName) { return parent.ChildNodes[i] == el; } } return false; }, pseudoClassLastOfType)); case pseudoClassOnlyChild: return(SimpleSelector.PseudoClass(el => el.IsOnlyChild(), pseudoClassOnlyChild)); case pseudoClassFirstChild: return(FirstChildSelector.Instance); case pseudoClassLastChild: return(LastChildSelector.Instance); case pseudoClassEmpty: return(SimpleSelector.PseudoClass(el => el.ChildNodes.Length == 0, pseudoClassEmpty)); case pseudoClassLink: return(SimpleSelector.PseudoClass(el => el.IsLink(), pseudoClassLink)); case pseudoClassVisited: return(SimpleSelector.PseudoClass(el => el.IsVisited(), pseudoClassVisited)); case pseudoClassActive: return(SimpleSelector.PseudoClass(el => el.IsActive(), pseudoClassActive)); case pseudoClassHover: return(SimpleSelector.PseudoClass(el => el.IsHovered(), pseudoClassHover)); case pseudoClassFocus: return(SimpleSelector.PseudoClass(el => el.IsFocused(), pseudoClassFocus)); case pseudoClassTarget: return(SimpleSelector.PseudoClass(el => el.Owner != null && el.Id == el.Owner.Location.Hash, pseudoClassTarget)); case pseudoClassEnabled: return(SimpleSelector.PseudoClass(el => el.IsEnabled(), pseudoClassEnabled)); case pseudoClassDisabled: return(SimpleSelector.PseudoClass(el => el.IsDisabled(), pseudoClassDisabled)); case pseudoClassDefault: return(SimpleSelector.PseudoClass(el => el.IsDefault(), pseudoClassDefault)); case pseudoClassChecked: return(SimpleSelector.PseudoClass(el => el.IsChecked(), pseudoClassChecked)); case pseudoClassIndeterminate: return(SimpleSelector.PseudoClass(el => el.IsIndeterminate(), pseudoClassIndeterminate)); case pseudoClassUnchecked: return(SimpleSelector.PseudoClass(el => el.IsUnchecked(), pseudoClassUnchecked)); case pseudoClassValid: return(SimpleSelector.PseudoClass(el => el.IsValid(), pseudoClassValid)); case pseudoClassInvalid: return(SimpleSelector.PseudoClass(el => el.IsInvalid(), pseudoClassInvalid)); case pseudoClassRequired: return(SimpleSelector.PseudoClass(el => el.IsRequired(), pseudoClassRequired)); case pseudoClassReadOnly: return(SimpleSelector.PseudoClass(el => el.IsReadOnly(), pseudoClassReadOnly)); case pseudoClassReadWrite: return(SimpleSelector.PseudoClass(el => el.IsEditable(), pseudoClassReadWrite)); case pseudoClassInRange: return(SimpleSelector.PseudoClass(el => el.IsInRange(), pseudoClassInRange)); case pseudoClassOutOfRange: return(SimpleSelector.PseudoClass(el => el.IsOutOfRange(), pseudoClassOutOfRange)); case pseudoClassOptional: return(SimpleSelector.PseudoClass(el => el.IsOptional(), pseudoClassOptional)); // LEGACY STYLE OF DEFINING PSEUDO ELEMENTS - AS PSEUDO CLASS! case pseudoElementBefore: return(SimpleSelector.PseudoClass(MatchBefore, pseudoElementBefore)); case pseudoElementAfter: return(SimpleSelector.PseudoClass(MatchAfter, pseudoElementAfter)); case pseudoElementFirstLine: return(SimpleSelector.PseudoClass(MatchFirstLine, pseudoElementFirstLine)); case pseudoElementFirstLetter: return(SimpleSelector.PseudoClass(MatchFirstLetter, pseudoElementFirstLetter)); } return(null); }
/// <summary> /// Invoked once a colon with an identifier has been found in the token enumerator. /// </summary> /// <param name="tokens">The token source.</param> /// <returns>The created selector.</returns> public SimpleSelector GetPseudoClassIdentifier(IEnumerator <CssToken> tokens) { switch (((CssKeywordToken)tokens.Current).Data) { case PSEUDOCLASS_ROOT: return(SimpleSelector.PseudoClass(el => el.OwnerDocument.DocumentElement == el, PSEUDOCLASS_ROOT)); case PSEUDOCLASS_FIRSTOFTYPE: return(SimpleSelector.PseudoClass(el => { var parent = el.ParentElement; if (parent == null) { return true; } for (int i = 0; i < parent.ChildNodes.Length; i++) { if (parent.ChildNodes[i].NodeName == el.NodeName) { return parent.ChildNodes[i] == el; } } return false; }, PSEUDOCLASS_FIRSTOFTYPE)); case PSEUDOCLASS_LASTOFTYPE: return(SimpleSelector.PseudoClass(el => { var parent = el.ParentElement; if (parent == null) { return true; } for (int i = parent.ChildNodes.Length - 1; i >= 0; i--) { if (parent.ChildNodes[i].NodeName == el.NodeName) { return parent.ChildNodes[i] == el; } } return false; }, PSEUDOCLASS_LASTOFTYPE)); case PSEUDOCLASS_ONLYCHILD: return(SimpleSelector.PseudoClass(el => { var parent = el.ParentElement; if (parent == null) { return false; } var elements = 0; for (int i = 0; i < parent.ChildNodes.Length; i++) { if (parent.ChildNodes[i] is Element && ++elements == 2) { return false; } } return true; }, PSEUDOCLASS_ONLYCHILD)); case PSEUDOCLASS_FIRSTCHILD: return(FirstChildSelector.Instance); case PSEUDOCLASS_LASTCHILD: return(LastChildSelector.Instance); case PSEUDOCLASS_EMPTY: return(SimpleSelector.PseudoClass(el => el.ChildNodes.Length == 0, PSEUDOCLASS_EMPTY)); case PSEUDOCLASS_LINK: return(SimpleSelector.PseudoClass(el => { if (el is HTMLAnchorElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")) && !((HTMLAnchorElement)el).IsVisited; } else if (el is HTMLAreaElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")) && !((HTMLAreaElement)el).IsVisited; } else if (el is HTMLLinkElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")) && !((HTMLLinkElement)el).IsVisited; } return false; }, PSEUDOCLASS_LINK)); case PSEUDOCLASS_VISITED: return(SimpleSelector.PseudoClass(el => { if (el is HTMLAnchorElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")) && ((HTMLAnchorElement)el).IsVisited; } else if (el is HTMLAreaElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")) && ((HTMLAreaElement)el).IsVisited; } else if (el is HTMLLinkElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")) && ((HTMLLinkElement)el).IsVisited; } return false; }, PSEUDOCLASS_VISITED)); case PSEUDOCLASS_ACTIVE: return(SimpleSelector.PseudoClass(el => { if (el is HTMLAnchorElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")) && ((HTMLAnchorElement)el).IsActive; } else if (el is HTMLAreaElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")) && ((HTMLAreaElement)el).IsActive; } else if (el is HTMLLinkElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")) && ((HTMLLinkElement)el).IsActive; } else if (el is HTMLButtonElement) { return !((HTMLButtonElement)el).Disabled && ((HTMLButtonElement)el).IsActive; } else if (el is HTMLInputElement) { var inp = (HTMLInputElement)el; return (inp.Type == HTMLInputElement.InputType.Submit || inp.Type == HTMLInputElement.InputType.Image || inp.Type == HTMLInputElement.InputType.Reset || inp.Type == HTMLInputElement.InputType.Button) && inp.IsActive; } else if (el is HTMLMenuItemElement) { return string.IsNullOrEmpty(el.GetAttribute("disabled")) && ((HTMLMenuItemElement)el).IsActive; } return false; }, PSEUDOCLASS_ACTIVE)); case PSEUDOCLASS_HOVER: return(SimpleSelector.PseudoClass(el => el.IsHovered, PSEUDOCLASS_HOVER)); case PSEUDOCLASS_FOCUS: return(SimpleSelector.PseudoClass(el => el.IsFocused, PSEUDOCLASS_FOCUS)); case PSEUDOCLASS_TARGET: return(SimpleSelector.PseudoClass(el => el.OwnerDocument != null && el.Id == el.OwnerDocument.Location.Hash, PSEUDOCLASS_TARGET)); case PSEUDOCLASS_ENABLED: return(SimpleSelector.PseudoClass(el => { if (el is HTMLAnchorElement || el is HTMLAreaElement || el is HTMLLinkElement) { return !string.IsNullOrEmpty(el.GetAttribute("href")); } else if (el is HTMLButtonElement) { return !((HTMLButtonElement)el).Disabled; } else if (el is HTMLInputElement) { return !((HTMLInputElement)el).Disabled; } else if (el is HTMLSelectElement) { return !((HTMLSelectElement)el).Disabled; } else if (el is HTMLTextAreaElement) { return !((HTMLTextAreaElement)el).Disabled; } else if (el is HTMLOptionElement) { return !((HTMLOptionElement)el).Disabled; } else if (el is HTMLOptGroupElement || el is HTMLMenuItemElement || el is HTMLFieldSetElement) { return string.IsNullOrEmpty(el.GetAttribute("disabled")); } return false; }, PSEUDOCLASS_ENABLED)); case PSEUDOCLASS_DISABLED: return(SimpleSelector.PseudoClass(el => { if (el is HTMLButtonElement) { return ((HTMLButtonElement)el).Disabled; } else if (el is HTMLInputElement) { return ((HTMLInputElement)el).Disabled; } else if (el is HTMLSelectElement) { return ((HTMLSelectElement)el).Disabled; } else if (el is HTMLTextAreaElement) { return ((HTMLTextAreaElement)el).Disabled; } else if (el is HTMLOptionElement) { return ((HTMLOptionElement)el).Disabled; } else if (el is HTMLOptGroupElement || el is HTMLMenuItemElement || el is HTMLFieldSetElement) { return !string.IsNullOrEmpty(el.GetAttribute("disabled")); } return false; }, PSEUDOCLASS_DISABLED)); case PSEUDOCLASS_DEFAULT: return(SimpleSelector.PseudoClass(el => { if (el is HTMLButtonElement) { var bt = (HTMLButtonElement)el; var form = bt.Form; if (form != null) //TODO Check if button is form def. button { return true; } } else if (el is HTMLInputElement) { var input = (HTMLInputElement)el; if (input.Type == HTMLInputElement.InputType.Submit || input.Type == HTMLInputElement.InputType.Image) { var form = input.Form; if (form != null) //TODO Check if input is form def. button { return true; } } else { //TODO input that are checked and can be checked ... } } else if (el is HTMLOptionElement) { return !string.IsNullOrEmpty(el.GetAttribute("selected")); } return false; }, PSEUDOCLASS_DEFAULT)); case PSEUDOCLASS_CHECKED: return(SimpleSelector.PseudoClass(el => { if (el is HTMLInputElement) { var inp = (HTMLInputElement)el; return (inp.Type == HTMLInputElement.InputType.Checkbox || inp.Type == HTMLInputElement.InputType.Radio) && inp.Checked; } else if (el is HTMLMenuItemElement) { var mi = (HTMLMenuItemElement)el; return (mi.Type == HTMLMenuItemElement.ItemType.Checkbox || mi.Type == HTMLMenuItemElement.ItemType.Radio) && mi.Checked; } else if (el is HTMLOptionElement) { return ((HTMLOptionElement)el).Selected; } return false; }, PSEUDOCLASS_CHECKED)); case PSEUDOCLASS_INDETERMINATE: return(SimpleSelector.PseudoClass(el => { if (el is HTMLInputElement) { var inp = (HTMLInputElement)el; return inp.Type == HTMLInputElement.InputType.Checkbox && inp.Indeterminate; } else if (el is HTMLProgressElement) { return string.IsNullOrEmpty(el.GetAttribute("value")); } return false; }, PSEUDOCLASS_INDETERMINATE)); case PSEUDOCLASS_UNCHECKED: return(SimpleSelector.PseudoClass(el => { if (el is HTMLInputElement) { var inp = (HTMLInputElement)el; return (inp.Type == HTMLInputElement.InputType.Checkbox || inp.Type == HTMLInputElement.InputType.Radio) && !inp.Checked; } else if (el is HTMLMenuItemElement) { var mi = (HTMLMenuItemElement)el; return (mi.Type == HTMLMenuItemElement.ItemType.Checkbox || mi.Type == HTMLMenuItemElement.ItemType.Radio) && !mi.Checked; } else if (el is HTMLOptionElement) { return !((HTMLOptionElement)el).Selected; } return false; }, PSEUDOCLASS_UNCHECKED)); case PSEUDOCLASS_VALID: return(SimpleSelector.PseudoClass(el => { if (el is IValidation) { return ((IValidation)el).CheckValidity(); } else if (el is HTMLFormElement) { return ((HTMLFormElement)el).IsValid; } return false; }, PSEUDOCLASS_VALID)); case PSEUDOCLASS_INVALID: return(SimpleSelector.PseudoClass(el => { if (el is IValidation) { return !((IValidation)el).CheckValidity(); } else if (el is HTMLFormElement) { return !((HTMLFormElement)el).IsValid; } else if (el is HTMLFieldSetElement) { return ((HTMLFieldSetElement)el).IsInvalid; } return false; }, PSEUDOCLASS_INVALID)); case PSEUDOCLASS_REQUIRED: return(SimpleSelector.PseudoClass(el => { if (el is HTMLInputElement) { return ((HTMLInputElement)el).Required; } else if (el is HTMLSelectElement) { return ((HTMLSelectElement)el).Required; } else if (el is HTMLTextAreaElement) { return ((HTMLTextAreaElement)el).Required; } return false; }, PSEUDOCLASS_REQUIRED)); case PSEUDOCLASS_READONLY: return(SimpleSelector.PseudoClass(el => { if (el is HTMLInputElement) { return !((HTMLInputElement)el).IsMutable; } else if (el is HTMLTextAreaElement) { return !((HTMLTextAreaElement)el).IsMutable; } return !el.IsContentEditable; }, PSEUDOCLASS_READONLY)); case PSEUDOCLASS_READWRITE: return(SimpleSelector.PseudoClass(el => { if (el is HTMLInputElement) { return ((HTMLInputElement)el).IsMutable; } else if (el is HTMLTextAreaElement) { return ((HTMLTextAreaElement)el).IsMutable; } return el.IsContentEditable; }, PSEUDOCLASS_READWRITE)); case PSEUDOCLASS_INRANGE: return(SimpleSelector.PseudoClass(el => { if (el is IValidation) { var state = ((IValidation)el).Validity; return !state.RangeOverflow && !state.RangeUnderflow; } return false; }, PSEUDOCLASS_INRANGE)); case PSEUDOCLASS_OUTOFRANGE: return(SimpleSelector.PseudoClass(el => { if (el is IValidation) { var state = ((IValidation)el).Validity; return state.RangeOverflow || state.RangeUnderflow; } return false; }, PSEUDOCLASS_OUTOFRANGE)); case PSEUDOCLASS_OPTIONAL: return(SimpleSelector.PseudoClass(el => { if (el is HTMLInputElement) { return !((HTMLInputElement)el).Required; } else if (el is HTMLSelectElement) { return !((HTMLSelectElement)el).Required; } else if (el is HTMLTextAreaElement) { return !((HTMLTextAreaElement)el).Required; } return false; }, PSEUDOCLASS_OPTIONAL)); // LEGACY STYLE OF DEFINING PSEUDO ELEMENTS - AS PSEUDO CLASS! case PSEUDOELEMENT_BEFORE: return(SimpleSelector.PseudoClass(MatchBefore, PSEUDOELEMENT_BEFORE)); case PSEUDOELEMENT_AFTER: return(SimpleSelector.PseudoClass(MatchAfter, PSEUDOELEMENT_AFTER)); case PSEUDOELEMENT_FIRSTLINE: return(SimpleSelector.PseudoClass(MatchFirstLine, PSEUDOELEMENT_FIRSTLINE)); case PSEUDOELEMENT_FIRSTLETTER: return(SimpleSelector.PseudoClass(MatchFirstLetter, PSEUDOELEMENT_FIRSTLETTER)); } return(null); }
/// <summary> /// Invoked once a pseudo class has been found in the token enumerator. /// </summary> /// <param name="token">The token.</param> /// <returns>True if no error occurred, otherwise false.</returns> Boolean OnPseudoClassFunctionEnd(CssToken token) { state = State.Data; if (token.Type == CssTokenType.RoundBracketClose) { switch (attrName) { case pseudoClassFunctionNthChild: { var sel = GetChildSelector <NthFirstChildSelector>(); if (sel == null) { return(false); } Insert(sel); return(true); } case pseudoClassFunctionNthLastChild: { var sel = GetChildSelector <NthLastChildSelector>(); if (sel == null) { return(false); } Insert(sel); return(true); } case pseudoClassFunctionNot: { var sel = nested.Result; var code = String.Concat(pseudoClassFunctionNot, "(", sel.ToCss(), ")"); Insert(SimpleSelector.PseudoClass(el => !sel.Match(el), code)); return(true); } case pseudoClassFunctionDir: { var code = String.Concat(pseudoClassFunctionDir, "(", attrValue, ")"); Insert(SimpleSelector.PseudoClass(el => el is IHtmlElement && ((IHtmlElement)el).Direction.Equals(attrValue, StringComparison.OrdinalIgnoreCase), code)); return(true); } case pseudoClassFunctionLang: { var code = String.Concat(pseudoClassFunctionLang, "(", attrValue, ")"); Insert(SimpleSelector.PseudoClass(el => el is IHtmlElement && ((IHtmlElement)el).Language.StartsWith(attrValue, StringComparison.OrdinalIgnoreCase), code)); return(true); } case pseudoClassFunctionContains: { var code = String.Concat(pseudoClassFunctionContains, "(", attrValue, ")"); Insert(SimpleSelector.PseudoClass(el => el.TextContent.Contains(attrValue), code)); return(true); } default: return(true); } } return(false); }
/// <summary> /// Invoked once a colon with a function has been found in the token enumerator. /// </summary> /// <param name="tokens">The token source.</param> /// <returns>The created selector.</returns> public SimpleSelector GetPseudoClassFunction(IEnumerator <CssToken> tokens) { var name = ((CssKeywordToken)tokens.Current).Data; var args = new List <CssToken>(); while (tokens.MoveNext()) { if (tokens.Current.Type == CssTokenType.RoundBracketClose) { break; } else { args.Add(tokens.Current); } } if (args.Count == 0) { return(null); } switch (name) { case PSEUDOCLASSFUNCTION_NTHCHILD: return(GetArguments <NthChildSelector>(args.GetEnumerator())); case PSEUDOCLASSFUNCTION_NTHLASTCHILD: return(GetArguments <NthLastChildSelector>(args.GetEnumerator())); case PSEUDOCLASSFUNCTION_DIR: if (args.Count == 1 && args[0].Type == CssTokenType.Ident) { var dir = ((CssKeywordToken)args[0]).Data; var code = string.Format("{0}({1})", PSEUDOCLASSFUNCTION_DIR, dir); var dirCode = dir == "ltr" ? DirectionMode.Ltr : DirectionMode.Rtl; return(SimpleSelector.PseudoClass(el => el.Dir == dirCode, code)); } break; case PSEUDOCLASSFUNCTION_LANG: if (args.Count == 1 && args[0].Type == CssTokenType.Ident) { var lang = ((CssKeywordToken)args[0]).Data; var code = string.Format("{0}({1})", PSEUDOCLASSFUNCTION_LANG, lang); return(SimpleSelector.PseudoClass(el => el.Lang.Equals(lang, StringComparison.OrdinalIgnoreCase), code)); } break; case PSEUDOCLASSFUNCTION_CONTAINS: if (args.Count == 1 && args[0].Type == CssTokenType.String) { var str = ((CssStringToken)args[0]).Data; var code = string.Format("{0}({1})", PSEUDOCLASSFUNCTION_CONTAINS, str); return(SimpleSelector.PseudoClass(el => el.TextContent.Contains(str), code)); } else if (args.Count == 1 && args[0].Type == CssTokenType.Ident) { var str = ((CssKeywordToken)args[0]).Data; var code = string.Format("{0}({1})", PSEUDOCLASSFUNCTION_CONTAINS, str); return(SimpleSelector.PseudoClass(el => el.TextContent.Contains(str), code)); } break; case PSEUDOCLASSFUNCTION_NOT: { var sel = GetSimpleSelector(args.GetEnumerator()); if (sel != null) { var code = string.Format("{0}({1})", PSEUDOCLASSFUNCTION_NOT, sel.ToCss()); return(SimpleSelector.PseudoClass(el => !sel.Match(el), code)); } } break; } if (!ignoreErrors) { throw new DOMException(ErrorCode.SyntaxError); } return(null); }