Layout Object Tree 创建

2023-10-26

站在老罗的肩膀上:https://blog.csdn.net/luoshengyang/article/details/50615628

每一个HTML标签在DOM Tree中都有一个对应的HTMLElement节点。相应地,在DOM Tree中每一个需要渲染的HTMLElement节点在Layout  Object Tree中都有一个对应的Layout  Object节点,如图1所示(To Update):

图1 Layout  Object Tree与DOM Tree、Render Layer Tree和Graphics Layer Tree的关系

       从图1还可以看到,Layout  Object Tree创建完成之后,WebKit还会继续根据它的内容创建一个Layout  Layer Tree和一个Graphics Layer Tree。本文主要关注Render Object Tree的创建过程。

       从前面Chromium DOM Tree创建过程分析一文还可以知道,DOM Tree是在网页内容的下载过程中创建的。一旦网页内容下载完成,DOM Tree就创建完成了。网页的Layout  Object Tree与DOM Tree不一样,它是在网页内容下载完成之后才开始创建的。因此,接下来我们就从网页内容下载完成时开始分析网页的Layout  Object Tree的创建过程。

       从前面Chromium网页URL加载过程分析一文可以知道,WebKit是通过Browser进程下载网页内容的。Browser进程一方面通过Net模块中的URLRequest类去Web服务器请求网页内容,另一方面又通过Content模块中的ResourceLoader类的成员函数OnReadCompleted不断地获得URLRequest类请求回来的网页内容,如下所示:

void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) {
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
               "ResourceLoader::OnReadCompleted");
  DCHECK_EQ(request_.get(), unused);
  DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\""
           << " bytes_read = " << bytes_read;

  pending_read_ = false;

  // bytes_read == -1 always implies an error.
  if (bytes_read == -1 || !request_->status().is_success()) {
    ResponseCompleted();
    return;
  }

  CompleteRead(bytes_read);
}

  src/content/browser/loader/resource_loader.cc

参数bytes_read表示当前这次从URLRequest类中读取回来的网页内容的长度。当这个长度值等于0的时候,就表示所有的网页内容已经读取完毕。这时候ResourceLoader类的成员函数OnReadCompleted就会调用另外一个成员函数ResponseCompleted进行下一步处理。

       ResourceLoader类的成员函数ResponseCompleted的实现如下所示:

void ResourceLoader::ResponseCompleted() {
  TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ResponseCompleted", this,
                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);

  DVLOG(1) << "ResponseCompleted: " << request_->url().spec();

  ScopedDeferral scoped_deferral(this, DEFERRED_FINISH);
  handler_->OnResponseCompleted(request_->status(),
                                std::make_unique<Controller>(this));
}

src/content/browser/loader/mojo_async_resource_handler.cc 

      在前面Chromium网页URL加载过程分析一文中,我们假设ResourceLoader类的成员变量handler_指向的是一个MojoAsyncResourceHandler对象。ResourceLoader类的成员函数ResponseCompleted调用这个MojoAsyncResourceHandler对象的成员函数OnResponseCompleted进行下一步处理。

      MojoAsyncResourceHandler类的成员函数OnResponseCompleted的实现如下所示:

void MojoAsyncResourceHandler::OnResponseCompleted(
    const net::URLRequestStatus& request_status,
    std::unique_ptr<ResourceController> controller) {
  ...
  url_loader_client_->OnComplete(loader_status);
  ...
}

src/content/browser/loader/mojo_async_resource_handler.cc 

void URLLoaderClientProxy::OnComplete(
    const network::URLLoaderCompletionStatus& in_status) {
  ...
  auto message = URLLoaderClientProxy_OnComplete_Message::Build(
      kSerialize, kExpectsResponse, kIsSync, std::move(in_status));
  ...
  ignore_result(receiver_->Accept(&message));
}

src/out/Debug/gen/services/network/public/mojom/url_loader.mojom.cc 

receiver为renderer进程的AsyncResourceHandler类的成员函数OnResponseCompleted所做的事情是向Render进程发送一个类型为ResourceMsg_RequestComplete的IPC消息,用来通知Render进程它所请求的网页内容已下载完毕。

       Render进程是通过ResourceDispatcher类的成员函数DispatchMessage接收类型为ResourceMsg_RequestComplete的IPC消息的,如下所示:

