Gecko

Gecko 是 Mozilla 的网页渲染引擎。它由 HTML 解析和渲染、网络、JavaScript、IPC、DOM、操作系统窗口部件抽象等等组成。它还包括一些与基于 Gecko 构建的应用程序共享的 UI 组件,例如桌面版 Firefox、Android 版 Firefox 和 Thunderbird。除了渲染网页,Gecko 还负责在某些应用程序中渲染应用程序的 UI。

网络 (necko)

网络引擎为 DNS 查询以及使用 http、http/2 或 http/3 协议托管在 Web 服务器上的内容服务请求。Necko 使用 NSS (网络安全服务库) 进行其加密用途,例如使用 TLS 执行安全请求。

阅读更多

JavaScript (SpiderMonkey)

JavaScript 引擎负责运行网页内容进程中的 JavaScript 代码,以及构成 Firefox 和 Thunderbird 等应用程序中大部分 UI 的 JavaScript 代码。

阅读更多

JavaScript 模块

SpiderMonkey 支持一种专有的 JavaScript 模块类型,它是在 EcmaScript 模块标准之前,甚至在 commonjs 流行之前开发的。这些模块使用包含要导出的符号名称列表的 EXPORTED_SYMBOLS 数组定义导出。这种模块正在被标准的 EcmaScript 模块取代。

XPCOM

XPCOM(跨平台组件对象模型)是 Mozilla 版本的 Microsoft COM

XPCOM 和 WebIDL 是我们的前端与底层平台通信并调用以本机代码实现的方法的主要方式。

XPCOM 执行以下关键功能

  1. 允许使用 XPIDL 创建具有严格定义的 接口 的软件组件。这些组件可以用 C++、JavaScript 或 Rust 实现。它们也可以在任何这些语言中调用和操作,而不管底层实现语言是什么。

  2. 充当命名组件的进程全局注册表(有单例“服务”以及用于创建组件实例的工厂)。

  3. 允许组件和服务实现多个接口,并使用 QueryInterface 动态转换为这些接口。

如果这一切听起来都相当抽象,那是因为它确实很抽象。XPCOM 是 Firefox 仍在构建其上的最古老的 Mozilla 技术之一。在 90 年代后期,当 Microsoft COM 仍然很流行并且 Mozilla 代码库也作为第三方的一般应用程序开发平台进行开发时,XPCOM 的意义更大。一直有 长期努力 在其有用性存疑的地方逐步摆脱或简化 XPCOM。

sequenceDiagram Caller->>Component Registry: 获取服务 @mozilla.org/cookie-banner-service#59;1 Component Registry->>nsCookieBannerService: 新建 nsCookieBannerService-->>Component Registry: 返回 Component Registry-->>Caller: 返回 Caller->>nsCookieBannerService: QueryInterface(nsICookieBannerService) nsCookieBannerService-->>Caller: 返回

阅读更多

进程分离/裂变/IPC/Actor

Firefox 是一个多进程应用程序。在主 Firefox 进程的生命周期中,可以启动和停止许多其他子进程。这些不同进程的完整目录可以在 此处 找到。

Firefox 在这些进程之间(主要)使用底层平台的本机进程间通信机制进行异步通信。这些机制及其详细信息隐藏在跨平台抽象之下,例如 IPDL(用于本机代码)和 JSActors(用于前端代码)。

Firefox 的初始 Web 内容进程分离(这是“电解”项目,有时缩写为“e10s”)于 2016 年发布,并将所有 Web 内容分离到一个共享的内容进程中。不久之后,启用了多个内容进程,并且选项卡的 Web 内容将使用循环方案分配给创建的内容进程之一。2021 年,作为对 幽灵熔断 处理器漏洞的缓解措施的一部分,Firefox 的进程模型发生了变化,以强制执行一个模型,其中每个内容进程仅加载并执行来自单个站点的指令(这是“裂变”项目)。您可以阅读更多关于 “裂变”项目的基础原理和技术细节

DOM + WebIDL

DOM API 实现网页和 Gecko 渲染的 UI 中元素的功能。

WebIDL 是用于描述 DOM 对象接口的标准规范。除了定义网页的接口,Gecko 还使用它来定义各种内部组件的接口。与 XPCOM 一样,实现 WebIDL 接口的组件可以从 C++ 和 JavaScript 调用。

样式系统 (CSS)

样式系统负责解析文档的 CSS 并使用它为文档中每个元素上的每个 CSS 属性解析一个值。这决定了每个元素将如何渲染的许多特征(例如字体、颜色、大小、布局模型)。

阅读更多

布局

布局引擎负责获取 DOM 和样式并生成和更新一个框架树,以供用户呈现。

阅读更多

图形

图形组件负责获取布局引擎生成的框架树并在屏幕上呈现它。

阅读更多

本地化 (Fluent)

在 Mozilla,本地化由全球各地的语言社区管理,他们负责将 Mozilla 软件高质量地语言和文化适应到 100 多个语言环境中。

本地化管理的确切过程因项目而异,但在 Gecko 应用程序的情况下,本地化主要通过名为 Pontoon 的 Web 本地化系统完成,并存储在 github.com/mozilla-l10n/firefox-l10n 下的 GitHub 存储库中。

阅读更多

配置文件

用户配置文件是 Gecko 存储设置、缓存和任何其他必须在应用程序退出后持续存在的数据的位置。它由磁盘上的两个目录组成。根目录(通常称为配置文件目录)是存储设置的位置。本地目录用于缓存或任何其他临时数据,如果这些数据不可用,则将重新构建这些数据,而用户不会感觉到任何损失。这两个目录可以是磁盘上的同一个目录。在企业环境或用户经常在计算机之间切换的其他情况下,根目录旨在位于所有计算机都可以访问的网络位置,而本地目录可以是计算机的本地目录。

