poxk/Falco

GitHub: poxk/Falco

用 Rust 从零编写的轻量级浏览器引擎,支持将网页渲染为 PNG 或实时交互窗口。

Stars: 52 | Forks: 8

Falco logo

Falco

Logo 由 Sanya 设计 — t.me/SanyochekDev

一个使用 Rust 编写的轻量级、极速浏览器引擎。
支持渲染 HTML、CSS、JavaScript、SVG 和图像 — 输出为 PNG,或显示为实时交互窗口。

License: MIT Built with Rust Binary size Lines of Rust CI Donate

快速开始 · 交互模式 · 功能 · 架构 · 贡献

## 项目简介 Falco 是一个真正的浏览器引擎,仅用约 **36,000 行 Rust** 代码编写。它 解析 HTML、应用 CSS、执行 JavaScript、加载图像、计算 布局,并绘制到 canvas 上 — 可以输出为 **PNG 文件**,或者是一个实时 **交互窗口**,你可以在其中滚动、点击链接、填写 表单以及进行导航。 ``` HTML ──▶ DOM ──▶ Style tree ──▶ Layout tree ──▶ Paint commands ──▶ Canvas ──▶ PNG / Window ▲ ▲ ▲ │ │ │ HTML5 tokenizer CSS cascade Flex / Grid / Table / Float / Absolute + tree builder + Selectors 4 + Inline / Block flow │ JS (custom VM with closures, generators, Promise, BigInt, Symbol) │ Image loader ──▶ HTTP / data: URL / local file ``` Falco **并不是**对 WebKit、Gecko 或 Chromium 的简单封装。每个 模块 — HTML tokenizer、CSS parser、layout engine、JS VM、字体 rasterizer、PNG encoder — 都是完全从零开始使用 Rust 编写的。 ## 现状声明(可用功能 vs 桩代码) 为了明确预期 — 这是 v0.1.0 版本,是由 个人开发者发布的早期版本。本 README 中列出的所有内容并不都是生产环境可用的。 以下是实际已接入渲染管线的内容,以及 结构上已完成但尚未被调用的内容: ### ✅ 实际工作(由 `render_with_base_url` 调用) - HTML parser (`html/`) — 旧版 parser,不完全符合规范但功能正常 - DOM 类型 (`dom/`) — 最简节点类型,无 observers/shadow - CSS parser (`css/`) — selectors、properties、cascade、color parsing - Style cascade (`style/`) — UA styles + inheritance + flex/grid props - Layout (`layout/`) — block / inline / flex / **CSS Grid** / **table** / float / absolute - Painting (`paint/`) — fonts (ab_glyph)、gradients、shadows、alpha compositing - SVG renderer (`svg/`) — paths、基本形状、gradients、stroke + fill - 手写的 PNG encoder (`png/`) - Image loader (`image/`) — HTTP、data: URLs、本地文件 - JS VM (`tjs/`) — bytecode interpreter + JIT (x86_64,仅限 Linux) - JS-DOM bindings (`js_tjs/`, `js_runner/`) — `document.getElementById`、`console.log`、`alert`、`onclick` - Networking (`net/`) — HTTP/1.1 (ureq)、cookies、cache、websocket、redirect - 交互式 `--window` 模式 — scrolling、forms、navigation、history ### ⚠️ 结构完整,通过自身的单元测试,**但尚未接入 renderer** 这些作为符合规范的替代模块,用于替换旧有模块。它们 可以编译并具有自己的单元测试,但 `render_with_base_url` 目前还没有 调用它们。这是 v0.2.0 的目标。 - `html::spec` — WHATWG §13.2 tokenizer(全部 80 个状态)+ tree builder(全部 22 种插入模式)+ serializer + XML parser + encoding detection - `dom::spec` — 符合规范的 DOM,包含 MutationObserver、Shadow DOM、custom elements、accessibility tree - `css::spec` — Selectors Level 4 (`:has()`、`:is()`、`:where()`、cascade layers、container queries) - `tjs_ext/` — Symbol、BigInt、Promise、microtasks、Map/Set、WeakMap/WeakSet、Reflect ### ⚠️ 已实现的算法,**但未在 renderer 中强制执行** - `security/` — SOP、多进程、seccomp sandbox、CSP、TLS cert chain validation、permissions、extensions、DevTools protocol。所有算法都已就位并经过单元测试,但 renderer 尚未强制执行它们。 - `web_runtime/` — `fetch()`、`XMLHttpRequest`、event loop、Promise。Promise / event loop 集成是真实的并经过了单元测试,但 `fetch` 和 `XHR` 是桩代码(在 JS 环境中背后没有真实的网络请求)。WebGL、video、MSE、EME、NDSD 是 **headless stubs** — 它们实现了 API 表面,但并不会实际渲染 WebGL 帧、解码 H.264 视频或执行 DRM。它们作为未来工作的脚手架而存在。 - `media/` — `@media` 查询会被解析,但总是被应用(目前还没有条件级联)。 ### ❌ 已知损坏 / 未完成 - `real-http2`、`real-webgl`、`sandbox` Cargo features 在使用 `--all-features` 编译时会失败,因为它们的上游 API 发生了偏移(`h2::Body` 被移除、glow API 更改、seccomp pre_exec 仅限 Unix)。它们默认是禁用的,并且 CI clippy 步骤不会检查它们。 - JIT (`tjs/jit.rs`) 可以在 Linux x86_64 上运行,但在 macOS CI 运行器上会失败,因为 `mmap(MAP_JIT)` 需要带有 `com.apple.security.cs.allow-jit` 权限的代码签名。macOS 上的 JIT 测试被标记为 `#[ignore]`。 - 来自 JS 的 DOM 变更(`element.innerHTML = ...`、`element.style.color = ...`)不会触发重新渲染。 - 符合 HTML5 规范的 tree repair(adoption agency、foster parenting)位于 `html/spec/tree_builder.rs` 中,但实际运行的是旧版的 parser。 **总结:** 如果你运行 `cargo build && ./falco https://example.com --out out.png`,你会得到一张真实的 PNG 渲染图。HTML/CSS/layout/paint 路径已经能够进行端到端的工作。符合规范的 parsers、安全强制执行以及高级 Web 运行时(WebGL/video/DRM)是 **未来里程碑的脚手架**,而不是已实现的功能。在声称其他情况之前,请先阅读代码。 ## 快速开始 ``` # 构建(发布二进制文件位于 target/release/falco) cargo build --release # 将本地 HTML 文件渲染为 PNG ./target/release/falco page.html --out page.png --width 1200 # 将 URL 渲染为 PNG ./target/release/falco https://example.com --out example.png --width 800 # 打开交互式实时窗口(仅限桌面版 — 支持滚动、悬停、链接点击) ./target/release/falco page.html --window # 使用合并在