/** * @return ParserState */ public static function queryState(IObject $aObject) { if ($aObject instanceof Tag) { return ParserStateTag::singleton(); } else { if ($aObject instanceof AttributeValue) { return ParserStateAttribute::singleton(); } else { if ($aObject instanceof Node) { return ParserStateNode::singleton(); } else { if ($aObject instanceof Macro) { return ParserStateMacro::singleton(); } else { if ($aObject instanceof Text) { return ParserStateText::singleton(); } else { if ($aObject instanceof ObjectBase) { return ParserStateDefault::singleton(); } else { throw new Exception("!?"); } } } } } } }
public function complete(IObject $aObject, string $aSource, $nPosition) { Assert::type("org\\jecat\\framework\\ui\\xhtml\\Tag", $aObject, 'aObject'); $aNode = $aObject->parent(); Assert::type("org\\jecat\\framework\\ui\\xhtml\\Node", $aNode); $sTagLen = $nPosition - $aObject->position() + 1; $sTagSource = $aSource->substr($aObject->position(), $sTagLen); $aObject->setSource($sTagSource); $aObject->setEndPosition($nPosition); // 单行标签 if ($sTagSource[strlen($sTagSource) - 2] == '/') { if ($aObject->isTail()) { throw new Exception("UI引擎在分析模板时无法确定标签类型,不能同时是尾标签和单行标签。位置:%d行", $aObject->line()); } $aObject->setTagType(Tag::TYPE_SINGLE); } // 头标签/单行标签 if ($aObject->isHead()) { // 处理属性 $aAttrs = $aObject->attributes(); $aAttrValIterator = $aAttrs->valueIterator(); $arrAttrs = array(); $arrRemoveVal = array(); $aPrevAttrVal = null; for ($aAttrValIterator->rewind(); $aVal = $aAttrValIterator->current(); $aAttrValIterator->next()) { if ($aVal->source() == '=') { // 属性名 if (!$aPrevAttrVal) { throw new Exception("UI引擎在分析模板时遇到空属性名称。位置:%d行", $aVal->line()); } $aAttrName = $aPrevAttrVal; if ($aAttrName->quoteType()) { throw new Exception("UI引擎在分析模板时遇到无效的节点属性名称,属性名称不能使用引号。位置:%d行", $aAttrName->line()); } $sAttrName = $aAttrName->source(); // 属性值 $aAttrValIterator->next(); $aAttrVal = $aAttrValIterator->current(); if (!$aAttrVal) { continue; throw new Exception("UI引擎在分析模板时遇到错误:属性名:%s没有对应的属性值。位置:%d行", array($sAttrName, $aVal->line())); } $aAttrVal->setName($sAttrName); // 移除 val name array_pop($arrAttrs); $arrAttrs[] = $aAttrVal; } else { $arrAttrs[] = $aVal; } $aPrevAttrVal = $aAttrValIterator->current(); } $aAttrs->clear(); foreach ($arrAttrs as $aAttrVal) { $aAttrs->add($aAttrVal); } if ($aObject->isSingle()) { // 单行标签节点结束 return ParserStateNode::singleton()->complete($aNode, $aSource, $nPosition); } else { return $aNode; } } else { if ($aObject->isTail()) { if ($aNode->tagName() != $aObject->name()) { throw new Exception("遇到不匹配的XHTML节点,头标签:%s(line:%d), 尾标签:%s(line:%d)", array($aNode->tagName(), $aNode->line(), $aObject->name(), $aObject->line())); } // 节点结束 return ParserStateNode::singleton()->complete($aNode, $aSource, $nPosition); } else { throw new Exception("遇到无效的xhtml标签。源文:%s", $sTagSource); } } }