Example #1
0
  /*
   * Parse a selector group (eg. E, F, G). In many/most cases there will be only one entry.
   */
  private List<Selector> parseSelectorGroup(CSSTextScanner scan) throws SAXException {
    if (scan.empty()) return null;

    ArrayList<Selector> selectorGroup = new ArrayList<Selector>(1);
    Selector selector = new Selector();

    while (!scan.empty()) {
      if (scan.nextSimpleSelector(selector)) {
        // If there is a comma, keep looping, otherwise break
        if (!scan.skipCommaWhitespace())
          continue; // if not a comma, go back and check for next part of selector
        selectorGroup.add(selector);
        selector = new Selector();
      } else break;
    }
    if (!selector.isEmpty()) selectorGroup.add(selector);
    return selectorGroup;
  }
Example #2
0
    /*
     * Scans for a CSS 'simple selector'.
     * Returns true if it found one.
     * Returns false if there was an error or the input is empty.
     */
    public boolean nextSimpleSelector(Selector selector) throws SAXException {
      if (empty()) return false;

      int start = position;
      Combinator combinator = null;
      SimpleSelector selectorPart = null;

      if (!selector.isEmpty()) {
        if (consume('>')) {
          combinator = Combinator.CHILD;
          skipWhitespace();
        } else if (consume('+')) {
          combinator = Combinator.FOLLOWS;
          skipWhitespace();
        }
      }

      if (consume('*')) {
        selectorPart = new SimpleSelector(combinator, null);
      } else {
        String tag = nextIdentifier();
        if (tag != null) {
          selectorPart = new SimpleSelector(combinator, tag);
          selector.addedElement();
        }
      }

      while (!empty()) {
        if (consume('.')) {
          // ".foo" is equivalent to *[class="foo"]
          if (selectorPart == null) selectorPart = new SimpleSelector(combinator, null);
          String value = nextIdentifier();
          if (value == null)
            throw new SAXException("Invalid \".class\" selector in <style> element");
          selectorPart.addAttrib(CLASS, AttribOp.EQUALS, value);
          selector.addedAttributeOrPseudo();
          continue;
        }

        if (consume('#')) {
          // "#foo" is equivalent to *[id="foo"]
          if (selectorPart == null) selectorPart = new SimpleSelector(combinator, null);
          String value = nextIdentifier();
          if (value == null) throw new SAXException("Invalid \"#id\" selector in <style> element");
          selectorPart.addAttrib(ID, AttribOp.EQUALS, value);
          selector.addedIdAttribute();
        }

        if (selectorPart == null) break;

        // Now check for attribute selection and pseudo selectors
        if (consume('[')) {
          skipWhitespace();
          String attrName = nextIdentifier();
          String attrValue = null;
          if (attrName == null)
            throw new SAXException("Invalid attribute selector in <style> element");
          skipWhitespace();
          AttribOp op = null;
          if (consume('=')) op = AttribOp.EQUALS;
          else if (consume("~=")) op = AttribOp.INCLUDES;
          else if (consume("|=")) op = AttribOp.DASHMATCH;
          if (op != null) {
            skipWhitespace();
            attrValue = nextAttribValue();
            if (attrValue == null)
              throw new SAXException("Invalid attribute selector in <style> element");
            skipWhitespace();
          }
          if (!consume(']'))
            throw new SAXException("Invalid attribute selector in <style> element");
          selectorPart.addAttrib(attrName, (op == null) ? AttribOp.EXISTS : op, attrValue);
          selector.addedAttributeOrPseudo();
          continue;
        }

        if (consume(':')) {
          // skip pseudo
          int pseudoStart = position;
          if (nextIdentifier() != null) {
            if (consume('(')) {
              skipWhitespace();
              if (nextIdentifier() != null) {
                skipWhitespace();
                if (!consume(')')) {
                  position = pseudoStart - 1;
                  break;
                }
              }
            }
            selectorPart.addPseudo(input.substring(pseudoStart, position));
            selector.addedAttributeOrPseudo();
          }
        }

        break;
      }

      if (selectorPart != null) {
        selector.add(selectorPart);
        return true;
      }

      // Otherwise 'fail'
      position = start;
      return false;
    }