Mozilla 中对布局的介绍

概要

  • 基本数据流
  • 关键数据结构
  • 详细执行步骤
  • 渐进模式
  • 未来高科技会谈
  • 总结起来,Q&A

基本数据流

  • 通过网络APIs获取源文档
  • 在单线程布局引擎中依次执行下面步骤:
    • 解析,计算样式,渲染;重复
    • CSS 用于渲染所有的内容
  • 理论上,内容与“展示”是相分离的

关键数据结构

  • 内容节点
    • 元素,属性,叶(leaves)
    • DOM
  • 帧(Frame)
    • 矩形格式
    • 几何信息
    • [0..n] 每个内容节点
    • 从第2个到第n个是“连续到”
  • 样式上下文(Style context)
    • 非几何信息
    • 可由相邻帧共享
    • 引用计数,从属于帧(frame)
  • 视图(View)
    • 裁剪,z顺序,透明度
    • [0..1] 仅与一个帧(frame)对应, 从属于帧(frame)
  • 小工具
    • 本地窗口
    • [0..1] 仅与一个视图(view)对应,从属于视图(view)

关键数据结构

  •  document对象中包含内容模型,以及一个或多个presentations
    • 通过DOM API 以编程方式暴露在外
  • presentation包含框架层级关系
    • 帧包含样式上下文,视图,控件
    • 演示包含的媒体类型,尺寸等
    • 可能不会直接操控

详细执行步骤

  • 设置
  • 内容模型的构建
  • 框架Frame 的构建
  • 样式Style 的決議
  • 回流
  • 繪畫

设置

  • 假設此處您已經熟悉嵌入和network API (doc shell, stream) 的基本知識。
  • Content DLL自動註冊一个文档裝載工厂(DLF)
    • @ mozilla.org /内容查看器工厂/视图; 1类型= text / html的
    • 所有MIME types 都与同一个類nsContentDLF 相对应
  • nsDocShell
    • 通过  nsDSURIContentListener接收获取的内容(原始数据)
    • 调用nsIDLF::CreateInstance方法,傳遞MIME type给DLF
  • nsContentDLF
    • 创建一个nsHTMLDocument对象,调用StartDocumentLoad
      • 创建一个解析器parser,将nsIStreamListener对象返回给docshell
      • 创建一个content sink (它会将解析器parser 与文档doucment 相連接)
    • 创建一个DocumentViewerImpl对象,将nsIContentViewer对象返回给docshell
  • DocumentViewerImpl创建pres context和pres shell

内容模型的构建

  • 從網絡上通过nsIStreamListener::OnDataAvailable获取内容
  • 解析器对内容進行標記&處理;使用  parser node对象在nsIContentSink上调用方法
    • 一些緩衝和修正发生在这里
    • OpenContainer,CloseContainer,AddLeaf
  • 内容水槽创建並使用附加内容節點nsIContent接口
    • 内容水槽保持棧的“活”元素
    • 更多緩衝和修正发生在这里
    • InsertChildAt,AppendChildTo,RemoveChildAt

框架Frame 的构建

  • 内容接收器使用nsIDocument接口,在内容模型通知ΔS的
    • ContentAppended,ContentInserted,ContentRemoved
  • PresShell被註冊作为文件觀察者
    • 接收ContentAppended等通知
    • 它傳遞给样式集的对象,誰又将傳遞给帧构造
  • 框架构造函數创建帧
    • ConstructFrameInternal遞歸散步内容樹,解決作風和创建帧
    • 或者通过標籤创建(< 選擇>)或顯示类型(<P>)
  • 帧管理者保持映射從内容到框架

Style 選定

  • 计算依據適用於框架的内容節點样式規則文體信息
  • 分成不同的结构样式数据
    • 顯示,能見度,字體,顏色,背景,...
    • 繼承与復位
  • 样式上下文对象是一个占位符部分计算文體数据
    • 样式数据懶洋洋地计算,因为它要求

回流

  • 遞歸计算幾何(x,Ÿ,W¯¯,^ h)为框架,视图和小部件
    • 鑑於“根帧”计算(W&H約束x,ÿ,W¯¯,^ h)为所有兒童
    • 通过約束傳播“向下”nsHTMLReflowState
    • 所需的大小返回“向上”通过nsHTMLReflowMetrics
  • 基本模式
    • 父框架初始化子回流狀態(可W¯¯,^ h); 地方子帧(x,ÿ); 调用孩子的回流方法
    • 子帧计算所需的(W¯¯,^ h),通过回流焊指標回報
    • 家長外形尺寸为子框架和观点的基礎上孩子的指標
  • 注:很多並不這樣工作!(表,塊,XUL盒)

回流

  • “環球”回流
    • 最初,調整大小,风格變化
    • 通过立即處理PresShell方法
  • 增量回流
    • 針对特定的帧
    • 内容改變风格改變了用戶自定義
    • nsHTMLReflowCommand对象封裝信息
    • 排隊和異步處理,nsIPressShell :: AppendReflowCommand,ProcessReflowCommands

增量回流

  • 遞歸下降到目標恢復回流狀態
    • 兒童rs.reason设置为增量

增量回流

  • 流程回流“正常”的目標框架
    • 兒童rs.reason一套基於RC的类型

增量回流

  • 傳播損害到“在流動”帧之后

增量回流

  • 多次回流焊命令批處理
    • nsReflowPath維持目標帧的一棵樹
    • 攤銷狀態的恢復和損傷擴展成本

繪畫

  • 當回流繼續通过帧層次结构,區域無效通过nsIViewManager ::更新视图
  • 除非直接的,無效的區域合併,並通过操作系統的異步處理揭露事件
  • 本機暴露事件分派到小部件; 小部件委託给视图管理器
  • 查看經理描繪的意見后到前,调用PresShell畫圖方法
  • PresShell ::油漆遍歷從视图帧; 将调用nsIFrame ::油漆每個

漸進

  • 單線程
    • 簡單(無鎖)
    • 不能離開事件隊列無人值守
  • 内容建設開卷“隨意”
    • 解析器和内容接收器做一些緩衝
    • 内容散熱器具有“通知限制”
    • 效率与響應速度的權衡
  • 框架结构運行完成
  • CSS解析運行完成
  • 回流焊運行完成(主要)
  • 繪畫運行完成

未来(?)技术讲座

  • 内容模型和DOM - jst,jkeiser
  • 解析器和内容接收器(ESP無效的内容) - harishd
  • 事件- 薩里條既納
  • 塊和行回流焊- 沃特森,dbaron
  • 表回流焊- karnaze
  • 窗體控件- 棒,礪石
  • 风格解析和規則樹- dbaron
  • 视图,窗口小部件,和繪畫- 大鵬 ,kmcclusk
  • 編輯器- 健,Jfrancis
  • XUL和箱的佈局- 休伊特
  • XBL - 休伊特

最后

  • 数据流
  • 关键数据结构
  • 详细演练
  • 渐进
  • Q&A?

原始文档信息