How renderer process accept message from browser
...Missing...

      从这里可以看到,ResourceDispatcher类的成员函数DispatchMessage将类型为mojo::Messege消息分发给另外一个成员函数OnRequestComplete处理。

      ResourceDispatcher类的成员函数OnRequestComplete的实现如下所示:

void ResourceDispatcher::OnRequestComplete(
    int request_id,
    const network::URLLoaderCompletionStatus& status) {
  TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete");

  PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
  ...
  RequestPeer* peer = request_info->peer.get();
  ...
  peer->OnCompletedRequest(renderer_status);
}

src/content/renderer/loader/resource_dispatcher.cc

从前面Chromium网页URL加载过程分析一文可以知道,Render进程在请求Browser进程下载指定URL对应的网页内容之前,会创建一个PendingRequestInfo对象。这个PendingRequestInfo对象以一个Request ID为键值保存在ResourceDispatcher类的内部。这个Request ID即为参数request_id描述的Request ID。因此,ResourceDispatcher类的成员函数OnRequestComplete可以通过参数request_id获得一个PendingRequestInfo对象。有了这个PendingRequestInfo对象之后,ResourceDispatcher类的成员函数OnSetDataBuffer再通过它的成员变量peer获得一个WebURLLoaderImpl::Context对象,并且调用它的成员函数OnCompletedRequest通知它下载网页内容的请求已完成。

       WebURLLoaderImpl::Context类的成员函数OnCompletedRequest的实现如下所示:

void WebURLLoaderImpl::RequestPeerImpl::OnCompletedRequest(
    const network::URLLoaderCompletionStatus& status) {
  context_->OnCompletedRequest(status);
}
void WebURLLoaderImpl::Context::OnCompletedRequest(
    const network::URLLoaderCompletionStatus& status) {
  ...
  if (client_) {
    ...
      client_->DidFail(
          status.cors_error_status
              ? WebURLError(*status.cors_error_status, has_copy_in_cache, url_)
              : WebURLError(status.error_code, status.extended_error_code,
                            has_copy_in_cache,
                            WebURLError::IsWebSecurityViolation::kFalse, url_),
          total_transfer_size, encoded_body_size, status.decoded_body_length);
    } else {
      client_->DidFinishLoading(status.completion_time, total_transfer_size,
                                encoded_body_size, status.decoded_body_length,
                                status.should_report_corb_blocking);
    }
  }
}

src/content/renderer/loader/web_url_loader_impl.cc 

       从前面Chromium网页URL加载过程分析一文可以知道,WebURLLoaderImpl::Context类的成员变量client_指向的是WebKit模块中的一个ResourceLoader对象。在成功下载完成网页内容的情况下,WebURLLoaderImpl::Context类的成员函数OnCompletedRequest调用这个ResourceLoader对象的成员函数d

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Layout Object Tree 创建 的相关文章

