parse static method
Implementation
static List<CSSRule> parse(String sheetText) {
final List<CSSRule> rules = <CSSRule>[];
StringBuffer buffer = StringBuffer();
int state = _BEFORE_SELECTOR;
for (int pos = 0, length = sheetText.length; pos < length; pos++) {
int c = sheetText.codeUnitAt(pos);
switch(c) {
case DOT_CODE:
// Current only support single class selector: `.red`.
int code = sheetText.codeUnitAt(pos + 1);
// `.` must followed by `-`, `_`, `a-z`, `A-Z`.
if (state == _BEFORE_SELECTOR && (code == 45 || code == 95 || (code < 123 && code > 96) || (code < 91 && code > 64))) {
state = _SELECTOR;
buffer.writeCharCode(c);
} else if (state != _BEFORE_SELECTOR) {
buffer.writeCharCode(c);
}
break;
case SPACE_CODE:
case TAB_CODE:
case CR_CODE:
case FEED_CODE:
case NEWLINE_CODE:
if (state != _BEFORE_SELECTOR && (state == _SELECTOR || state == _VALUE) && pos > 0) {
// Squash 2 or more white-spaces in the row into 1 space.
switch (sheetText.codeUnitAt(pos - 1)) {
case SPACE_CODE:
case TAB_CODE:
case CR_CODE:
case FEED_CODE:
case NEWLINE_CODE:
break;
default:
buffer.writeCharCode(SPACE_CODE);
break;
}
}
break;
case SEMICOLON_CODE:
if (state != _BEFORE_SELECTOR && state == _VALUE || state == _NAME) {
if (state == _NAME) {
state = _BEFORE_NAME;
}
buffer.writeCharCode(c);
}
break;
case OPEN_CURLY_CODE:
if (state == _SELECTOR) {
String selector = buffer.toString();
// Only support single class selector now.
state = _classSelectorRegExp.hasMatch(selector) ? _BEFORE_NAME : _BEFORE_SELECTOR;
if (state == _BEFORE_SELECTOR) {
buffer.clear();
}
}
if (state != _BEFORE_SELECTOR) {
buffer.writeCharCode(c);
}
break;
case COLON_CODE:
if (state == _NAME) {
state = _VALUE;
}
if (state != _BEFORE_SELECTOR) {
buffer.writeCharCode(c);
}
break;
case CLOSE_CURLY_CODE:
if (state == _BEFORE_SELECTOR) break;
if (state == _VALUE || state == _BEFORE_NAME) {
buffer.writeCharCode(c);
String ruleText = buffer.toString();
CSSStyleRule? styleRule = CSSStyleRuleParser.parse(ruleText);
if (styleRule != null) {
rules.add(styleRule);
}
} else if (state == _NAME){
// `.foo { .x {}; color: red }`
buffer.writeCharCode(c);
}
if (state != _NAME) {
buffer.clear();
state = _BEFORE_SELECTOR;
}
break;
default:
if (state == _BEFORE_SELECTOR) break;
buffer.writeCharCode(c);
if (state == _BEFORE_NAME) {
state = _NAME;
}
}
}
return rules;
}