浏览器的容错度
你从不会在HTML页面上得到“无效语法”错误。浏览器修正一个无效内容然后继续处理。
例如下面的HTML:
<html> <mytag> </mytag> <div> <p> </div> Really lousy HTML </p> </html>
我几乎违反了所有规则(“mytag”不是个标准标签,“p”和“div”有错误嵌套,还有其它错误)但是浏览器仍然正确显示,并没有抱怨。所以有大量的解析器代码用于修正HTML作者的错误。
浏览器的错误处理非常一致,但令人惊奇的是这并不是当前HTML规范的一部份。象书签和向后/向前按钮一样,这只是多年对浏览器的开发形成的东西。有些著名的非法HTML结构在许多网站上反复出现,于是一种浏览器就试图跟别的浏览器一样以一致的方式纠正它们。
HTML5规范定义了一些这样的需求,Webkit在HTML解析类的开始处的注释里给予了恰当的总结。
“解析器把标记化的输入解析成文档,建立文档树。如果文档组织良好,一直往下处理就行了。不幸的是,我们必须处理许多结构混乱的HTML文档,因此解析器不得不提供容错能力。我们必须考虑至少以下错误状况:
1 被增加的元素明确的不允许添加到某些外标签中。
在这种情况下,我们应该关闭所有到这个标签(拒绝添加这个元素的)之前的标签,把它添到后面。
2 不允许我们直接添加这个元素。
可能是因为写这个文档的人忘了里面的一些标签(或其中的一些标签是可选的)。
这可能发生在后面的一些标签里:HTML HEAD BODY TBODY TR TD LI (我忘了什么吗?)
3 我们希望增加一个块元素到一个内联元素里。关闭到下一个更高层的块元素为止的所有内联元素。
4 如果这些都没用,关闭元素,直到允许我们添加这个元素或忽略这个标签。”
我们看一些Webkit容错性的例子:
</br>替换<br>
一些站点用</br>代替<br>。为了兼容IE和Firefox,Webkit象处理<br>一样处理它们。代码:
if (t->isCloseTag(brTag) && m_document->inCompatMode()) { reportError(MalformedBRError); t->beginTag = true;
注意—错误处理只在内部—不会被展现给用户。
零散的表格
零散的表格是一个在另一个表格内容里的表格,但却没有处于一个单元格里面。
象这样的例子:
<table> <table> <tr><td>inner table</td></tr> </table> <tr><td>outer table</td></tr> </table>
Webkit将更正这种层级关系为两个兄弟表:
<table> <tr><td>outer table</td></tr> </table> <table> <tr><td>inner table</td></tr> </table>
代码:
if (m_inStrayTableContent && localName == tableTag) popBlock(tableTag);
Webkit为当前元素内容使用了一个栈—它会把内部表从外部表栈里弹出。表格就变成兄弟表了。
嵌套的form元素
在用户把一个form放进另一个form的情况下,第二个form会被忽略掉。
代码:
if (!m_currentFormElement) { m_currentFormElement = new HTMLFormElement(formTag, m_document); }
过深的标签层次
注释里自己说道:
www.liceo.edu.mx是一个站点的例子,嵌套居然达到了大约1500个标签,一长串<b>标签。
我们只允许最多20个相同类型的标签嵌套,否则将全部忽略它们。
bool HTMLParser::allowNestedRedundantTag(const AtomicString& tagName) { unsigned i = 0; for (HTMLStackElem* curr = m_blockStack;i < cMaxRedundantTagDepth && curr && curr->tagName == tagName;curr = curr->next, i++) { } return i != cMaxRedundantTagDepth; }
html和body结束标签放置错误
再一次—注释里自己提到:
“支持未结束的html。
我们从未关闭body标签,因为一些愚蠢的网页在实际文档结束之前就关闭了它。我们依靠end()调用来关闭一切。”
if (t->tagName == htmlTag || t->tagName == bodyTag ) return;
所以网页编写者们可得小心了—除非你愿意出现在Webkit的容错性例子里—所以记得要编写结构良好的HTML。
(待续)
原创文章,作者:苏葳,如需转载,请注明出处:https://www.swmemo.com/2038.html