Skip to content

Commit

Permalink
#493 Semi working proof of concept on extracting SVG CSS styles.
Browse files Browse the repository at this point in the history
Still needs work on passing through CSS properties tht are not valid in HTML but valid in SVG such as the fill property.
  • Loading branch information
danfickle committed Jul 17, 2020
1 parent 3bd9343 commit f1284f4
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.openhtmltopdf.css.extend.lib.DOMTreeResolver;
import com.openhtmltopdf.css.newmatch.CascadedStyle;
import com.openhtmltopdf.css.newmatch.PageInfo;
import com.openhtmltopdf.css.newmatch.Selector;
import com.openhtmltopdf.css.parser.CSSPrimitiveValue;
import com.openhtmltopdf.css.sheet.PropertyDeclaration;
import com.openhtmltopdf.css.sheet.Stylesheet;
Expand Down Expand Up @@ -196,7 +197,16 @@ public CascadedStyle getCascadedStyle(Element e, boolean restyle) {
if (e == null) return CascadedStyle.emptyCascadedStyle;
return _matcher.getCascadedStyle(e, restyle);
}


/**
* Given an element, returns all selectors and their rulesets
* for its descendants. Useful for getting the styles that should be
* applied to SVG, etc.
*/
public String getCSSForAllDescendants(Element e) {
return _matcher.getCSSForAllDescendants(e);
}

public PageInfo getPageStyle(String pageName, String pseudoPage) {
return _matcher.getPageCascadedStyle(pageName, pseudoPage);
}
Expand Down Expand Up @@ -268,14 +278,7 @@ private List<StylesheetInfo> getStylesheets() {

return infos;
}

@Deprecated
public void removeStyle(Element e) {
if (_matcher != null) {
_matcher.removeStyle(e);
}
}


