Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9ca5fd7
redo attribute selector parsing to include wq-name and modifier.
ylafon Sep 27, 2021
9973904
regen
ylafon Sep 27, 2021
f6ed3ac
redo attribute selector parsing to include wq-name and modifier.
ylafon Sep 27, 2021
f7d14b8
regen
ylafon Sep 27, 2021
4b2d2aa
Merge branch 'selectors-4' of github.com:w3c/css-validator into selec…
ylafon Sep 27, 2021
9538721
redo attribute selector parsing to include wq-name and modifier.
ylafon Sep 27, 2021
761629c
regen
ylafon Sep 27, 2021
1ee5cd3
production renaming
ylafon Sep 28, 2021
0dd523e
regen
ylafon Sep 28, 2021
e9bb082
Merge branch 'selectors-4' of github.com:w3c/css-validator into selec…
ylafon Sep 28, 2021
751f1e1
Merge branch 'selectors-4' of github.com:w3c/css-validator into selec…
ylafon Sep 28, 2021
779d09e
Merge branch 'selectors-4' of github.com:w3c/css-validator into selec…
ylafon Sep 28, 2021
0ff3daa
regen
ylafon Sep 29, 2021
fb4c8a3
lang() pseudo function value check (wildcard ranges are not checked, …
ylafon Sep 29, 2021
3041782
combinator must be a string (as column combinator is not a single cha…
ylafon Sep 29, 2021
dbf50db
regen
ylafon Sep 29, 2021
833b61f
moved combinators for clarity
ylafon Sep 29, 2021
bc50295
support for pseudofunction requiring a selector list as an argument
ylafon Sep 29, 2021
6640eec
regen
ylafon Sep 29, 2021
133212f
making :not() more generic, note that the behaviour of selectors-3 ch…
ylafon Sep 29, 2021
951cdce
added applcontext for further checks
ylafon Sep 29, 2021
5d9c43d
regen
ylafon Sep 29, 2021
327615c
support for :has() and relative selectors
ylafon Sep 29, 2021
93a2e9a
regen
ylafon Sep 29, 2021
8649d88
complex selector parsing per https://www.w3.org/TR/2018/WD-selectors-…
ylafon Sep 30, 2021
2d477c2
regen
ylafon Sep 30, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
complex selector parsing per https://www.w3.org/TR/2018/WD-selectors-…
  • Loading branch information
ylafon committed Sep 30, 2021
commit 8649d88ba33e9129740398511b84f04afa7ec5db
8 changes: 4 additions & 4 deletions org/w3c/css/parser/CssSelectors.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public final class CssSelectors extends SelectorsList
//private int hashGeneral;

// The CssStyle to use
private static Class style;
private static Class<?> style;

// see isEmpty and addProperty
private boolean Init;
Expand All @@ -93,7 +93,7 @@ public CssSelectors(ApplContext ac) {
this.ac = ac;
}

private CssSelectors(Class style) {
private CssSelectors(Class<?> style) {
super();
CssSelectors.style = style;
try {
Expand Down Expand Up @@ -130,7 +130,7 @@ public CssSelectors(ApplContext ac, CssSelectors next) {
*
* @param style0 the style
*/
public void setStyle(Class style0) {
public void setStyle(Class<?> style0) {
Util.verbose("Style is : " + style0);
style = style0;
}
Expand Down Expand Up @@ -605,7 +605,7 @@ private boolean canMatch(CssSelectors selector) {
Util.verbose("canMatch for attributes :" + result);

if ((hashElement != selector.hashElement) && hashElement != 0) {
if ((connector == DESCENDANT_COMBINATOR) && (selector.next != null)) {
if ((connector.equals(DESCENDANT_COMBINATOR)) && (selector.next != null)) {
// here we are in this case :
// H1 and HTML BODY H1 EM
// H1 can't match EM but EM have next
Expand Down
259 changes: 146 additions & 113 deletions org/w3c/css/parser/analyzer/CssParser.jj
Original file line number Diff line number Diff line change
Expand Up @@ -1903,7 +1903,7 @@ String combinator() :
String connector = " ";
}
{
( ( <PLUS> { connector = "+" ; }
( ( <PLUS> { connector = "+" ; }
| <GREATER> { connector = ">" ; }
| <TILDE> { connector = "~" ; }
| <TWOPIPES> { connector = "||"; }
Expand Down Expand Up @@ -1966,12 +1966,12 @@ ArrayList<CssSelectors> selector_list() :
ArrayList<CssSelectors> context_set = new ArrayList<CssSelectors>();
}
{
selector=selector() {
selector=complex_selector(null) {
if (selector != null) {
context_set.add(selector);
}
}
( <COMMA> ( <S> )* selector=selector() {
( <COMMA> ( <S> )* selector=complex_selector(null) {
if (selector != null) {
context_set.add(selector);
}
Expand Down Expand Up @@ -2182,101 +2182,12 @@ CssSelectors relative_selector() :
current.addDescendantCombinator();
}
}
// FIXME should be complex_selector
current=simple_selector(current)
current=complex_selector(current)
{
return current;
}

}
/**
* @exception ParseException exception during the parse
*/
CssSelectors selector() :
{ String comb;
CssSelectors current; }
{
try {
current=simple_selector(null)
(
comb=combinator() {
if ((ac.getCssProfile() == CssProfile.MOBILE) ||
getAtRule().toString().equals("@media atsc-tv") ||
(ac.getCssVersion() == CssVersion.CSS1)) {
if (comb.equals("+") || comb.equals(">")) {
throw new InvalidParamException("nocomb", comb, ac);
}
} else if (ac.getCssProfile() == CssProfile.TV) {
if (comb.equals("+")) {
throw new InvalidParamException("nocomb", comb, ac);
}
}
// if version < CSS3, ~ is undefined
if (ac.getCssVersion().compareTo(CssVersion.CSS3) < 0) {
if (comb.equals("~") || comb.equals("||")) {
throw new InvalidParamException("nocomb", comb, ac);
}
}
switch(comb) {
case "+":
current.addNextSiblingCombinator();
break;
case ">":
current.addChildCombinator();
break;
case "~":
current.addSubsequentSiblingCombinator();
break;
case "||":
current.addColumnCombinator();
break;
default:
current.addDescendantCombinator();
}
//current.setConnector(comb);
}
current=simple_selector(current)
)*
{ return current; }
}
catch (InvalidParamException ie) {
// skipStatement();
// removeThisRule();
ac.getFrame()
.addError(new CssError(getSourceFile(), getBeginLine(),
getBeginColumn(), getEndLine(), getEndColumn(), ie));
Token t = getToken(1);
StringBuilder s = new StringBuilder();
s.append(getToken(0).image);
// eat until , { or EOF
while ((t.kind != COMMA) && (t.kind != LBRACE) && (t.kind != EOF)) {
s.append(t.image);
getNextToken();
t = getToken(1);
}
return null;
}
catch (ParseException e) {
// validSelector = false;
Token t = getToken(1);
StringBuilder s = new StringBuilder("[");
s.append(getToken(0).image);
// eat until , { or EOF
while ((t.kind != COMMA) && (t.kind != LBRACE) && (t.kind != EOF)) {
s.append(t.image);
getNextToken();
t = getToken(1);
}
s.append(']');
// if (validSelector) {
addError(e, s.toString());
// } else {
// addError(e,"");
// }
validSelector = true;
return null;
}
}

/**
* I made this rule to parse a selector from a document. Combinator are avoid.
Expand Down Expand Up @@ -2315,6 +2226,119 @@ CssSelectors simple_selector(CssSelectors next) :
}
}

CssSelectors subclass_selector(CssSelectors selector) :
{
}
{
( id_selector(selector)
| class_selector(selector)
| attribute_selector(selector)
| pseudo_class_selector(selector)
)
{
return selector;
}
}

CssSelectors complex_selector(CssSelectors sel) :
{
String comb;
CssSelectors current;
}
{
try {
current=compound_selector(sel)
( ( comb=combinator() {
if ((ac.getCssProfile() == CssProfile.MOBILE) ||
getAtRule().toString().equals("@media atsc-tv") ||
(ac.getCssVersion() == CssVersion.CSS1)) {
if (comb.equals("+") || comb.equals(">")) {
throw new InvalidParamException("nocomb", comb, ac);
}
} else if (ac.getCssProfile() == CssProfile.TV) {
if (comb.equals("+")) {
throw new InvalidParamException("nocomb", comb, ac);
}
}
// if version < CSS3, ~ is undefined
if (ac.getCssVersion().compareTo(CssVersion.CSS3) < 0) {
if (comb.equals("~") || comb.equals("||")) {
throw new InvalidParamException("nocomb", comb, ac);
}
}
switch(comb) {
case "+":
current.addNextSiblingCombinator();
break;
case ">":
current.addChildCombinator();
break;
case "~":
current.addSubsequentSiblingCombinator();
break;
case "||":
current.addColumnCombinator();
break;
default:
current.addDescendantCombinator();
}
} )?
current=compound_selector(current)
)*
{
return current;
}
} catch (InvalidParamException ie) {
// skipStatement();
// removeThisRule();
ac.getFrame().addError(new CssError(getSourceFile(), getBeginLine(),
getBeginColumn(), getEndLine(), getEndColumn(), ie));
Token t = getToken(1);
StringBuilder s = new StringBuilder();
s.append(getToken(0).image);
// eat until , { or EOF
while ((t.kind != COMMA) && (t.kind != LBRACE) && (t.kind != EOF)) {
s.append(t.image);
getNextToken();
t = getToken(1);
}
return null;
} catch (ParseException e) {
// validSelector = false;
Token t = getToken(1);
StringBuilder s = new StringBuilder("[");
s.append(getToken(0).image);
// eat until , { or EOF
while ((t.kind != COMMA) && (t.kind != LBRACE) && (t.kind != EOF)) {
s.append(t.image);
getNextToken();
t = getToken(1);
}
s.append(']');
// if (validSelector) {
addError(e, s.toString());
// } else {
// addError(e,"");
// }
validSelector = true;
return null;
}

}

CssSelectors compound_selector(CssSelectors next) :
{
CssSelectors selector = new CssSelectors(ac, next);
selector.setAtRule(getAtRule());
}
{
( LOOKAHEAD(3) ( ( ( type_selector(selector) )? ( LOOKAHEAD(2) subclass_selector(selector) )+ ) ( LOOKAHEAD(2) pseudo_element_selector(selector) ( LOOKAHEAD(2) pseudo_class_selector(selector) )* )* )
| ( type_selector(selector) ( LOOKAHEAD(2) pseudo_element_selector(selector) ( LOOKAHEAD(2) pseudo_class_selector(selector) )* )* )
| ( ( LOOKAHEAD(2) pseudo_element_selector(selector) ( LOOKAHEAD(2) pseudo_class_selector(selector) )* )+ ) ) {
return selector;
}
}

/**
* @exception ParseException exception during the parse
*/
Expand Down Expand Up @@ -2596,36 +2620,45 @@ void attribute_selector(CssSelectors s) :
}
}

void pseudo_element_selector(CssSelectors s) :
{
Token n;
}
{
<PSEUDOELEMENT_SYM> ( n=ident() ) {
try {
// should be >CSS3
if (ac.getCssVersion().compareTo(CssVersion.CSS3) >= 0) {
s.addPseudoElement(convertIdent(n.image).toLowerCase());
} else {
throw new InvalidParamException("pseudo-element",
"::" + convertIdent(n.image).toLowerCase(),
ac.getCssVersionString() ,ac);
}
} catch(InvalidParamException e) {
validSelector = false;
throw new ParseException(e.getMessage());
}
}
}

void pseudo(CssSelectors s) :
{}
{
pseudo_element_selector(s) | pseudo_class_selector(s)

}
/**
* @exception ParseException exception during the parse
*/
void pseudo(CssSelectors s) :
void pseudo_class_selector(CssSelectors s) :
{Token n;
Token language = null;
CssExpression param = null;
ArrayList<CssSelectors> selector_list = null;
String error_str = null;
}
{
<PSEUDOELEMENT_SYM> ( ( n=ident()
{
try {
// should be >CSS3
if (ac.getCssVersion().compareTo(CssVersion.CSS3) >= 0) {
s.addPseudoElement(convertIdent(n.image).toLowerCase());
} else {
throw new InvalidParamException("pseudo-element",
"::" + convertIdent(n.image).toLowerCase() ,
ac.getCssVersionString() ,ac);
}
} catch(InvalidParamException e) {
// removeThisRule();
// ac.getFrame().addError(new CssError(e));
validSelector = false;
throw new ParseException(e.getMessage());
}
} ) )
|
<COLON> ( ( n=ident()
{
try {
Expand Down
14 changes: 4 additions & 10 deletions org/w3c/css/selectors/SelectorsList.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,10 @@ public int size() {
* @throws InvalidParamException when trying to add a selector after a pseudo-element
*/
public void addSelector(Selector selector) throws InvalidParamException {
if (selectors.size() > 0) {
Selector last = selectors.get(selectors.size() - 1);
if (last instanceof PseudoElementSelector
&& !(selector instanceof PseudoClassSelector
&& ((PseudoClassSelector) selector)
.isUserAction())) {
throw new InvalidParamException("pseudo-element-not-last",
selector, last, ac);
}
}
/* FIXME TODO
the grammar is checking the basic structure but specific rules
should appear here
*/
selectors.add(selector);
stringrep = null;
}
Expand Down