3737abstract class Condition {
3838
3939 abstract boolean matches (Object e , AttributeResolver attRes , TreeResolver treeRes );
40+ abstract void toCSS (StringBuilder sb );
4041
4142 /**
4243 * the CSS condition [attribute]
@@ -217,6 +218,17 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
217218
218219 return compare (val , _value );
219220 }
221+
222+ protected void toCSS (StringBuilder sb , String type ) {
223+ sb .append ('[' );
224+ sb .append (_name );
225+ sb .append (type );
226+ sb .append ('=' );
227+ sb .append ('\"' );
228+ sb .append (_value );
229+ sb .append ('\"' );
230+ sb .append (']' );
231+ }
220232 }
221233
222234 private static class AttributeExistsCondition extends AttributeCompareCondition {
@@ -241,6 +253,13 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
241253 protected boolean compare (String attrValue , String conditionValue ) {
242254 throw new UnsupportedOperationException ();
243255 }
256+
257+ @ Override
258+ void toCSS (StringBuilder sb ) {
259+ sb .append ('[' );
260+ sb .append (_name );
261+ sb .append (']' );
262+ }
244263 }
245264
246265 private static class AttributeEqualsCondition extends AttributeCompareCondition {
@@ -252,6 +271,11 @@ private static class AttributeEqualsCondition extends AttributeCompareCondition
252271 protected boolean compare (String attrValue , String conditionValue ) {
253272 return attrValue .equals (conditionValue );
254273 }
274+
275+ @ Override
276+ void toCSS (StringBuilder sb ) {
277+ toCSS (sb , "" );
278+ }
255279 }
256280
257281 private static class AttributePrefixCondition extends AttributeCompareCondition {
@@ -263,6 +287,11 @@ private static class AttributePrefixCondition extends AttributeCompareCondition
263287 protected boolean compare (String attrValue , String conditionValue ) {
264288 return attrValue .startsWith (conditionValue );
265289 }
290+
291+ @ Override
292+ void toCSS (StringBuilder sb ) {
293+ toCSS (sb , "^" );
294+ }
266295 }
267296
268297 private static class AttributeSuffixCondition extends AttributeCompareCondition {
@@ -274,6 +303,11 @@ private static class AttributeSuffixCondition extends AttributeCompareCondition
274303 protected boolean compare (String attrValue , String conditionValue ) {
275304 return attrValue .endsWith (conditionValue );
276305 }
306+
307+ @ Override
308+ void toCSS (StringBuilder sb ) {
309+ toCSS (sb , "$" );
310+ }
277311 }
278312
279313 private static class AttributeSubstringCondition extends AttributeCompareCondition {
@@ -285,8 +319,13 @@ private static class AttributeSubstringCondition extends AttributeCompareConditi
285319 protected boolean compare (String attrValue , String conditionValue ) {
286320 return attrValue .indexOf (conditionValue ) > -1 ;
287321 }
322+
323+ @ Override
324+ void toCSS (StringBuilder sb ) {
325+ toCSS (sb , "*" );
326+ }
288327 }
289-
328+
290329 private static class AttributeMatchesListCondition extends AttributeCompareCondition {
291330 AttributeMatchesListCondition (String namespaceURI , String name , String value ) {
292331 super (namespaceURI , name , value );
@@ -303,6 +342,11 @@ protected boolean compare(String attrValue, String conditionValue) {
303342 }
304343 return matched ;
305344 }
345+
346+ @ Override
347+ void toCSS (StringBuilder sb ) {
348+ toCSS (sb , "~" );
349+ }
306350 }
307351
308352 private static class AttributeMatchesFirstPartCondition extends AttributeCompareCondition {
@@ -318,6 +362,11 @@ protected boolean compare(String attrValue, String conditionValue) {
318362 }
319363 return false ;
320364 }
365+
366+ @ Override
367+ void toCSS (StringBuilder sb ) {
368+ toCSS (sb , "|" );
369+ }
321370 }
322371
323372 private static class ClassCondition extends Condition {
@@ -343,6 +392,12 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
343392 // in an XML DOM, space normalization in attributes is supposed to have happened already.
344393 return (" " + c + " " ).indexOf (_paddedClassName ) != -1 ;
345394 }
395+
396+ @ Override
397+ public void toCSS (StringBuilder sb ) {
398+ sb .append ('.' );
399+ sb .append (_paddedClassName .substring (1 , _paddedClassName .length () - 1 ));
400+ }
346401 }
347402
348403 private static class IDCondition extends Condition {
@@ -363,6 +418,12 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
363418 }
364419 return true ;
365420 }
421+
422+ @ Override
423+ void toCSS (StringBuilder sb ) {
424+ sb .append ('#' );
425+ sb .append (_id );
426+ }
366427 }
367428
368429 private static class LangCondition extends Condition {
@@ -390,6 +451,13 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
390451 }
391452 return false ;
392453 }
454+
455+ @ Override
456+ void toCSS (StringBuilder sb ) {
457+ sb .append (":lang(" );
458+ sb .append (_lang );
459+ sb .append (')' );
460+ }
393461 }
394462
395463 private static class FirstChildCondition extends Condition {
@@ -401,6 +469,11 @@ private static class FirstChildCondition extends Condition {
401469 boolean matches (Object e , AttributeResolver attRes , TreeResolver treeRes ) {
402470 return treeRes .isFirstChildElement (e );
403471 }
472+
473+ @ Override
474+ void toCSS (StringBuilder sb ) {
475+ sb .append (":first-child" );
476+ }
404477 }
405478
406479 private static class LastChildCondition extends Condition {
@@ -412,6 +485,11 @@ private static class LastChildCondition extends Condition {
412485 boolean matches (Object e , AttributeResolver attRes , TreeResolver treeRes ) {
413486 return treeRes .isLastChildElement (e );
414487 }
488+
489+ @ Override
490+ void toCSS (StringBuilder sb ) {
491+ sb .append (":last-child" );
492+ }
415493 }
416494
417495 private static class NthChildCondition extends Condition {
@@ -420,10 +498,12 @@ private static class NthChildCondition extends Condition {
420498
421499 private final int a ;
422500 private final int b ;
501+ private final String input ;
423502
424- NthChildCondition (int a , int b ) {
503+ NthChildCondition (int a , int b , String input ) {
425504 this .a = a ;
426505 this .b = b ;
506+ this .input = input ;
427507 }
428508
429509 @ Override
@@ -442,16 +522,23 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
442522 }
443523 }
444524
525+ @ Override
526+ void toCSS (StringBuilder sb ) {
527+ sb .append (":nth-child(" );
528+ sb .append (input );
529+ sb .append (')' );
530+ }
531+
445532 static NthChildCondition fromString (String number ) {
446533 number = number .trim ().toLowerCase ();
447534
448535 if ("even" .equals (number )) {
449- return new NthChildCondition (2 , 0 );
536+ return new NthChildCondition (2 , 0 , number );
450537 } else if ("odd" .equals (number )) {
451- return new NthChildCondition (2 , 1 );
538+ return new NthChildCondition (2 , 1 , number );
452539 } else {
453540 try {
454- return new NthChildCondition (0 , Integer .parseInt (number ));
541+ return new NthChildCondition (0 , Integer .parseInt (number ), number );
455542 } catch (NumberFormatException e ) {
456543 Matcher m = pattern .matcher (number );
457544
@@ -467,7 +554,7 @@ static NthChildCondition fromString(String number) {
467554 b *= -1 ;
468555 }
469556
470- return new NthChildCondition (a , b );
557+ return new NthChildCondition (a , b , number );
471558 }
472559 }
473560 }
@@ -484,6 +571,11 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
484571 int position = treeRes .getPositionOfElement (e );
485572 return position >= 0 && position % 2 == 0 ;
486573 }
574+
575+ @ Override
576+ void toCSS (StringBuilder sb ) {
577+ sb .append (":nth-child(even)" );
578+ }
487579 }
488580
489581 private static class OddChildCondition extends Condition {
@@ -496,6 +588,11 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
496588 int position = treeRes .getPositionOfElement (e );
497589 return position >= 0 && position % 2 == 1 ;
498590 }
591+
592+ @ Override
593+ void toCSS (StringBuilder sb ) {
594+ sb .append (":nth-child(odd)" );
595+ }
499596 }
500597
501598 private static class LinkCondition extends Condition {
@@ -507,6 +604,11 @@ private static class LinkCondition extends Condition {
507604 boolean matches (Object e , AttributeResolver attRes , TreeResolver treeRes ) {
508605 return attRes .isLink (e );
509606 }
607+
608+ @ Override
609+ void toCSS (StringBuilder sb ) {
610+ sb .append (":link" );
611+ }
510612 }
511613
512614 /**
@@ -521,6 +623,11 @@ private static class UnsupportedCondition extends Condition {
521623 boolean matches (Object e , AttributeResolver attRes , TreeResolver treeRes ) {
522624 return false ;
523625 }
626+
627+ @ Override
628+ void toCSS (StringBuilder sb ) {
629+ // Nothing we can do...
630+ }
524631 }
525632
526633 private static String [] split (String s , char ch ) {
0 commit comments