/**
* 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 插件/样式生效,例如行号、括号高亮等)。
关键点逐步说明
- 构造器和初始化
- constructor(element = null)
- 接收一个 HTMLElement 或 Document(如果不传则默认 document),并立即调用 init()。
- init()
- 先尝试应用 Prism 主题(见下)。
- 然后判断传入的根节点(root)是否包含 .code-view-wrapper:如果包含则直接 return,不对这些页面干预(因为 code-explorer.js 会处理)。
- 否则调用 _prismOnAll() 对页面上的所有代码块进行处理与高亮。
- 主题应用:_applyPrismTheme()
- 首先检查全局变量 Prism 是否存在(如果没有就直接返回,不报错)。
- 查找 id 为 prism_theme 的元素(通常是)。
- 如果该元素不存在或已经有 href(说明已设置过),则不再改动。
- 否则根据用户的配色偏好(window.matchMedia('(prefers-color-scheme: dark)'))选择对应的 CSS 文件:
- 深色模式 -> prism-tomorrow-night.css
- 浅色模式 -> prism-light.css
- 将选中的样式表 URL 赋给该 link 元素的 href,从而动态切换 Prism 的主题样式。
- 为页面中所有代码块运行 Prism:_prismOnAll()
- 也会先检查 Prism 是否已定义。
- 在 this.element(通常是 document)中查找所有的 'pre code' 节点,对每个 code 节点:
- 调用 _decoratePre(block.parentNode, i) 给对应的
做装饰(添加 id、class、data-line 等)。
- 调用 Prism.highlightElement(block) 对该
元素执行 Prism 的语法高亮。
- 调用 _decoratePre(block.parentNode, i) 给对应的
装饰:_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 来进行高亮,同时动态设置主题样式以响应深/浅色偏好。
评论加载中...