架构概述

由于 Mozilla 过去曾经发布过一个名为 XULRunner 的框架,因此 Places 被拆分为工具包和浏览器两个部分。工具包部分通常由与产品无关的 API 组成,这些 API 可以被任何类型的项目使用,而不仅仅是 Web 浏览器。浏览器部分包含特定于 Firefox 浏览器的代码。

代码库

大部分代码库是用以下语言编写的:
  • JavaScript

  • C++(例如,数据库初始化代码或部分访问跟踪代码)。

前端

书签体验的前端部分包括各种视图:

所有视图共享一个通用的 控制器,负责处理视图所需的各种操作和命令。每个视图创建一个 Result 对象并接收有关其更改的通知。

例如,从视图中删除书签将调用控制器,控制器再调用 PlacesTransactions 来实际执行删除操作。删除操作将通知一个 Places 事件,该事件由 Result 捕获,Result 将立即更新其书签树的内部表示。然后,Result 向视图发送一个通知,视图将处理该通知并更新用户看到的界面。该系统根据经典的 模型-视图-控制器 模式工作。

前端对话框和面板使用 xhtml 和 shadow DOM 编写。特别是书签对话框是围绕一个通用模板的包装器,editBookmarkPanel.inc.xhtml,它可以像对象一样扩展或重载(覆盖,类似于 Web 组件)。

编辑书签覆盖层的大部分逻辑位于通用脚本 editBookmark.js 中。

前端结构

大部分前端代码位于:Browser/Components/Places/Content

  • BookmarkProperties、BookmarkProperties.xhtml - 负责编辑书签和新建书签对话框。面板根据作为 window.arguments[0] 传递的 js 对象中的数据进行初始化。如果对话框被接受,则 Window.arguments[0] 将设置为项目的 guid。

  • BookmarksHistoyTooltip.xhtml - 负责工具提示的代码

  • BookmarksSidebar、bookmarksSidebar.xhtml - 负责侧边栏窗口的代码。搜索现有书签树以查找所需的书签。

  • BrowserPlacesViews - 控制大多数视图(菜单、面板、工具箱)。基本视图实现了工具栏和菜单视图的共有功能。

  • Controller - 所有 Places 视图共享的控制器。连接 UI 和实际操作。

  • EditBookmark、editBookmarkPanel.inc.xhtml - 控制编辑书签面板。观察书签的更改并将所有 UI 操作与后端连接。

  • HistorySidebar、historySidebar.xhtml - 负责历史记录侧边栏窗口的代码。搜索现有树以查找请求的历史记录。

  • Places-menupopup - Places 菜单的自定义元素定义

  • Places-tree - 类 MozPlacesTree - 为 Places 树构建自定义元素定义。这将加载到所有 XUL 窗口中。必须将其包装在一个块中以防止泄漏到窗口范围。

  • Places.css、places.js、places.xhtml - 负责库窗口

  • PlacesCommands.inc.xhtml - 多个窗口的命令

  • PlacesContextMenu.inc.xhtml - 上下文菜单的定义

  • TreeView - 树视图的实现

后端

由于用户在前端执行的任何书签操作都是可撤销的,因此 Firefox 通常不会直接调用书签/历史记录 API,而是通过一个名为 PlacesTransactions 的包装器进行调用。

此模块的范围是将书签更改请求转换为操作描述符,并将它们存储在日志中。当用户修改书签时,PlacesTransactions 会将书签之前的状态存储在日志中;如果用户在库窗口中选择撤消(或 CTRL+Z),则可以恢复该状态。这可以防止用户意外删除书签时造成数据丢失。

工具包 Places 还提供了一种通过 Results 查询书签的方法。这是代码库中最古老的部分之一,未来可能会重写。它使用 XPCOM(跨平台组件对象模型),这是一种 Mozilla 技术,允许 C++ 和 Javascript 进行通信。这是一个声明式系统,其中接口必须在 XPIDL 文件中定义和记录。实际上,所有可用方法和属性都记录在 nsINavHistoryService.idl 中。查询书签将返回一个 nsINavHistoryResult 对象,该对象具有根节点。根节点具有表示书签或文件夹的子节点。它像一棵树一样工作,必须打开容器,然后才能检查其子节点。这是大多数 Firefox 前端书签视图使用的基础。

后端结构

大部分后端代码位于:Toolkit/Components/Places

存储

Places 使用 SQLite(一个具有稳定、跨平台和向后兼容文件格式的 C 语言库)作为其数据存储后端。所有数据都包含在漫游 Firefox 配置文件文件夹中的 places.sqlite 文件中。数据库通过名为 mozStorage 的 SQLite 库包装器进行访问。为了存储我们的收藏夹图标,我们使用 favicons.sqlite,它表示附加到 places.sqlite。这使得更容易将我们两个独立的 sqlite 用作一个数据库。

同步

Places 与 Firefox Sync 密切配合,以便跨设备同步书签和历史记录,因此您可以在 Places 代码库的各个部分中遇到 Sync 特定的代码。一些代码可能指的是 Weave,这是 Sync 的旧项目名称。