Skip to content

Commit bc50295

Browse files
committed
support for pseudofunction requiring a selector list as an argument
1 parent 833b61f commit bc50295

File tree

6 files changed

+165
-23
lines changed

6 files changed

+165
-23
lines changed

org/w3c/css/parser/CssSelectors.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,23 @@ public void setPseudoFun(String pseudo, String param)
255255
}
256256
}
257257

258+
public void setPseudoFun(String pseudo, ArrayList<CssSelectors> selector_list)
259+
throws InvalidParamException {
260+
261+
CssVersion version = ac.getCssVersion();
262+
String[] ps = PseudoFactory.getPseudoFunction(version);
263+
if (ps != null) {
264+
for (String s : ps) {
265+
if (pseudo.equals(s)) {
266+
addPseudoFunction(PseudoFactory.newPseudoFunction(pseudo, selector_list, ac));
267+
return;
268+
}
269+
}
270+
throw new InvalidParamException("pseudo", ":" + pseudo, ac);
271+
}
272+
}
273+
274+
258275
public void addType(TypeSelector type) throws InvalidParamException {
259276
super.addType(type);
260277
element = type.getName();
@@ -621,4 +638,21 @@ public void findConflicts(ApplContext ac, Warnings warnings,
621638
CssStyle style = getStyle();
622639
style.findConflicts(ac, warnings, this, allSelectors);
623640
}
641+
642+
public static String toArrayString(ArrayList<CssSelectors> selectors) {
643+
if (selectors == null) {
644+
return "";
645+
}
646+
StringBuilder sb = new StringBuilder();
647+
boolean first = true;
648+
for (CssSelectors s : selectors) {
649+
if (!first) {
650+
sb.append(", ");
651+
} else {
652+
first = false;
653+
}
654+
sb.append(s);
655+
}
656+
return sb.toString();
657+
}
624658
}

org/w3c/css/parser/analyzer/CssParser.jj

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -759,11 +759,15 @@ TOKEN [IGNORE_CASE] :
759759
< CLASS : "." <IDENT> >
760760
}
761761

762-
/* FIXED, added a spacial case for lang pseudoclass */
762+
/* FIXED, added a special case for lang pseudoclass */
763763
<DEFAULT>
764764
TOKEN [IGNORE_CASE] :
765765
{
766766
< FUNCTIONLANG : "lang(" >
767+
| <FUNCTIONDIR : "dir(" >
768+
| <FUNCTIONIS : "is(" >
769+
| <FUNCTIONWHERE : "where(" >
770+
| <FUNCTIONHAS : "has(" >
767771
| <FUNCTIONNOT : ":not(" >
768772
| <FUNCTIONCALC : "calc(" | "-moz-calc(" | "-webkit-calc(" >
769773
| <FUNCTIONMIN : "min(" >
@@ -1956,33 +1960,41 @@ String property() :
19561960
( <S> )*
19571961
}
19581962

