6.5 中 HTML API 的更新

WordPress 6.5 对HTML API 进行了重大更新。值得注意的是,标签处理器进行了重大修改,使其能够扫描 HTML文档中的每个标记并解锁一系列广泛的新功能。HTML处理器比WordPress 6.4 中最低限度引入时支持更多的 HTML规范。

标签处理器中的新功能。

标签处理器旨在扫描 HTML文档中的每个标签,跳过所有非标签标记。在 WordPress 6.5 中,它可以扫描所有内容。令牌是构成文档的基本部分;对于 HTML,它们是标签、注释、文档类型定义和文本节点。这意味着现在可以读取 HTML 文档的文本内容,简化以前复杂的操作,例如剥离标签或截断 HTML。

支持这项工作的是引入了一个称为可修改文本的新概念。可修改的文本表示标记边界内的内容,或者可以更改而不影响整个文档结构的内容。不同的标记包含不同类型的可修改文本:

  • 文本节点的整个范围都是可修改的文本。
  • HTML 注释的内部内容是可修改的文本。
  • 特殊元素的开始标签和结束标签之间的内容是可修改的内容。

在这种情况下,特殊元素是指其内部内容不能包含其他 HTML 标签的元素。其中包括 SCRIPT 和 STYLE 元素的内容以及 TITLE 和 TEXTAREA 元素的内容。还有一些代表已弃用或无效的语法:请参阅类文档以获取完整列表。

新方法。

  • next_token()前进到文档中的下一个标记,包括结束标记。与此方法不同的next_tag()是,没有查询。它扫描一切
  • get_token_type()指示找到哪种标记,例如 a#tag#text#comment
  • get_token_name()返回一个大致对应于 DOM 的值nodeName,例如SPANor #textor html(对于 doctype 声明)。
  • get_modifiable_text()返回匹配标记的正确解码的文本内容。
  • get_comment_type()指示为什么标记是注释,因为不同类型的无效标记会变成 HTML 注释。例如,<​![CDA​TA[​text]​]>是该类型的 HTML 注释COMMENT_AS_CDATA_LOOKALIKE,因为它看起来好像是 CDATA 部分,而 HTML 内容中不存在该部分。
  • paused_at_incomplete_token()指示标签处理器是否到达文档末尾的标记中间。例如,它可能在标签中间被截断。

用法示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$title = null;
$text_content = '';
$processor = new WP_HTML_Tag_Processor( $html );
while ( $processor->next_token() ) {
    if ( '#text' === $processor->get_token_type() ) {
        $text_content .= $processor->get_modifiable_text();
    } elseif ( null === $title && 'TITLE' === $processor->get_token_name() ) {
        $title = $processor->get_modifiable_text();
    }
}
 
echo $title ? $title : '(untitled post)';
echo "\n\n";
echo $text_content;

HTML 处理器中的扩展支持。

WordPress 现在能够识别并正确解析大多数 HTML。只有少数几个主要例外。

  • HTML 处理器在遇到 FORM、MATH、SVG、TABLE 或 TEMPLATE 标记时都会退出。这些元素引入了复杂的解析规则,需要额外的关注、测试和设计工作。
  • 有时,HTML 解析器需要隐式创建 HTML 本身不存在的元素,或者需要将标记移动到文档中较早的位置。这需要进一步的设计工作来正确传达文档已追溯更改的信息。
  • 如果 HTML 处理器被馈送到 BODY 元素外部存在的完整 HTML 文档或片段(例如文档 HEAD),那么它将中止,因为它当前仅支持解析 BODY 上下文内的 HTML。

最后一点强调,HTML 处理器是根据块相关代码的需求而开发的,并重点关注 HTML 规范中与如何在 BODY 元素内解释标签相关的规则。完成此部分后,将添加其他部分。值得庆幸的是,从长远来看,这是最难的部分,在完成主要工作后应该很快就能解析完整的文档。

实验者注意事项。

如果您一直在尝试 HTML API 并构建标签处理器的自定义子类,那么了解两个更改非常重要:处理不完整的文档以及具有可修改文本的特殊 HTML 标签。

文件不完整。

以前,当标签处理器到达文档末尾并且存在不完整的标记(例如“ <div cl”)时,它会返回false并完成文档的解析。现在标签处理器可以扫描并访问文档中的每个标记,但是,它会指示是否遇到了这种情况。当它发生时,它仍然会返回false,但它会返回到令牌的开头并冻结。在未来的版本中,将可以扩展文档并继续处理。现在,如果paused_at_incomplete_token()返回true,那么您可以知道发送到处理器的原始 HTML 可能比收到的更多

带有可修改文本的特殊 HTML 标签。

 

HTML 处理器正确跟踪文档结构,并且是确定元素何时开始和结束的适当方法。许多更简单的方法对于实际使用来说通常看起来足够正确,但在常见情况下这些方法都会失效。虽然标签处理器比基于正则表达式的方法更容易估计结构,但在跳过 HTML 处理器实现的规则时要小心,因为即使是规范的 HTML 也常常会破坏将 HTML 文本转换为 DOM 结构的简单心理模型。

对于那些依赖标签处理器来估计结构的人来说,行为上的变化可能会破坏您的子类:标签处理器不再访问特殊元素组的结束标签。这些是 SCRIPT、STYLE 和 TITLE 等标签。进行此更改的原因是这些元素内部不能包含其他标签。它通常看起来像它们一样(例如,使用<title>an <img> is plain text</title>),但内部内容被解析为文本而不是 HTML。此更改可防止将这些内部内容误解为 HTML 标记。

当标签处理器遇到 SCRIPT 标签或任何这些特殊元素时,它将继续解析,直到找到关联的结束标签,然后内部内容将作为可修改的文本提供。对于跟踪文档深度的算法,它们不仅需要检查 tag 是否is_void(),还需要检查它是否是特殊元素,因为结束标签将不再被单独访问。