/** * Return an integer value from 0-255 for a component of an RGB color. * * @param color typed value from the CSS parser, which may be an INTEGER or a * PERCENTAGE * @return integer value from 0-255 * @throws IllegalArgumentException if the color is not an INTEGER or * PERCENTAGE value */ private static int getRgbComponentValue(LexicalUnit color) { switch (color.getLexicalUnitType()) { case LexicalUnit.SAC_INTEGER: return Math.min(color.getIntegerValue(), 255); case LexicalUnit.SAC_PERCENTAGE: return (int) Math.min(color.getFloatValue() * 255, 255); default: throw new CSSException(CSSException.SAC_SYNTAX_ERR, "RGB component value must be integer or percentage, was " + color, null); } }
private void log(TreeLogger.Type type, CSSParseException e) { log(type, "Line " + e.getLineNumber() + " column " + e.getColumnNumber() + ": " + e.getMessage()); }
private static String valueOf(Condition condition) { if (condition instanceof AttributeCondition) { AttributeCondition c = (AttributeCondition) condition; switch (c.getConditionType()) { case Condition.SAC_ATTRIBUTE_CONDITION: return "[" + c.getLocalName() + (c.getValue() != null ? "=\"" + c.getValue() + '"' : "") + "]"; case Condition.SAC_ONE_OF_ATTRIBUTE_CONDITION: return "[" + c.getLocalName() + "~=\"" + c.getValue() + "\"]"; case Condition.SAC_BEGIN_HYPHEN_ATTRIBUTE_CONDITION: return "[" + c.getLocalName() + "|=\"" + c.getValue() + "\"]"; case Condition.SAC_ID_CONDITION: return "#" + c.getValue(); case Condition.SAC_CLASS_CONDITION: return "." + c.getValue(); case Condition.SAC_PSEUDO_CLASS_CONDITION: return ":" + c.getValue(); switch (condition.getConditionType()) { case Condition.SAC_AND_CONDITION: return valueOf(c.getFirstCondition()) + valueOf(c.getSecondCondition()); case Condition.SAC_OR_CONDITION: return ":lang(" + c.getLang() + ")"; + condition.getConditionType() + " " + condition.getClass().getName());
String simpleSelector = valueOf(s.getSimpleSelector()); return valueOf(s.getCondition()); } else { return simpleSelector + valueOf(s.getCondition()); switch (s.getSelectorType()) { case Selector.SAC_CHILD_SELECTOR: if (s.getSimpleSelector().getSelectorType() == Selector.SAC_PSEUDO_ELEMENT_SELECTOR) { return valueOf(s.getAncestorSelector()) + ":" + valueOf(s.getSimpleSelector()); } else { return valueOf(s.getAncestorSelector()) + ">" + valueOf(s.getSimpleSelector()); return valueOf(s.getAncestorSelector()) + " " + valueOf(s.getSimpleSelector()); if (s.getLocalName() == null) { return "*"; } else { return escapeIdent(s.getLocalName()); return valueOf(s.getSelector()) + "+" + valueOf(s.getSiblingSelector());
private <T extends CssNode & HasNodes> void parseInnerStylesheet( String tagName, T parent, String blockContents) { pushParent(parent); // parse the inner text InputSource s = new InputSource(); s.setCharacterStream(new StringReader(blockContents)); Parser parser = new Parser(); parser.setDocumentHandler(this); parser.setErrorHandler(errors); try { parser.parseStyleSheet(s); } catch (IOException e) { throw new CSSException(CSSException.SAC_SYNTAX_ERR, "Unable to parse " + tagName, e); } if (currentParent.pop() != parent) { // This is a coding error throw new RuntimeException("Incorrect element popped"); } }
private static Value valueOf(LexicalUnit value) { switch (value.getLexicalUnitType()) { case LexicalUnit.SAC_ATTR: return new IdentValue("attr(" + value.getStringValue() + ")"); case LexicalUnit.SAC_IDENT: return new IdentValue(escapeIdent(value.getStringValue())); case LexicalUnit.SAC_STRING_VALUE: return new StringValue(value.getStringValue()); case LexicalUnit.SAC_RGBCOLOR: return colorValue(value.getParameters()); case LexicalUnit.SAC_INTEGER: return new NumberValue(value.getIntegerValue()); case LexicalUnit.SAC_REAL: return new NumberValue(value.getFloatValue()); case LexicalUnit.SAC_CENTIMETER: case LexicalUnit.SAC_DEGREE: case LexicalUnit.SAC_RADIAN: case LexicalUnit.SAC_SECOND: return new NumberValue(value.getFloatValue(), value.getDimensionUnitText()); case LexicalUnit.SAC_URI: return new IdentValue("url(" + value.getStringValue() + ")"); case LexicalUnit.SAC_OPERATOR_COMMA: return new TokenValue(","); case LexicalUnit.SAC_COUNTERS_FUNCTION: case LexicalUnit.SAC_FUNCTION: { if (value.getFunctionName().equals(VALUE_FUNCTION_NAME)) {
public void startSelector(SelectorList selectors) throws CSSException { CssRule r; if (nextSelectorCreatesRule) { r = new CssRule(); addNode(r); currentRule = r; } else { r = (CssRule) currentRule; nextSelectorCreatesRule = true; } for (int i = 0; i < selectors.getLength(); i++) { r.getSelectors().add(new CssSelector(valueOf(selectors.item(i)))); } }
void parseEval(String atRule) throws CSSException { // @eval key com.google.Type.staticFunction String[] parts = atRule.substring(0, atRule.length() - 1).split("\\s"); if (parts.length != 3) { throw new CSSException(CSSException.SAC_SYNTAX_ERR, "Incorrect number of parts for @eval", null); } CssEval eval = new CssEval(parts[1], parts[2]); addNode(eval); }
private void reportWarningSkipText(Locator l, String text) { if (errorHandler != null && text != null) { errorHandler.warning(new CSSParseException("Skipping: " + text, l)); } }
/** * Convert a LexicalUnit list into a List of Values. */ private static void extractValueOf(List<Value> accumulator, LexicalUnit value) { do { accumulator.add(valueOf(value)); value = value.getNextLexicalUnit(); } while (value != null); }
public void startDocument(InputSource source) throws CSSException { // Unfortunately flute doesn't call parseCharset() method when it reaches a charset // declaration. The only place to get the charset is in this method. Flute use ASCII by // default to read the file except if it detects a valid charset definition. if (source.getEncoding() != null && !"ASCII".equals(source.getEncoding())) { // valid charset at-rule is defined in this file. CssCharset charset = new CssCharset(source.getEncoding()); addNode(charset); } }
void parseSprite(String atRule) throws CSSException { CssSprite sprite = new CssSprite(); currentRule = sprite; addNode(sprite); // Flag to tell startSelector() to use the CssSprite instead of creating // its own CssRule. nextSelectorCreatesRule = false; // parse the inner text InputSource s = new InputSource(); s.setCharacterStream(new StringReader(atRule.substring(7))); Parser parser = new Parser(); parser.setDocumentHandler(this); parser.setErrorHandler(errors); try { parser.parseRule(s); } catch (IOException e) { throw new CSSException(CSSException.SAC_SYNTAX_ERR, "Unable to parse @sprite", e); } }
void parseUrl(String atRule) throws CSSException { // @url key dataResourceFunction String[] parts = atRule.substring(0, atRule.length() - 1).split("\\s"); if (parts.length != 3) { throw new CSSException(CSSException.SAC_SYNTAX_ERR, "Incorrect number of parts for @url", null); } CssUrl url = new CssUrl(parts[1], parts[2]); addNode(url); }
private void reportWarningSkipText(Locator l, String text) { if (errorHandler != null && text != null) { errorHandler.warning(new CSSParseException("Skipping: " + text, l)); } }
LexicalUnit red = colors; int r = getRgbComponentValue(red); LexicalUnit green = red.getNextLexicalUnit().getNextLexicalUnit(); int g = getRgbComponentValue(green); LexicalUnit blue = green.getNextLexicalUnit().getNextLexicalUnit(); int b = getRgbComponentValue(blue);
void parseDef(String atRule) { String value = atRule.substring(4, atRule.length()).trim(); InputSource s = new InputSource(); s.setCharacterStream(new StringReader(value)); Parser parser = new Parser(); parser.setErrorHandler(errors); parser.parseStyleSheet(new InputSource(new StringReader(dummy))); } catch (IOException e) { assert false : "Should never happen"; throw new CSSException(CSSException.SAC_SYNTAX_ERR, "@def rules must specify an identifier and one or more values", null); throw new CSSException(CSSException.SAC_SYNTAX_ERR, "First lexical unit must be an identifier", null);
/** * The elif nodes are processed as though they were {@code @if} nodes. The * newly-generated CssIf node will be attached to the last CssIf in the * if/else chain. */ void parseElif(String atRule) throws CSSException { List<CssNode> nodes = currentParent.peek().getNodes(); CssIf lastIf = findLastIfInChain(nodes); if (lastIf == null) { throw new CSSException(CSSException.SAC_SYNTAX_ERR, "@elif must immediately follow an @if or @elif", null); } assert lastIf.getElseNodes().isEmpty(); // @elif -> lif (because parseIf strips the first three chars) parseIf(atRule.substring(2)); // Fix up the structure by remove the newly-created node from the parent // context and moving it to the end of the @if chain lastIf.getElseNodes().add(nodes.remove(nodes.size() - 1)); }
throw new CSSException(CSSException.SAC_SYNTAX_ERR, "Incorrect format for @if predicate", null); case 1: if (predicateParts[0].length() == 0) { throw new CSSException(CSSException.SAC_SYNTAX_ERR, "Incorrect format for @if predicate", null);
/** * The else nodes are processed as though they were written as {@code @elif * true} rules. */ void parseElse(String atRule) throws CSSException { // The last CssIf in the if/else chain CssIf lastIf = findLastIfInChain(currentParent.peek().getNodes()); if (lastIf == null) { throw new CSSException(CSSException.SAC_SYNTAX_ERR, "@else must immediately follow an @if or @elif", null); } // Create the CssIf to hold the @else rules String fakeElif = "@elif (true) " + atRule.substring(atRule.indexOf("{")); parseElif(fakeElif); CssIf elseIf = findLastIfInChain(currentParent.peek().getNodes()); assert lastIf.getElseNodes().size() == 1 && lastIf.getElseNodes().get(0) == elseIf; assert elseIf.getElseNodes().isEmpty(); // Merge the rules into the last CssIf to break the chain and prevent // @else followed by @else lastIf.getElseNodes().clear(); lastIf.getElseNodes().addAll(elseIf.getNodes()); }