1963+
ArrayList<CssSelectors> selector_list() :
1964+
{
1965+
CssSelectors selector;
1966+
ArrayList<CssSelectors> context_set = new ArrayList<CssSelectors>();
1967+
}
1968+
{
1969+
selector=selector() {
1970+
if (selector != null) {
1971+
context_set.add(selector);
1972+
}
1973+
}
1974+
( <COMMA> ( <S> )* selector=selector() {
1975+
if (selector != null) {
1976+
context_set.add(selector);
1977+
}
1978+
} )*
1979+
{
1980+
return context_set;
1981+
}
1982+
}
1983+
19591984
/**
19601985
* @exception ParseException exception during the parse
19611986
*/
19621987
void ruleSet() :
1963-
{ CssSelectors contextual;
1964-
ArrayList<CssSelectors> context_set = new ArrayList<CssSelectors>();
1988+
{
1989+
ArrayList<CssSelectors> context_set = null;
19651990
ArrayList<CssProperty> value_set = null;
19661991
currentContext = context_set;
19671992
}
19681993
{
19691994
try {
1970-
contextual=selector_list()
1971-
{
1972-
if (contextual != null) {
1973-
context_set.add(contextual);
1974-
}
1975-
}
1976-
1977-
( <COMMA> ( <S> )*
1978-
contextual=selector_list()
1979-
{
1980-
if (contextual != null) {
1981-
context_set.add(contextual);
1982-
}
1983-
}
1984-
)*
1985-
<LBRACE> {
1995+
context_set = selector_list()
1996+
1997+
<LBRACE> {
19861998
validSelector = (context_set.size() > 0);
19871999
}
19882000
( <S> )*
@@ -2127,7 +2139,7 @@ ArrayList<CssProperty> attributeDeclarations() :
21272139
/**
21282140
* @exception ParseException exception during the parse
21292141
*/
2130-
CssSelectors selector_list() :
2142+
CssSelectors selector() :
21312143
{ String comb;
21322144
CssSelectors current; }
21332145
{
@@ -2561,6 +2573,7 @@ void pseudo(CssSelectors s) :
25612573
{Token n;
25622574
Token language = null;
25632575
CssExpression param = null;
2576+
ArrayList<CssSelectors> selector_list = null;
25642577
}
25652578
{
25662579
<PSEUDOELEMENT_SYM> ( ( n=ident()
@@ -2594,7 +2607,7 @@ CssExpression param = null;
25942607
}
25952608
} )
25962609
// FXIXME rewrite to make :lang( use a special case
2597-
| ( ( n=<FUNCTIONLANG> ( <S> )* (language=<NUMBER> | language=ident() | language=<STRING> ) ( <S> )* ) {
2610+
| ( ( n=<FUNCTIONLANG> ( <S> )* ( language=ident() | language=<STRING> ) ( <S> )* ) {
25982611
try {
25992612
s.setPseudoFun(convertStringIndex(n.image, 0,
26002613
n.image.length() -1, false).toLowerCase(),
@@ -2606,6 +2619,15 @@ CssExpression param = null;
26062619
getBeginColumn(), getEndLine(), getEndColumn(), e));
26072620
}
26082621
}
2622+
| ( ( n=<FUNCTIONIS> | n=<FUNCTIONWHERE> ) ( <S> )* selector_list=selector_list() ) {
2623+
try {
2624+
s.setPseudoFun(convertStringIndex(n.image, 0, n.image.length() -1, false).toLowerCase(), selector_list);
2625+
} catch(InvalidParamException e) {
2626+
removeThisRule();
2627+
ac.getFrame().addError(new CssError(getSourceFile(), getBeginLine(),
2628+
getBeginColumn(), getEndLine(), getEndColumn(), e));
2629+
}
2630+
}
26092631
| ( n=<FUNCTION> ( <S> )* param=expression() ) {
26102632
try {
26112633
s.setPseudoFun(convertStringIndex(n.image, 0,
@@ -3654,6 +3676,10 @@ String skip_to_matching_paren() {
36543676
case LPAREN:
36553677
case FUNCTION:
36563678
case FUNCTIONLANG:
3679+
case FUNCTIONDIR:
3680+
case FUNCTIONIS:
3681+
case FUNCTIONWHERE:
3682+
case FUNCTIONHAS:
36573683
case FUNCTIONNOT:
36583684
case FUNCTIONCALC:
36593685
case FUNCTIONMIN:

org/w3c/css/selectors/PseudoFactory.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@
44
// Please first read the full copyright statement in file COPYRIGHT.html
55
package org.w3c.css.selectors;
66

7+
import org.w3c.css.parser.CssSelectors;
8+
import org.w3c.css.selectors.pseudofunctions.PseudoFunctionIs;
79
import org.w3c.css.selectors.pseudofunctions.PseudoFunctionLang;
810
import org.w3c.css.selectors.pseudofunctions.PseudoFunctionNot;
911
import org.w3c.css.selectors.pseudofunctions.PseudoFunctionNthChild;
1012
import org.w3c.css.selectors.pseudofunctions.PseudoFunctionNthLastChild;
1113
import org.w3c.css.selectors.pseudofunctions.PseudoFunctionNthLastOfType;
1214
import org.w3c.css.selectors.pseudofunctions.PseudoFunctionNthOfType;
15+
import org.w3c.css.selectors.pseudofunctions.PseudoFunctionWhere;
1316
import org.w3c.css.util.ApplContext;
1417
import org.w3c.css.util.CssProfile;
1518
import org.w3c.css.util.CssVersion;
1619
import org.w3c.css.util.InvalidParamException;
1720

21+
import java.util.ArrayList;
22+
1823
/**
1924
* PseudoFactory<br />
2025
* Created: Sep 2, 2005 2:41:09 PM<br />
@@ -223,4 +228,25 @@ public static PseudoFunctionSelector newPseudoFunction(String name,
223228
throw new InvalidParamException("pseudo",
224229
":" + name, ac);
225230
}
231+
232+
public static PseudoFunctionSelector newPseudoFunction(String name,
233+
ArrayList<CssSelectors> value,
234+
ApplContext ac)
235+
throws InvalidParamException {
236+
if (name == null) {
237+
throw new InvalidParamException("pseudo",
238+
"null pseudofunction", ac);
239+
}
240+
if (name.equals("not")) {
241+
return new PseudoFunctionNot(name, value);
242+
}
243+
if (name.equals("is")) {
244+
return new PseudoFunctionIs(name, value);
245+
}
246+
if (name.equals("where")) {
247+
return new PseudoFunctionWhere(name, value);
248+
}
249+
throw new InvalidParamException("pseudo",
250+
":" + name, ac);
251+
}
226252
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// Author: Yves Lafon <ylafon@w3.org>
3+
//
4+
// (c) COPYRIGHT MIT, ERCIM, Keio, Beihang, 2021.
5+
// Please first read the full copyright statement in file COPYRIGHT.html
6+
package org.w3c.css.selectors.pseudofunctions;
7+
8+
import org.w3c.css.parser.CssSelectors;
9+
import org.w3c.css.selectors.PseudoFunctionSelector;
10+
11+
import java.util.ArrayList;
12+
13+
/**
14+
* PseudoFunctionNot
15+
*/
16+
public class PseudoFunctionIs extends PseudoFunctionSelector {
17+
18+
public PseudoFunctionIs(String name, String value) {
19+
setName(name);
20+
setParam(value);
21+
}
22+
23+
public PseudoFunctionIs(String name, ArrayList<CssSelectors> selector_list) {
24+
this(name, CssSelectors.toArrayString(selector_list));
25+
}
26+
27+
}

org/w3c/css/selectors/pseudofunctions/PseudoFunctionNot.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.w3c.css.parser.CssSelectors;
88
import org.w3c.css.selectors.PseudoFunctionSelector;
99

10+
import java.util.ArrayList;
11+
1012
/**
1113
* PseudoFunctionNot<br />
1214
* Created: Sep 2, 2005 4:25:20 PM<br />
@@ -18,8 +20,8 @@ public PseudoFunctionNot(String name, String value) {
1820
setParam(value);
1921
}
2022

21-
public PseudoFunctionNot(String name, CssSelectors selector_list) {
22-
this(name, selector_list.toString());
23+
public PseudoFunctionNot(String name, ArrayList<CssSelectors> selector_list) {
24+
this(name, CssSelectors.toArrayString(selector_list));
2325
}
2426

2527
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// Author: Yves Lafon <ylafon@w3.org>
3+
//
4+
// (c) COPYRIGHT MIT, ERCIM, Keio, Beihang, 2021.
5+
// Please first read the full copyright statement in file COPYRIGHT.html
6+
package org.w3c.css.selectors.pseudofunctions;
7+
8+
import org.w3c.css.parser.CssSelectors;
9+
import org.w3c.css.selectors.PseudoFunctionSelector;
10+
11+
import java.util.ArrayList;
12+
13+
/**
14+
* PseudoFunctionWhere
15+
*/
16+
public class PseudoFunctionWhere extends PseudoFunctionSelector {
17+
18+
public PseudoFunctionWhere(String name, String value) {
19+
setName(name);
20+
setParam(value);
21+
}
22+
23+
public PseudoFunctionWhere(String name, ArrayList<CssSelectors> selector_list) {
24+
this(name, CssSelectors.toArrayString(selector_list));
25+
}
26+
27+
}

0 commit comments

Comments
 (0)