# 控件：这一行上有什么

[← 返回 README](../README.md) · [文档索引](./index.md)

表头只留两个常驻入口 + 一个菜单：**[拾取元素] [查找] [文件下拉] [更多操作]**。
表头右侧另有一个**开关胶囊**。

原来的六个控件一行放不下，所以除了留在手边的拾取器，其余折进了菜单
（菜单用的就是文件下拉那套 chrome）。「历史版本」是**菜单里的第二页**（不关菜单，就地翻页），
左上角有「返回」。

---

## 控件一览

| 控件 | 行为 |
| --- | --- |
| 拾取元素 | 在界面里点选一个元素，把它写成一条规则（[详见](./picker.md)）。武装期间按钮变成「取消拾取」，`Esc` 等效 |
| 查找 | 打开表头的**查找栏**（`Ctrl+F` 等效）：查找 / 替换为 / 命中计数 / 区分大小写 / 上一个 / 下一个 / 替换 / 全部替换 / 关闭。栏打开时按钮变成「关闭查找」。命中在彩色层里圈出、当前那条更重；**`Aa` 按下去有明显样式**（品牌色文字 + 按下态底色），状态一眼可辨 |
| 大纲（文件栏右侧） | 整张表的**顶层规则**按顺序列出，每条后面跟着它**在当前页面命中几个元素**（`无命中` 就是那条规则什么都没做）。点一下就跳到那条规则并打开它的面板 |
| 强调显示（规则面板里，选择器字段右侧） | 见下一节 |
| 文件选择器 | DSH 原生样式的下拉（触发按钮 + 弹出菜单，**不是**原生 `<select>`）：列出目录里全部 `.css`，当前项带勾选；切换即写回 `active.json` 并立刻换用该文件。**最下面一项是「＋ 新建…」** |
| ＋ 新建… | 选中后行内出现文件名输入框（`Enter` 创建 / `Esc` 取消），创建空文件并切换过去；重名返回「已存在」 |
| 打开文件 | 用**系统默认程序**打开当前选中的那个文件（浏览器的文件对话框只能选文件、不能「打开」，所以由 host 侧 `POST /open` 调起系统关联程序），适合在真正的编辑器里改 |
| 导入 | 用文件对话框从磁盘选一个 `.css`，其内容复制为目录里的新文件并切换过去；同名自动加 `-2`、`-3` 后缀，**绝不静默覆盖** |
| 导出 | 把当前样式表另存为文件：优先用 File System Access 的「另存为」选择器指定位置，不支持时回退为浏览器下载 |
| 格式化 | 把整张表重排（[规则见编辑器](./editor.md#格式化)）。已经排好的表上这一项置灰 |
| 令牌管理 | 「更多操作」菜单里的**第四页**（规划中）：把 DSH 与其它扩展的 `--*` 令牌列出来，标来源与用量，可接管覆盖。见 [令牌管理](./token-manager.md) |
| 问题检测 | 「更多操作」菜单里的**第二页**：命不中的规则可逐条注释；透明与定位、动效与性能两节可逐条跳转。见 [编辑器](./editor.md#问题检测) |
| 历史版本 | 「更多操作」菜单里的**第三页**：把当前这张表留在磁盘上的版本按时间倒序列出来，点一条就恢复。恢复前会先把被替换的内容也留一份快照，所以**恢复本身也可以反悔** |
| 重置 | 清空当前文件内容（移除注入的样式；**文件本身保留**）。语义是破坏性的，用错误色与其他控件区分（`--dsw-alias-state-error-primary`）。放在菜单**最后**正是因为这个 |
| 开关胶囊（容器表头右侧） | **临时停用当前样式表** —— 样式不再注入页面，而文件内容、当前选择、校验状态全都不动。状态写进 `active.json` 的 `disabled` 列表，因此**多个浏览器与重启后一致** |

> 「导入」是复制而不是链接原文件：浏览器出于安全不会把所选文件的完整路径交给页面。
> 原文件不受影响；要反复编辑同一份文件，请用「打开文件」。

## 窄窗口下谁先让位

表头挤不下时按顺序让步，**控件不会消失**：

1. 查找栏里先隐去命中计数（640px 以下）
2. 再让 `替换` / `全部替换` 换成 ↦ / ⇉（540px 以下）

阈值取在**仍有富余处**，是实测量出来的，不是拍的（见 [已知坑](./known-issues.md) 那条
「一行放不下就换行，而换行不报错」）。

---

## 强调显示：三种看起来都像 0 的情况

那个数字正是用来判断选择器写没写对的，所以三种情况必须分开说：

| 情况 | 例子 | 按钮显示 |
| --- | --- | --- |
| 选择器合法，但页面上没有 | `.cm-peak-strip`（这个类在 DSH 里不存在） | `无命中`（禁用） |
| 这根本不是选择器 | `@media (max-width: 600px)` —— at-rule，`querySelectorAll` 抛 SyntaxError 而不是返回空 | `不是选择器`（禁用） |
| 规则写在**伪元素**上 | `a::before`、`:before` | `伪元素`（禁用） |

第三种值得说明：`a::before` 匹配不到任何**元素**，所以报「0 个命中」技术上没错，
但等于告诉用户**选择器写坏了** —— 实际是它**无法被框选**，
而且这个说法还藏掉了有用的那半答案（宿主元素是命中的）。

### 它做什么，不做什么

- 页面上所有匹配该选择器的元素都被**框出来**：琥珀色描边；
  **只有一个匹配时用 2px 并且不填充** —— 一个的时候没有「彼此区分」的需要，
  而一整块色会盖住你正在看的内容。
- 按钮上直接写命中数，因为那正是看这个字段的人想知道的。
- **只读不改页面**：框浮在最上层、`pointer-events:none`、不压暗也不拦截点击。
- **面板关掉后强调继续留着** —— 这个功能的目的就是看页面，而面板正压在被看的东西上面。
  关掉整个设置则清干净。

## 相关

- [元素拾取器](./picker.md) —— 拾取按钮的完整行为
- [规则面板](./rule-panel.md) —— 强调显示所在的面板
- [API](./api-host.md) —— 文件下拉 / 新建 / 导入导出背后的接口
