FIT2CLOUD
代码折叠增强 的图标

代码折叠增强

1,138
574

自动折叠长代码块和长图片,高度可以自行配置

PluginCodeEnhance

Halo 博客平台的代码折叠增强插件,专注提供代码块折叠长图折叠功能,轻量高效,无外部依赖。

我的博客:代码折叠增强插件 — PluginCodeEnhance


✨ 功能特性

  • 代码折叠:自动检测长代码块,超过指定行数自动折叠,支持展开/收起
  • 长图折叠:自动折叠超过指定高度的图片,优化文章排版
  • 懒加载兼容:支持 data-srcdata-originaldata-lazy 等懒加载属性
  • 展开态 sticky 按钮:长代码时展开按钮固定在视口底部,方便操作
  • 横向滚动:超长代码行自动横向滚动,不撑破布局
  • 暗色模式:通过 CSS 变量自动适配 Halo 暗色主题
  • 无障碍支持:完整的 ARIA 属性支持(aria-labelaria-expanded:focus-visible
  • 移动端适配:按钮尺寸优化,触摸友好
  • 性能优化:使用 IntersectionObserver 延迟初始化,文件大小仅 8KB(减少 97%)
  • pjax 兼容:自动监听 pjax:complete 事件,支持 Halo 默认主题的 pjax 路由切换

📦 安装方法

方法一:手动安装

  1. 下载最新版本的插件 JAR 文件(plugin-codeenhance-x.x.x.jar
  2. 登录 Halo 管理后台
  3. 进入「插件管理」→「安装插件」
  4. 选择下载的 JAR 文件上传安装
  5. 安装完成后启用插件

方法二:构建安装

# 克隆仓库
git clone https://github.com/NoEggEgg/plugin-code-enhance.git
cd plugin-code-enhance

# 构建插件
./gradlew build -x test

# 构建产物位于 build/libs/plugin-codeenhance-x.x.x.jar

⚙️ 配置选项

插件安装后,可在 Halo 管理后台进行配置:

配置项 说明 默认值
enableCodeFold 是否启用代码折叠 true
codeFoldLine 代码折叠阈值(行数) 20
enableImgFold 是否启用长图折叠 true
imgFoldHeight 图片折叠阈值(像素) 400

说明:自 v2.0.0 起,所有功能默认启用。代码折叠和长图折叠独立控制,互不影响。


🚀 使用说明

插件安装启用后,会自动对文章和页面中的代码块和图片进行处理:

适用范围:支持文章(post)、页面(page),以及 Moments、Docsme 插件页面。

代码折叠

当代码块行数超过 codeFoldLine(默认 20 行)时,自动折叠:

  • 折叠态:显示前 N 行代码(可预览),底部显示「展开代码 ▼」按钮
  • 展开态:显示完整代码,底部显示「折叠代码 ▲」按钮(sticky 固定在视口底部)
  • 横向滚动:超长代码行自动横向滚动

长图折叠

当图片高度超过 imgFoldHeight(默认 400px)时,自动折叠:

  • 折叠态:显示图片顶部 400px,底部显示「展开图片 ▼」按钮
  • 展开态:显示完整图片,底部显示「折叠图片 ▲」按钮(sticky 固定在视口底部)
  • SVG 图片:自动跳过(矢量图不适合折叠)

🛠️ 技术栈

  • Halo:>=2.20.0
  • Java:21
  • Gradle:8.5
  • 前端:原生 JavaScript(无框架)+ CSS 变量

📁 项目结构

plugin-code-enhance/
├── src/main/java/run/halo/codeenhance/
│   ├── CodeEnhancePlugin.java        # 插件主类
│   └── CodeEnhanceHeadProcessor.java # 扩展点实现(资源注入)
├── src/main/resources/
│   ├── extensions/
│   │   └── settings.yaml             # 设置表单定义
│   ├── static/
│   │   ├── js/
│   │   │   └── code-enhance.js       # 前端核心逻辑(~270 行)
│   │   └── styles/
│   │       └── code-enhance.css      # 插件样式(~220 行)
│   └── plugin.yaml                   # 插件元数据
├── .gitignore                        # Git 忽略规则
├── build.gradle                      # Gradle 配置
└── README.md                         # 项目说明

🔧 核心实现

后端实现

插件使用 Halo 2.x 的扩展点机制,通过 TemplateHeadProcessor 向页面注入前端资源:

@Component
@Order(-100)
public class CodeEnhanceHeadProcessor implements TemplateHeadProcessor {
    @Override
    public Mono<Void> process(ITemplateContext context, IModel model,
                              IElementModelStructureHandler handler) {
        // 从配置读取启用的功能
        // 只有折叠或长图折叠启用时才注入资源
        return fetcher.fetch("basic", BasicConfig.class)
            .defaultIfEmpty(new BasicConfig())
            .filter(BasicConfig::hasAny)
            .doOnNext(cfg -> inject(context, model, cfg))
            .then();
    }
}

前端实现

前端采用简洁的单文件设计,核心逻辑约 270 行:

  • 配置读取:从 window.CodeEnhanceConfig 读取用户配置
  • 懒加载观察:使用 IntersectionObserver 延迟处理,提升性能
  • 代码折叠:计算行数,超过阈值时创建包装容器并添加按钮
  • 长图折叠:监听 load 事件,获取图片真实尺寸后判断是否需要折叠
  • 懒加载兼容:检测 data-src 等属性,触发真实资源加载

关键优化

  • 无外部依赖(不依赖 hljs、jQuery 等),JS 约 23KB
  • 使用 CSS 变量管理配色,自动适配暗色主题
  • 分状态定位:折叠态 absolute 锚定容器底部中央,展开态 sticky 粘视口底部(被 overflow 阻断时以 overflow:clip 修复或降级 absolute,按钮永不脱离容器)
  • 完整 ARIA 支持,提升无障碍体验

📄 许可证

This project is licensed under the GPL-3.0 License - see the LICENSE file for details.


🔗 链接


讨论(0)

这是一个开源应用,我们推荐优先在开源仓库中提交 issue,以便开发者更好地接收和跟进问题。

去提交 issue