/**
 * CodeArea — 代码块渲染模块(Prism.js)
 *
 * 职责:
 *  - 在代码浏览页(含 .code-view-wrapper):不做任何事,由 code-explorer.js 负责。
 *  - 在其他页面(文章、README 等):用 Prism.js 高亮所有 pre code 块。
 *
 * Monaco / 代码浏览模块的入口在 monaco-editor.js + code-explorer.js 中。
 */

export class CodeArea {

    /**
     * @param {HTMLElement|Document} element
     */
    constructor(element = null) {
        this.element = element || document;
        this.init();
    }

    init() {
        this._applyPrismTheme();

        // 代码浏览模块页面由 CodeExplorer 负责渲染,这里不介入
        const root = (typeof this.element.querySelector === 'function') ? this.element : document;
        if (root.querySelector('.code-view-wrapper')) return;

        // 其他页面(文章、README 等):用 Prism 高亮所有代码块
        this._prismOnAll();
    }

    // ------------------------------------------------------------------ Prism

    _applyPrismTheme() {
        if (typeof Prism === 'undefined') return;
        const el = document.getElementById('prism_theme');
        if (!el || el.href) return;
        el.href = window.matchMedia('(prefers-color-scheme: dark)').matches
            ? 'https://dpangzi.com/library/prism/prism-tomorrow-night.css'
            : 'https://dpangzi.com/library/prism/prism-light.css';
    }

    /** 对页面内所有 pre code 运行 Prism(文章 / 其他模块) */
    _prismOnAll() {
        if (typeof Prism === 'undefined') return;
        this.element.querySelectorAll('pre code').forEach((block, i) => {
            this._decoratePre(block.parentNode, i);
            Prism.highlightElement(block);
        });
    }

    _decoratePre(pre, index) {
        if (!pre.id) pre.id = `code-block-${index}`;
        ['rainbow-braces', 'match-braces', 'line-numbers', 'linkable-line-numbers'].forEach(cls => {
            if (!pre.classList.contains(cls)) pre.classList.add(cls);
        });
        if (!pre.hasAttribute('data-line')) pre.setAttribute('data-line', '');
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这段代码实现了一个“代码块渲染/高亮”模块(基于 Prism.js),类名为 CodeArea。总体作用和行为可以概括为:

总体职责

  • 在“代码浏览页”(页面中存在 .code-view-wrapper 元素)不做任何高亮处理——这些页面由别的模块(monaco-editor.js / code-explorer.js)负责。
  • 在其它页面(文章、README 等)查找页面中的所有
    块,使用 Prism.js 高亮并给
     做一些装饰(方便 Prism 插件/样式生效,例如行号、括号高亮等)。

关键点逐步说明

  1. 构造器和初始化
  • constructor(element = null)
    • 接收一个 HTMLElement 或 Document(如果不传则默认 document),并立即调用 init()。
  • init()
    • 先尝试应用 Prism 主题(见下)。
    • 然后判断传入的根节点(root)是否包含 .code-view-wrapper:如果包含则直接 return,不对这些页面干预(因为 code-explorer.js 会处理)。
    • 否则调用 _prismOnAll() 对页面上的所有代码块进行处理与高亮。
  1. 主题应用:_applyPrismTheme()
  • 首先检查全局变量 Prism 是否存在(如果没有就直接返回,不报错)。
  • 查找 id 为 prism_theme 的元素(通常是)。
  • 如果该元素不存在或已经有 href(说明已设置过),则不再改动。
  • 否则根据用户的配色偏好(window.matchMedia('(prefers-color-scheme: dark)'))选择对应的 CSS 文件:
    • 深色模式 -> prism-tomorrow-night.css
    • 浅色模式 -> prism-light.css
  • 将选中的样式表 URL 赋给该 link 元素的 href,从而动态切换 Prism 的主题样式。
  1. 为页面中所有代码块运行 Prism:_prismOnAll()
  • 也会先检查 Prism 是否已定义。
  • 在 this.element(通常是 document)中查找所有的 'pre code' 节点,对每个 code 节点:
    • 调用 _decoratePre(block.parentNode, i) 给对应的
       做装饰(添加 id、class、data-line 等)。
    • 调用 Prism.highlightElement(block) 对该 元素执行 Prism 的语法高亮。
  1.  装饰:_decoratePre(pre, index)
    
  • 如果
     没有 id,会自动设置 id 为 code-block-{index}(index 为查询到的顺序)。
  • 确保
     含有这些 class(若不存在则添加):'rainbow-braces', 'match-braces', 'line-numbers', 'linkable-line-numbers'。这些 class 一般对应 Prism 的插件或自定义样式(例如括号高亮、行号、可链接行号等)。
  • 如果没有 data-line 属性,则添加 data-line=""(Prism 的行号/高亮插件可能使用这个属性来支持按行高亮等功能)。

容错与边界

  • 如果全局 Prism 未加载(Prism 未定义),代码不会抛错,只是跳过主题设置和高亮步骤。
  • 在有 .code-view-wrapper 的页面完全不干预,避免与代码浏览/Monaco 编辑器模块冲突。

总结

  • CodeArea 是一个轻量的 Prism 高亮协调器:根据页面类型决定是否启用,对
     进行装饰并调用 Prism.highlightElement 来进行高亮,同时动态设置主题样式以响应深/浅色偏好。
评论加载中...