随机推荐

  • java-PDF读取一页某一区域内容

    首先还是我的风格 先看效果 在某一页pdf中获取某一块区域的内容和图片 这样就能获取想要的东西了 上代码 这里需要注意maven 是两部分
  • 电路交换,报文交换和分组交换的原理、区别、优缺点

    电路交换 电路交换技术是在通信两端设备间 通过一个一个交换设备中线路的连接 实际建立了一条专用的物理线路 在该连接被拆除前 这两端的设备单独占用该线路进行数据传输 电话系统就是采用了线路交换技术 通过一个一个交换机中的输入线与输出线的物理连
  • word2003脚注问题

    问题分析 在题目上插入脚注的时候 脚注放在文件结尾 然后正文拆开了 不能续前节 解决办法 word2003中 工具 gt 选项 gt 兼容性
  • Java中的byte详解

    Java中的byte详解 介绍 byte 即字节 由8位的二进制组成 在Java中 byte类型的数据是8位带符号的二进制数 在计算机中 8位带符号二进制数的取值范围是 128 127 所以在Java中 byte类型的取值范围也是 128
  • OpenGL 红宝书 反走样 雾 点参数 多边形偏移

    6 2 反走样 void glHint GLenum target GLenum hint 控制OpenGL的某些行为 参数target是要控制的行为 参数hint可以是GL FASTEST GL NICEST GL DONT CARE 效
  • 组成原理---中断

    文章目录 中断的基本概念 中断请求与判优 中断响应 中断服务与返回 中断系统是计算机中实现中断功能的软 硬件总称 一般在 CPU 中配置中断机构 在外设接口中配置中断控制器 在软件上设计相应的中断初始化程序和中断服务程序 中断的基本概念 在
  • python从入门到精通 第一节 数据类型

    Python 中的变量不需要声明 每个变量在使用前都必须赋值 变量赋值以后该变量才会被创建 在 Python 中 变量就是变量 它没有类型 我们所说的 类型 是变量所指的内存中对象的类型 等号 用来给变量赋值 等号 运算符左边是一个变量名
  • 分布式锁的实现与应用

    为什么需要锁 在多任务环境下解决并发场景的数据竞争问题 Java常见锁 我们可以根据锁是否包含某一特性来进行分组归类 从线程是否对资源加锁 可以将锁分为乐观锁和悲观锁 从资源已被锁定时 线程是否阻塞 可以分为自旋锁 JUC下的atomic家
  • react实现计数器

    var In display gt div display div var Btn click gt
  • 同页面javascript中文参数传递

    修改前
  • VMware Workstation 14 Pro 安装 Windows Server 2003(完)

    一 下载镜像文件 Windows Server 2003有多种版本 每种都适合不同的商业需求 Windows Server 2003 Web Edition WindowsServer2003Web版 用于构建和存放Web应用程序 网页和X
  • Python入门的20个基础练习

    01 Hello World python的语法逻辑完全靠缩进 建议缩进4个空格 如果是顶级代码 那么必须顶格书写 哪怕只有一个空格也会有语法错误 下面示例中 满足if条件要输出两行内容 这两行内容必须都缩进 而且具有相同的缩进级别 pri
  • sqli - labs - Less 17

    我们先来看看源码 这里我们可以看到 首先进行上传数据的判断 但是 uname是通过上面的check input函数进行相关过滤所以用户名必须要正确 密码可以忽略 所以本关在密码这里找到突破口 可以看出在得到row变量之后 如果不为空 代码将
  • STM32跳至硬件错误中断(HardFault_Handle)

    1 遇到错误问题是数据类型不对 导致该步骤永远不能执行到 跳至硬件错误中断 所以硬件中断可尝试查找数据类型错误 2 堆栈设置错误也会跳至hardwarefault 3 如果上电后 在调试时 执行单步 会在不确定位置的地方产生HardFaul
  • 基于OpenCV的手势识别完整项目(Python3.7)

    这是我的本科毕设题目 刚开始接触机器学习这方面 感谢CSDN和GitHub上的大佬 网上类似项目很多 方法也有很多 自己顺带进行了整理 边做毕设边分享一下自己学习心得吧 也算是梳理一下所学知识 各大佬有什么好的建议还请指出 不吝赐教 项目简
  • Qt的槽函数崩溃问题

    当Qt的槽函数是一个lambda表达式时 如果传入的方法为引用传递 而你又在lambda表达式里使用了外面定义的stl或类 那么就会崩溃 这是因为Qt的槽函数是一个轮询的过程 第一次你进入这个表达式结束时会进行一次自动析构 第二次进入这个l
  • linux删除文件后没有释放空间

    系统 centos 7 现象 早上收到阿里云短信 发现一台服务器的磁盘空间使用率达到90 昨天晚上已经加了定时任务 难道没有啥用 无奈的我打开电脑 解决 由于已经解决 当时没有截图 查看磁盘空间 df h 找到对应文件 进行删除 rm fi
  • yaml文件的读写

    官方使用文档 https yaml cpp docsforge com 写入 include
  • addr2line命令

    在Linux下写C C 程序的程序员 时常与Core Dump相见 在内存越界访问 收到不能处理的信号 除零等错误出现时 我们精心或不精心写就的程序就直接一命呜呼了 Core Dump是Linux仁慈地留下的程序的尸体 帮助程序员们解决了一
  • Layout Object Tree 创建

    站在老罗的肩膀上 https blog csdn net luoshengyang article details 50615628 每一个HTML标签在DOM Tree中都有一个对应的HTMLElement节点 相应地 在DOM Tree