public List<FontFaceRule> getFontFaceRules() {
return _matcher.getFontFaceRules();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
abstract class Condition {

abstract boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes);
abstract void toCSS(StringBuilder sb);

/**
* the CSS condition [attribute]
Expand Down Expand Up @@ -217,6 +218,17 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {

return compare(val, _value);
}

protected void toCSS(StringBuilder sb, String type) {
sb.append('[');
sb.append(_name);
sb.append(type);
sb.append('=');
sb.append('\"');
sb.append(_value);
sb.append('\"');
sb.append(']');
}
}

private static class AttributeExistsCondition extends AttributeCompareCondition {
Expand All @@ -241,6 +253,13 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
protected boolean compare(String attrValue, String conditionValue) {
throw new UnsupportedOperationException();
}

@Override
void toCSS(StringBuilder sb) {
sb.append('[');
sb.append(_name);
sb.append(']');
}
}

private static class AttributeEqualsCondition extends AttributeCompareCondition {
Expand All @@ -252,6 +271,11 @@ private static class AttributeEqualsCondition extends AttributeCompareCondition
protected boolean compare(String attrValue, String conditionValue) {
return attrValue.equals(conditionValue);
}

@Override
void toCSS(StringBuilder sb) {
toCSS(sb, "");
}
}

private static class AttributePrefixCondition extends AttributeCompareCondition {
Expand All @@ -263,6 +287,11 @@ private static class AttributePrefixCondition extends AttributeCompareCondition
protected boolean compare(String attrValue, String conditionValue) {
return attrValue.startsWith(conditionValue);
}

@Override
void toCSS(StringBuilder sb) {
toCSS(sb, "^");
}
}

private static class AttributeSuffixCondition extends AttributeCompareCondition {
Expand All @@ -274,6 +303,11 @@ private static class AttributeSuffixCondition extends AttributeCompareCondition
protected boolean compare(String attrValue, String conditionValue) {
return attrValue.endsWith(conditionValue);
}

@Override
void toCSS(StringBuilder sb) {
toCSS(sb, "$");
}
}

private static class AttributeSubstringCondition extends AttributeCompareCondition {
Expand All @@ -285,8 +319,13 @@ private static class AttributeSubstringCondition extends AttributeCompareConditi
protected boolean compare(String attrValue, String conditionValue) {
return attrValue.indexOf(conditionValue) > -1;
}

@Override
void toCSS(StringBuilder sb) {
toCSS(sb, "*");
}
}

private static class AttributeMatchesListCondition extends AttributeCompareCondition {
AttributeMatchesListCondition(String namespaceURI, String name, String value) {
super(namespaceURI, name, value);
Expand All @@ -303,6 +342,11 @@ protected boolean compare(String attrValue, String conditionValue) {
}
return matched;
}

@Override
void toCSS(StringBuilder sb) {
toCSS(sb, "~");
}
}

private static class AttributeMatchesFirstPartCondition extends AttributeCompareCondition {
Expand All @@ -318,6 +362,11 @@ protected boolean compare(String attrValue, String conditionValue) {
}
return false;
}

@Override
void toCSS(StringBuilder sb) {
toCSS(sb, "|");
}
}

private static class ClassCondition extends Condition {
Expand All @@ -343,6 +392,12 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
// in an XML DOM, space normalization in attributes is supposed to have happened already.
return (" " + c + " ").indexOf(_paddedClassName) != -1;
}

@Override
public void toCSS(StringBuilder sb) {
sb.append('.');
sb.append(_paddedClassName.substring(1, _paddedClassName.length() - 1));
}
}

private static class IDCondition extends Condition {
Expand All @@ -363,6 +418,12 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
}
return true;
}

@Override
void toCSS(StringBuilder sb) {
sb.append('#');
sb.append(_id);
}
}

private static class LangCondition extends Condition {
Expand Down Expand Up @@ -390,6 +451,13 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
}
return false;
}

@Override
void toCSS(StringBuilder sb) {
sb.append(":lang(");
sb.append(_lang);
sb.append(')');
}
}

private static class FirstChildCondition extends Condition {
Expand All @@ -401,6 +469,11 @@ private static class FirstChildCondition extends Condition {
boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
return treeRes.isFirstChildElement(e);
}

@Override
void toCSS(StringBuilder sb) {
sb.append(":first-child");
}
}

private static class LastChildCondition extends Condition {
Expand All @@ -412,6 +485,11 @@ private static class LastChildCondition extends Condition {
boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
return treeRes.isLastChildElement(e);
}

@Override
void toCSS(StringBuilder sb) {
sb.append(":last-child");
}
}

private static class NthChildCondition extends Condition {
Expand All @@ -420,10 +498,12 @@ private static class NthChildCondition extends Condition {

private final int a;
private final int b;
private final String input;

NthChildCondition(int a, int b) {
NthChildCondition(int a, int b, String input) {
this.a = a;
this.b = b;
this.input = input;
}

@Override
Expand All @@ -442,16 +522,23 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
}
}

@Override
void toCSS(StringBuilder sb) {
sb.append(":nth-child(");
sb.append(input);
sb.append(')');
}

static NthChildCondition fromString(String number) {
number = number.trim().toLowerCase();

if ("even".equals(number)) {
return new NthChildCondition(2, 0);
return new NthChildCondition(2, 0, number);
} else if ("odd".equals(number)) {
return new NthChildCondition(2, 1);
return new NthChildCondition(2, 1, number);
} else {
try {
return new NthChildCondition(0, Integer.parseInt(number));
return new NthChildCondition(0, Integer.parseInt(number), number);
} catch (NumberFormatException e) {
Matcher m = pattern.matcher(number);

Expand All @@ -467,7 +554,7 @@ static NthChildCondition fromString(String number) {
b *= -1;
}

return new NthChildCondition(a, b);
return new NthChildCondition(a, b, number);
}
}
}
Expand All @@ -484,6 +571,11 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
int position = treeRes.getPositionOfElement(e);
return position >= 0 && position % 2 == 0;
}

@Override
void toCSS(StringBuilder sb) {
sb.append(":nth-child(even)");
}
}

private static class OddChildCondition extends Condition {
Expand All @@ -496,6 +588,11 @@ boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
int position = treeRes.getPositionOfElement(e);
return position >= 0 && position % 2 == 1;
}

@Override
void toCSS(StringBuilder sb) {
sb.append(":nth-child(odd)");
}
}

private static class LinkCondition extends Condition {
Expand All @@ -507,6 +604,11 @@ private static class LinkCondition extends Condition {
boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
return attRes.isLink(e);
}

@Override
void toCSS(StringBuilder sb) {
sb.append(":link");
}
}

/**
Expand All @@ -521,6 +623,11 @@ private static class UnsupportedCondition extends Condition {
boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) {
return false;
}

@Override
void toCSS(StringBuilder sb) {
// Nothing we can do...
}
}

private static String[] split(String s, char ch) {
Expand Down
Loading

0 comments on commit f1284f4

Please sign in to comment.