/** * 获取下一个token * @see Fl_Token::getNextToken() */ public function getNextToken() { $token = parent::getNextToken(); if ($token || $token === false) { return $token; } $result = ""; while ($this->pos < $this->length) { //如果是圆括号,则匹配对应的结束圆括号 if ($this->text[$this->pos] === '(') { $match = $this->getMatched("(", ")"); $result .= $match; continue; } $char = $this->getNextChar(); if ($this->isWhiteSpace($char) && !preg_match("/^\\s*\\(/", substr($this->text, $this->pos))) { break; } else { $result .= $char; } } if (strlen($result)) { return $this->getTokenInfo(FL_TOKEN_CSS_VALUE_TYPE_COMMON, $result); } return false; }
/** * get next token * @see Fl_Token::getNextToken() */ public function getNextToken() { $token = parent::getNextToken(); if ($token || $token === false) { return $token; } //获取特殊Token $token = $this->getSpecialToken(); if ($token) { return $token; } $char = $this->text[$this->pos]; //字符串 $result = $this->getQuoteText($char, true, true); if ($result) { $this->pendingNextChar = false; return $this->getTokenInfo(FL_TOKEN_JS_STRING, $result); } //数值 if (Fl_Js_Static::isDigit($char) || $char === '.' && preg_match("/\\d/", $this->text[$this->pos + 1])) { $result = $this->getNumberToken($char); return $this->getTokenInfo(FL_TOKEN_JS_NUMBER, $result); } //符号 if (Fl_Js_Static::isPuncChar($char) || $char === '.') { $this->getNextChar(); if (isset($this->validateData[$char])) { $this->validateData[$char]++; } return $this->getTokenInfo(FL_TOKEN_JS_PUNC, $char); } if ($char === '/' && $this->regexpAllowed) { $result = $this->getRegexpToken($char); return $this->getTokenInfo(FL_TOKEN_JS_REGEXP, $result); } //操作符号 if (Fl_Js_Static::isOperatorChar($char) || $char === '/') { $result = $this->getOperatorToken($char); return $this->getTokenInfo(FL_TOKEN_JS_OPERATOR, $result); } //单词 if (Fl_Js_Static::isIdentifierStart($char)) { $result = $this->readWhile('getWordToken'); $type = FL_TOKEN_JS_NAME; if (Fl_Js_Static::isKeywordAtom($result)) { $type = FL_TOKEN_JS_ATOM; } else { if (Fl_Js_Static::isOperator($result)) { $type = FL_TOKEN_JS_OPERATOR; } else { if (Fl_Js_Static::isKeyword($result)) { $type = FL_TOKEN_JS_KEYWORD; } } } return $this->getTokenInfo($type, $result); } $this->throwException('Unexpected character ' . $char); }
/** * 获取下一个TOKEN * (non-PHPdoc) * @see Fl_Token::getNextToken() */ public function getNextToken() { $token = parent::getNextToken(); if ($token || $token === false) { return $token; } $char = $this->getCurrentChar(); if ($char === false) { return $this->getLastToken(); } //现在特殊token的配置第一个字符都是<,所有可以优先判断<进行提速 if ($char === Fl_Html_Static::LEFT) { $token = $this->getSpecialToken(); if ($token) { return $token; } } $next = $this->getPosChar($this->pos + 1); //当前字符为<,且下个字符不为<,且下个字符是个合法的tag首字符 if ($char === Fl_Html_Static::LEFT && $next !== Fl_Html_Static::RIGHT && Fl_Html_Static::isTagFirstChar($next)) { $token = $this->readWhile('getTagToken'); if ($this->tagChecked) { $lastChar = $token[strlen($token) - 1]; //检测tag最有一个字符是否是> if ($lastChar !== Fl_Html_Static::RIGHT) { $this->throwException('uncaught tag token ' . $token); } } $type = FL_TOKEN_HTML_TAG_START; if (strpos($token, '</') === 0) { $type = FL_TOKEN_HTML_TAG_END; } elseif (!$this->isXML && strpos($token, Fl_Html_Static::XML_PREFIX) === 0) { $this->isXML = true; $type = FL_TOKEN_XML_HEAD; array_push(Fl_Html_Static::$specialTokens, array(Fl_Html_Static::CDATA_PREFIX, Fl_Html_Static::CDATA_SUFFIX, FL_TOKEN_XML_CDATA)); } return $this->getTokenInfo($type, $token); } $token = $this->readWhile('getTextToken'); if (isset($token)) { $this->newlineBefore -= count(explode(FL_NEWLINE, $token)) - 1; return $this->getTokenInfo(FL_TOKEN_HTML_TEXT, $token); } $this->throwException('uncaught char ' . $char); }
/** * 获取下一个TOKEN * @see Fl_Token::getNextToken() */ public function getNextToken() { $token = parent::getNextToken(); if ($token || $token === false) { return $token; } $char = $this->text[$this->pos]; switch ($char) { case "@": $this->pendingNextChar = false; $value = rtrim($this->readWhile('getAtToken')); $type = $this->getAtDetailType($value); break; case "{": $type = $this->getStartBracesType(); $this->getNextChar(); break; case "}": $type = $this->getEndBracesType(); $this->getNextChar(); break; case ":": if ($this->preTokenType == FL_TOKEN_CSS_PROPERTY || $this->preTokenType == FL_TOKEN_TPL) { $this->getNextChar(); $type = $this->preTokenType = FL_TOKEN_CSS_COLON; } break; case ";": if ($this->validate && $this->preTokenType === FL_TOKEN_CSS_PROPERTY) { $this->throwException("`;` can not after propery"); } $this->getNextChar(); $type = $this->preTokenType = FL_TOKEN_CSS_SEMICOLON; break; } if ($type) { return $this->getTokenInfo($type, isset($value) ? $value : $char); } //specail tokens now only have [;color:red;], performance opti if ($char === '[') { $token = $this->getSpecialToken(); if ($token) { return $token; } } switch ($this->preTokenType) { case FL_TOKEN_CSS_BRACES_ONE_START: case FL_TOKEN_CSS_SEMICOLON: $result = $this->getPropertyToken($char); $this->preTokenType = FL_TOKEN_CSS_PROPERTY; if (!$this->checkProperty($result)) { $this->throwException("property `" . str_replace("\n", " ", $result) . "` is not valid."); } return $this->getTokenInfo(FL_TOKEN_CSS_PROPERTY, $result); case FL_TOKEN_CSS_COLON: #case FL_TOKEN_CSS_PROPERTY : $result = trim($this->getValueToken()); $this->preTokenType = FL_TOKEN_CSS_VALUE; return $this->getTokenInfo(FL_TOKEN_CSS_VALUE, $result); default: //$result = trim ( $this->readWhile ( 'getSelectorToken' ) ); $result = $this->getSelectorToken($char); if ($this->validate && $this->text[$this->pos] !== '{') { $this->throwException('get Selector error `' . $result . '`' . $this->text); } $this->preTokenType = FL_TOKEN_CSS_SELECTOR; return $this->getTokenInfo(FL_TOKEN_CSS_SELECTOR, $result); } $this->throwException('uncaught char ' . $char); }
/** * get next token * @see Fl_Token::getNextToken() */ public function getNextToken() { $token = parent::getNextToken(); if ($token || $token === false) { return $token; } $char = $this->getCurrentChar(); if ($char === false) { return $this->getLastToken(); } if (!$this->_checkNamespace) { $this->_checkNamespace = true; if (Fl_Css_Static::checkNamespace($this->text)) { $result = $this->readWhile('getNamespaceToken'); return $this->getTokenInfo(FL_TOKEN_CSS_SELECTOR_NAMESPACE, $result); } } $type = ''; $value = ''; switch ($char) { case '*': $type = FL_TOKEN_CSS_SELECTOR_UNIVERSAL; $this->getNextChar(); $value = $char; break; case ',': $type = FL_TOKEN_CSS_SELECTOR_COMMA; $this->getNextChar(); $value = $char; break; case '>': case '+': case '~': $this->getNextChar(); $value = $char; $type = FL_TOKEN_CSS_SELECTOR_COMBINATOR; break; case '#': $type = FL_TOKEN_CSS_SELECTOR_ID; $value = $this->readWhile('getIdToken'); break; case '.': $type = FL_TOKEN_CSS_SELECTOR_CLASS; $value = $this->readWhile('getClassToken'); break; case '[': $type = FL_TOKEN_CSS_SELECTOR_ATTRIBUTES; $value = $this->getAttributeToken($char); break; case ':': if ($this->getPosChar($this->pos + 1) === ':') { $this->getNextChar(); $value = ':' . $this->readWhile('getPseudoElementToken'); $type = FL_TOKEN_CSS_SELECTOR_PSEUDO_ELEMENT; } else { $value = $this->getPseudoClassToken($char); $type = FL_TOKEN_CSS_SELECTOR_PSEUDO_CLASS; } break; default: $value = $this->readWhile('getTypeToken'); $type = FL_TOKEN_CSS_SELECTOR_TYPE; } if ($this->check && !Fl_Css_Static::checkSelectorToken($type, $value)) { $this->throwException($value . ' is not valid'); } return $this->getTokenInfo($type, $value); }
/** * 获取下一个TOKEN * @see Fl_Token::getNextToken() */ public function getNextToken() { $token = parent::getNextToken(); if ($token || $token === false) { return $token; } $char = $this->getCurrentChar(); if ($char === false) { return $this->getLastToken(); } if ($char === '@') { $result = $this->readWhile('getAtToken'); $type = $this->getAtDetailType($result); return $this->getTokenInfo($type, $result); } else { if ($char === '{') { $type = $this->getStartBracesType(); $this->getNextChar(); return $this->getTokenInfo($type, $char); } else { if ($char === '}') { $type = $this->getEndBracesType(); $this->getNextChar(); return $this->getTokenInfo($type, $char); } else { if ($char === ':') { if ($this->preTokenType != FL_TOKEN_CSS_PROPERTY && $this->preTokenType != FL_TOKEN_TPL) { $this->throwException('prev value is not property or tpl'); } $this->getNextChar(); $this->preTokenType = FL_TOKEN_CSS_COLON; return $this->getTokenInfo(FL_TOKEN_CSS_COLON, $char); } else { if ($char === ';') { $this->getNextChar(); $this->preTokenType = FL_TOKEN_CSS_SEMICOLON; return $this->getTokenInfo(FL_TOKEN_CSS_SEMICOLON, $char); } } } } } $token = $this->getSpecialToken(); if ($token) { return $token; } switch ($this->preTokenType) { case FL_TOKEN_CSS_BRACES_ONE_START: case FL_TOKEN_CSS_SEMICOLON: $result = $this->readWhile('getPropertyToken'); $this->preTokenType = FL_TOKEN_CSS_PROPERTY; return $this->getTokenInfo(FL_TOKEN_CSS_PROPERTY, $result); case FL_TOKEN_CSS_COLON: case FL_TOKEN_CSS_PROPERTY: $result = $this->getValueToken(); $this->preTokenType = FL_TOKEN_CSS_VALUE; return $this->getTokenInfo(FL_TOKEN_CSS_VALUE, $result); default: $result = $this->readWhile('getSelectorToken'); if ($this->getPosChar($this->pos) !== '{') { $this->throwException('get Selector error'); } $this->preTokenType = FL_TOKEN_CSS_SELECTOR; return $this->getTokenInfo(FL_TOKEN_CSS_SELECTOR, $result); } $this->throwException('uncaught error'); }
/** * get next token * @see Fl_Token::getNextToken() */ public function getNextToken() { //左右定界符可能包含html注释 $this->skipWhiteSpace(); $this->startToken(); $tplToken = $this->getTplToken(); if ($tplToken !== false) { return $this->getTokenInfo(FL_TOKEN_TPL, $tplToken); } $token = parent::getNextToken(); if ($token || $token === false) { return $token; } $char = $this->text[$this->pos]; //现在特殊token的配置第一个字符都是<,所有可以优先判断<进行提速 if ($char === Fl_Html_Static::LEFT) { $token = $this->getSpecialToken(); if ($token) { return $token; } } $next = $this->text[$this->pos + 1]; //当前字符为<,且下个字符不为<,且下个字符是个合法的tag首字符 if ($char === Fl_Html_Static::LEFT && $next !== Fl_Html_Static::RIGHT && Fl_Html_Static::isTagFirstChar($next)) { $token = $this->readWhile('getTagToken'); if ($this->validate) { $lastChar = $token[strlen($token) - 1]; //检测tag最有一个字符是否是> if ($lastChar !== Fl_Html_Static::RIGHT) { $this->throwException('uncaught tag token ' . $token); } } $type = FL_TOKEN_HTML_TAG_START; if (strpos($token, '</') === 0) { $type = FL_TOKEN_HTML_TAG_END; } elseif (!$this->isXML && strpos($token, Fl_Html_Static::XML_PREFIX) === 0) { $this->isXML = true; $type = FL_TOKEN_XML_HEAD; array_push(Fl_Html_Static::$specialTokens, array(Fl_Html_Static::CDATA_PREFIX, Fl_Html_Static::CDATA_SUFFIX, FL_TOKEN_XML_CDATA)); } return $this->getTokenInfo($type, $token); } $token = $this->readWhile('getTextToken'); if (isset($token)) { //check tag name if ($this->validate && ($token === '<' || $token[strlen($token) - 1] === '<')) { if ($this->hasTplToken && $this->ld === substr($this->text, $this->pos, strlen($this->ld))) { $text = substr($this->text, $this->pos); $pattern = "/" . preg_quote($this->ld, "/") . ".*?" . preg_quote($this->rd, "/") . "/e"; $text = preg_replace($pattern, "", $text); $pos = strpos($text, ">"); if ($this->validate && $pos !== false && strpos(substr($text, 0, $pos), "<") === false) { $this->throwException("tag name can't have tpl."); } } } $this->newlineBefore -= count(explode(FL_NEWLINE, $token)) - 1; return $this->getTokenInfo(FL_TOKEN_HTML_TEXT, $token); } $this->throwException('uncaught char ' . $char); }