Пример #1
0
 /** Parses the next rule set, which is a selector followed by a declaration block. */
 private void parseRuleSet() throws IOException {
   if (parseSelectors()) {
     callback.startRule();
     parseDeclarationBlock();
     callback.endRule();
   }
 }
Пример #2
0
  // identifier+: identifier* ;|}
  private int parseDeclaration() throws IOException {
    int token;

    if ((token = parseIdentifiers(':', false)) != IDENTIFIER) {
      return token;
    }
    // Make the property name to lowercase
    for (int counter = unitBuffer.length() - 1; counter >= 0; counter--) {
      unitBuffer.setCharAt(counter, Character.toLowerCase(unitBuffer.charAt(counter)));
    }
    callback.handleProperty(unitBuffer.toString());

    token = parseIdentifiers(';', true);
    callback.handleValue(unitBuffer.toString());
    return token;
  }
Пример #3
0
  /** Parses a set of selectors, returning false if the end of the stream is reached. */
  private boolean parseSelectors() throws IOException {
    // Parse the selectors
    int nextToken;

    if (tokenBufferLength > 0) {
      callback.handleSelector(new String(tokenBuffer, 0, tokenBufferLength));
    }

    unitBuffer.setLength(0);
    for (; ; ) {
      while ((nextToken = nextToken((char) 0)) == IDENTIFIER) {
        if (tokenBufferLength > 0) {
          callback.handleSelector(new String(tokenBuffer, 0, tokenBufferLength));
        }
      }
      switch (nextToken) {
        case BRACE_OPEN:
          return true;

        case BRACKET_OPEN:
        case PAREN_OPEN:
          parseTillClosed(nextToken);
          // Not too sure about this, how we handle this isn't very
          // well spec'd.
          unitBuffer.setLength(0);
          break;

        case BRACKET_CLOSE:
        case BRACE_CLOSE:
        case PAREN_CLOSE:
          throw new RuntimeException("Unexpected block close in selector");

        case END:
          // Prematurely hit end.
          return false;
      }
    }
  }
Пример #4
0
  /** Parses an @ rule, stopping at a matching brace pair, or ;. */
  private void parseAtRule() throws IOException {
    // PENDING: make this more effecient.
    boolean done = false;
    boolean isImport =
        (tokenBufferLength == 7
            && tokenBuffer[0] == '@'
            && tokenBuffer[1] == 'i'
            && tokenBuffer[2] == 'm'
            && tokenBuffer[3] == 'p'
            && tokenBuffer[4] == 'o'
            && tokenBuffer[5] == 'r'
            && tokenBuffer[6] == 't');

    unitBuffer.setLength(0);
    while (!done) {
      int nextToken = nextToken(';');

      switch (nextToken) {
        case IDENTIFIER:
          if (tokenBufferLength > 0 && tokenBuffer[tokenBufferLength - 1] == ';') {
            --tokenBufferLength;
            done = true;
          }
          if (tokenBufferLength > 0) {
            if (unitBuffer.length() > 0 && readWS) {
              unitBuffer.append(' ');
            }
            unitBuffer.append(tokenBuffer, 0, tokenBufferLength);
          }
          break;

        case BRACE_OPEN:
          if (unitBuffer.length() > 0 && readWS) {
            unitBuffer.append(' ');
          }
          unitBuffer.append(charMapping[nextToken]);
          parseTillClosed(nextToken);
          done = true;
          // Skip a tailing ';', not really to spec.
          {
            int nextChar = readWS();
            if (nextChar != -1 && nextChar != ';') {
              pushChar(nextChar);
            }
          }
          break;

        case BRACKET_OPEN:
        case PAREN_OPEN:
          unitBuffer.append(charMapping[nextToken]);
          parseTillClosed(nextToken);
          break;

        case BRACKET_CLOSE:
        case BRACE_CLOSE:
        case PAREN_CLOSE:
          throw new RuntimeException("Unexpected close in @ rule");

        case END:
          done = true;
          break;
      }
    }
    if (isImport && !encounteredRuleSet) {
      callback.handleImport(unitBuffer.toString());
    }
  }