配置文件服务维护一个命名用户配置文件数据库,可以通过命令行或基本用户界面从中进行选择。此外,还存在命令行参数,可以使用任何给定的目录运行应用程序作为用户配置文件。

偏好设置

偏好设置服务是用户设置的基本键值存储。键是简单的字符串,尽管通常被认为是分层结构,各部分由句点分隔,但内部所有内容都只是作为平面列表保存。偏好设置值可以是字符串、整数或布尔值。

阅读更多

观察者服务

观察者服务 (nsIObserverService) 是一个进程全局的 XPCOM 服务,充当通用消息总线,实现 发布-订阅模式。实现 nsIObserver(或 JavaScript 中的简单函数)的组件可以注册到观察者服务,以便在发生特定“主题”(主题只是开发者定义的字符串)时收到通知。这对于在两个组件之间创建依赖关系而不紧密耦合它们特别有用。

例如,假设有一种机制可以从磁盘和内存中清除用户的浏览历史记录。在此过程结束时,它可能会告诉观察者服务在“browser-clear-history”等主题上发出通知。注册了该主题的观察者可能会使用该信号来知道清除其某些缓存,这些缓存也可能包含浏览历史记录。

主体/安全模型

无论何时桌面版或 Android 版 Firefox 从 Web 获取资源,Firefox 都会执行各种 Web 安全检查。最突出的莫过于 同源策略,以确保网页无法通过执行恶意操作(例如访问本地文件系统)来危害最终用户。Firefox 中所有与 Web 相关的安全检查都是基于主体安全概念进行评估的,主体安全概念(简化后)表示一个来源。更准确地说,Firefox 使用以下四种主体类型之一捕获安全上下文

  • 内容主体(Content-Principal),反映网页内容(来源)的安全上下文。例如,访问https://example.com时,内容主体为https://example.com,反映了该来源的安全上下文,并且如果方案、主机和端口匹配则通过。

  • 空主体(Null-Principal),反映沙盒(或最小权限)安全上下文。例如,加载带有沙盒属性的 iframe 时,Firefox 内部会生成一个空主体来反映该安全上下文。空主体仅与其自身同源。

  • 系统主体(System-Principal),反映浏览器 chrome 代码的安全上下文,并通过所有安全检查。重要:如果要加载的 URI 可能受网页内容影响,切勿使用 SystemPrincipal。

  • 扩展主体(Expanded-Principal),是一个主体列表,用于匹配 Firefox 扩展程序中内容脚本的安全需求。

每当 Firefox 开始加载资源(例如脚本、css、图像)时,包含nsIPrincipal的安全相关元信息就会附加到nsILoadInfo中。此加载上下文提供对象会一直附加到资源加载(nsIChannel)上,贯穿整个资源加载生命周期,并允许 Firefox 提供相同安全保证,即使资源加载遇到服务器端重定向也是如此。

请阅读以下博文,了解 Firefox 安全模型的详细信息:理解 Firefox 中的 Web 安全检查(第一部分 & 第二部分)和在 Firefox 中默认实施内容安全

Chrome 协议

Chrome 协议是用于引用作为应用程序一部分提供的文件的内部协议。其格式为chrome://<package>/<provider>/…,其中 provider 是 content、skin 或 locale 之一。Chrome 协议引用的绝大多数文件存储在 omni.ja 文件中,这些文件是在构建时根据JAR 清单文件生成的。Chrome 清单文件用于注册不同包存储在 jar 文件中的位置。

资源协议

资源协议是另一个内部协议,可以引用作为应用程序一部分提供的文件。严格来说,它只是一个映射,所有格式为resource://<package>/…的 URL 都映射到<new-uri>/…。这些映射通常使用Chrome 清单文件中的资源指令定义,但也可以在运行时定义,以及一些硬编码的映射。常见示例包括

  • resource://gre/…,引用 gecko omni.ja 文件中的文件。

  • resource://app/…,通常简化为resource:///…,引用应用程序 omni.ja 文件中的文件。

关于页面/协议

about协议允许将简短易读的 URL 绑定到要显示在内容区域中的内部内容。在大多数情况下,每个关于页面只是 chrome 或资源协议中内容的更简单的名称。例如,页面about:processes只需加载chrome://global/content/aboutProcesses.html。关于页面在全局桌面重定向组件中注册。

工具包

工具包由可以在构建在 Gecko 之上的多个应用程序之间共享的组件组成。例如,我们的许多 WebExtensions API 表面是在工具包中实现的,因为其中一些 API 在 Firefox、Firefox for Android 以及某些情况下 Thunderbird 之间共享。

阅读更多

代码风格检查/构建/测试/开发工作流程

使用贡献者快速参考设置构建环境。

了解代码风格检查设置,特别是如何运行代码风格检查器并在提交时自动运行代码风格检查器添加钩子。此外,确保使用适用于代码风格检查器的适当设置设置您的编辑器。对于 VS Code,这些设置会自动设置,如文档所述

对于前端工作,ESLint 和 Prettier 是您最常使用的代码风格检查器,请参阅关于 ESLint 的部分了解这两者的详细信息,其中还包含常见问题解答

有关自动化测试的详细信息,请参阅此处。最常用的测试是XPCShell(用于测试后端组件)、浏览器 Chrome 测试(用于测试前端 UI)和Web 平台测试(用于测试 Web API)。

WebExtensions

WebExtensions API 允许扩展与浏览器的其他部分交互。

阅读更多