# light-dom
**Repository Path**: fakis/light-dom
## Basic Information
- **Project Name**: light-dom
- **Description**: A lightweight, secure HTML DOM builder for PHP, with jQuery-style selectors and auto-escaping.
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-09-21
- **Last Updated**: 2026-09-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# LightDom
一个轻量、安全的 **HTML DOM 构建器**(PHP)。
用嵌套的 `Dom` 节点描述 HTML,自动输出经过正确转义、可靠的 HTML 字符串——附赠 jQuery 风格的选择器。
```php
use Fakis\LightDom\Dom;
echo Dom::render(
Dom::make('div#app.card[disabled]', ['data-id' => 1],
Dom::make('h1.title', 'Hello & "World"'),
Dom::trust('icon'), // 受信任,不会被转义
)
);
```
输出
```html
Hello & "World"
icon
```
## 特性
- **默认安全** — 文本节点和属性值均经过 HTML 转义(`ENT_QUOTES | ENT_HTML5`);只有 `Raw`(通过 `Dom::trust()` 创建)会绕过转义,再也不怕意外 XSS。
- **jQuery 风格选择器** — `div#id.classA.classB[attr=value][boolean-attr]` 一口气解析成 `Dom`;只写 `#id` 或 `.class` 时默认标签为 `div`。
- **可组合** — 每个节点就是一个纯 `Dom` 值对象(包含 `tag`、`attrs`、`children`),递归构建,任意子树独立渲染。
- **智能 `class` / `style` 处理** — 专用的 `Classes` 和 `Styles` 值对象,支持 attach / detach / patch 与自动去重,合并属性时不会丢失已有 class。
- **组件支持** — 把 `callable(Attrs, children): Dom` 当作选择器传入,即可构建可复用组件。
- **Packagist 就绪** — PSR-4 自动加载,PHP 8.1+,MIT 协议,PHPUnit + GitHub Actions CI。
## 安装
```bash
composer require fakis/light-dom
```
## 要求
- PHP **8.1+**
## 使用
### 选择器语法
| 选择器 | 生成的节点 |
|----------------------------------|----------------------------------------|
| `div` | `` |
| `#app` | `
` *(默认标签 = div)* |
| `.btn.large` | `
` |
| `a[href="/x"][target=_blank]` | `
` |
| `input[type=text][required]` | `` *(void 元素)* |
### 属性与子节点
```php
// 第一个额外参数若是关联数组,则视为属性
Dom::make('input', ['type' => 'text', 'value' => 'a&b']);
// 否则额外参数都是子节点
Dom::make('ul', Dom::make('li', 'one'), Dom::make('li', 'two'));
```
`class` 和 `style` 是**合并**而非替换:
```php
$attrs = new Attrs(['class' => 'a', 'style' => 'color:red']);
$attrs->attachClass('b c')->patchStyle('font-size:12px');
(string)$attrs; // class="a b c" style="color:red;font-size:12px;"
```
### 原始(受信任)HTML
```php
Dom::make('div', Dom::trust($userProvidedMarkup)); // 不会被转义
```
> `Dom::trust()` 仅用于你**完全信任**的内容。不可信输入**必须**作为普通字符串传入,将自动转义。
### 组件(可调用对象)
```php
$card = function (Attrs $attrs, array $children) {
return Dom::make('section.card', $attrs, ...$children);
};
Dom::make($card, ['data-x' => 1], Dom::make('p', 'body'));
```
### 全局辅助函数
```php
echo dom('div#x.btn', 'Hi')->render(); // 等同于 Dom::make(...)
$attrs = attrs_merge(['class' => 'a', 'style' => 'color:red'], ['class' => 'b c']);
$classes = classes_attach('a b', 'd x');
$classes = classes_detach('a b', 'b c x');
$styles = styles_patch('display: none', 'font-size:12px', ['display' => 'block']);
```
## 架构
```
src/
├── Dom/ # PSR-4 命名空间 Fakis\LightDom
│ ├── Classes.php # class 属性集合(规范化、attach、detach)
│ ├── Styles.php # style 属性集合(规范化、patch)
│ ├── Attrs.php # 通用属性容器(委托给 class 与 style)
│ ├── Raw.php # 标记:受信任、不转义的 HTML
│ └── Dom.php # Dom 工厂方法、选择器解析、渲染器
└── helpers.php # 全局 dom() 函数(autoload.files)
```
| 类 | 职责 |
|-----------|------------------------------------------------------|
| `Classes` | 规范化 / 去重 / attach / detach CSS 类名 |
| `Styles` | 规范化 / 合并 CSS 声明 |
| `Attrs` | 统一的属性包;委托处理 `class` 与 `style` |
| `Raw` | `readonly` 标记:选择不转义 |
| `Dom` | 不可变 DOM 节点 + `make()` + `render()` + 选择器解析 |
## 开发
```bash
composer install
composer test # 运行 PHPUnit
composer cs-check # PSR-12 代码风格检查
composer cs-fix # 自动修复
```
## 安全
所有动态内容默认都被转义。唯一的安全入口是 `Dom::trust()` / `Raw`,它被有意设计得非常显式,方便做 XSS 审查。
## 协议
MIT — 见 [LICENSE](LICENSE)。