-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Supporting additional CSS properties #117
Comments
Update: Found out that, along with adding a supported property, you also need to register a declaration parser. So my original solution is not suitable. With liberal use of delegation and updating the factories, I've got a solution working with any type of term, which I'm sharing for anyone else looking to add additional CSS properties with CSSbox or jStyleParser: (the css we want to support) .custom-css {
x-custom-color: red;
x-custom-dimension: 4px 8px;
} (before creating a SupportedCSS3Extender.addCSS3Extensions();
DOMAnalyzer da = new DOMAnalyzer(document, url);
// ... (extending SupportedCSS3 with new values) public class SupportedCSS3Extender {
/** have we extended {@link SupportedCSS3} yet? */
private static boolean isApplied = false;
private SupportedCSS3Extender() {
// empty, prevent instantiation
}
public enum CustomDimension implements CSSProperty {
list_values(""),
INHERIT("inherit"), INITIAL("initial"), UNSET("unset");
private String text;
private CustomDimension(String text) {
this.text = text;
}
@Override
public boolean inherited() {
return false;
}
@Override
public boolean equalsInherit() {
return this == INHERIT;
}
@Override
public boolean equalsInitial() {
return this == INITIAL;
}
@Override
public boolean equalsUnset() {
return this == UNSET;
}
@Override
public ValueType getValueType() {
return ValueType.LIST;
}
@Override
public String toString() {
return text;
}
}
/**
* If not already registered, registers additional supported CSS3 properties
* for our CSSBox.
*
* <p>
* Does nothing if already registered.
*/
public static synchronized void addCSS3Extensions() {
if (!isApplied) {
CSSFactory.registerDeclarationTransformer(dtInstance);
CSSFactory.registerSupportedCSS(supportedCssInstance);
isApplied = true;
}
}
private static ExtendedSupportedCSS3 supportedCssInstance = new ExtendedSupportedCSS3();
private static ExtendedDeclarationTransformerImpl dtInstance = new ExtendedDeclarationTransformerImpl();
} (extended SupportedCSS with additional CSS properties) public class ExtendedSupportedCSS3 implements SupportedCSS {
private SupportedCSS3 delegate = SupportedCSS3.getInstance();
private Map<String, CSSProperty> additionalDefaultCssProperties = new HashMap<>();
private Map<String, Term<?>> additionalDefaultCssValues = new HashMap<>();
public ExtendedSupportedCSS3() {
additionalDefaultCssProperties.put("x-custom-color", CSSProperty.Color.color);
additionalDefaultCssProperties.put("x-custom-dimension", CustomDimension.list_values);
setOrdinals();
}
@Override
public int getTotalProperties() {
return delegate.getTotalProperties() + additionalDefaultCssProperties.size();
}
@Override
public Set<String> getDefinedPropertyNames() {
Set<String> result = new HashSet<>();
result.addAll(delegate.getDefinedPropertyNames());
result.addAll(additionalDefaultCssProperties.keySet());
return result;
}
@Override
public boolean isSupportedMedia(String media) {
return delegate.isSupportedMedia(media);
}
@Override
public boolean isSupportedCSSProperty(String property) {
if (additionalDefaultCssProperties.containsKey(property)) {
return true;
}
return delegate.isSupportedCSSProperty(property);
}
@Override
public CSSProperty getDefaultProperty(String propertyName) {
if (additionalDefaultCssProperties.containsKey(propertyName)) {
return additionalDefaultCssProperties.get(propertyName);
}
return delegate.getDefaultProperty(propertyName);
}
@Override
public Term<?> getDefaultValue(String propertyName) {
if (additionalDefaultCssValues.containsKey(propertyName)) {
return additionalDefaultCssValues.get(propertyName);
}
return delegate.getDefaultValue(propertyName);
}
@Override
public String getRandomPropertyName() {
return delegate.getRandomPropertyName(); // ?? what a weird method
}
// for faster performance, I think: loops for keys -> ints
private Map<String, Integer> additionalOrdinals = new HashMap<>();
private Map<Integer, String> additionalOrdinalsReverse = new HashMap<>();
// we assume that our delegate uses ordinals up to 200, so we can use bigger ones
private static final int MINIMUM_ADDITIONAL_ORDINAL_INDEX = 200;
private void setOrdinals() {
int i = MINIMUM_ADDITIONAL_ORDINAL_INDEX;
for (String key : additionalDefaultCssProperties.keySet()) {
additionalOrdinals.put(key, i);
additionalOrdinalsReverse.put(i, key);
i++;
}
}
@Override
public int getOrdinal(String propertyName) {
if (additionalOrdinals.containsKey(propertyName)) {
return additionalOrdinals.get(propertyName).intValue();
}
return delegate.getOrdinal(propertyName);
}
@Override
public String getPropertyName(int o) {
Integer i = Integer.valueOf(o);
if (additionalOrdinalsReverse.containsKey(i)) {
return additionalOrdinalsReverse.get(i);
}
return delegate.getPropertyName(o);
}
} (custom Declaration Transformer) public class ExtendedDeclarationTransformerImpl implements DeclarationTransformer {
private DeclarationTransformer delegate = DeclarationTransformerImpl.getInstance();
@Override
public boolean parseDeclaration(Declaration d, Map<String, CSSProperty> properties,
Map<String, Term<?>> values) {
final String propertyName = d.getProperty();
System.out.println("parse -> " + propertyName);
switch (propertyName) {
case "x-custom-color":
return processColor(d, properties, values);
case "x-custom-dimension":
return processCustomDimensionList(d, properties, values);
default:
return delegate.parseDeclaration(d, properties, values);
}
}
private boolean processColor(Declaration d,
Map<String, CSSProperty> properties, Map<String, Term<?>> values) {
return Decoder.genericOneIdentOrColor(Color.class, Color.color, d, properties,
values);
}
private boolean processCustomDimensionList(Declaration d,
Map<String, CSSProperty> properties, Map<String, Term<?>> values) {
return Decoder.genericTwoIdentsOrLengthsOrPercents(CustomDimension.class,
CustomDimension.list_values, ValueRange.DISALLOW_NEGATIVE, d, properties, values);
}
} And finally, using a CSSBox renderer to get the actual values from CSS: public void renderTextContent(TextBox text) {
VisualContext ctx = text.getVisualContext();
CSSDecoder dec = new CSSDecoder(ctx);
NodeData style = text.getParent().getStyle();
TermColor customColor = style.getValue(TermColor.class, "x-custom-color");
System.out.println("customColor -> " + customColor);
TermList customDimension = style.getValue(TermList.class, "x-custom-dimension");
if (customDimension.size() == 2) {
// two terms
TermLengthOrPercent term1 = (TermLengthOrPercent) customDimension.get(0);
TermLengthOrPercent term2 = (TermLengthOrPercent) customDimension.get(1);
System.out.println(String.format("customDimension -> %s, %s", term1, term2));
float calculatedWidth = dec.getLength(term1, false, 0, 0, drawArea.width);
float calculatedHeight = dec.getLength(term2, false, 0, 0, drawArea.height);
System.out.println(String.format("customDimension calculated to be -> %s, %s", calculatedWidth, calculatedHeight));
} else {
throw new IllegalStateException("Cannot handle x-custom-dimension with " + customDimension.size() + " terms");
}
} |
Hello! Thank you so much for this project, it's incredible.
I'm building a libgdx-based game engine with rendering based on CSSBox, and I'm needing to add additional custom CSS properties, not just for CSS3 things not yet supported (such as
text-shadow
andtext-decoration-thickness
), but also custom things specific to my renderer (likex-tooltip-position
orx-selection-color
).I've got a vaguely-working solution by extending SupportedCSS3's
setSupportedCSS()
, and then accessing the value directly:However, since jStyleParser is LGPL, I'd need to put my changes to SupportedCSS3 into a separate library. (Which is fine! Open source ❤️)
Before I do that, would you be open to having a method to register additional supported CSS properties? I'm thinking something like
which would just look like
(and of course,
addSupportedDefaultValue
,addSupportedOrdinal
, etc)I'mappy to try and attempt a PR, not sure how awkward it'll be to get a jStyleParser dev environment working.
The text was updated successfully, but these errors were encountered: