mirror of https://github.com/layui/layui
feat(code): 新增行高亮功能 (#2763)
* feat(code): 新增行高亮功能 支持行高亮,聚焦,diff,自定义行高亮 * update code * chore: 优化变量命名 * docs(code): 更新文档 * test(code): 添加行高亮测试用例 * docs(code): 优化 highlightLine 文档 --------- Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>main
parent
af6ba6c972
commit
fd78240b53
|
@ -11,13 +11,13 @@
|
||||||
<th>描述</th>
|
<th>描述</th>
|
||||||
<th>类型</th>
|
<th>类型</th>
|
||||||
<th>默认值</th>
|
<th>默认值</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>elem</td>
|
<td>elem</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
绑定元素选择器或 DOM 对象
|
绑定元素选择器或 DOM 对象
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -37,11 +37,11 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>preview <sup>2.8+</sup></td>
|
<td>preview <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
是否开启 Code 预览功能,可选值有:
|
是否开启 Code 预览功能,可选值有:
|
||||||
|
|
||||||
- `true` 开启 Code 的普通预览
|
- `true` 开启 Code 的普通预览
|
||||||
- `false` 关闭 Code 预览(默认)
|
- `false` 关闭 Code 预览(默认)
|
||||||
- `"iframe"` 开启 Code 在 iframe 模式中预览
|
- `"iframe"` 开启 Code 在 iframe 模式中预览
|
||||||
|
|
||||||
当开启该属性时,`elem` 指定的元素需要设置成以下结构:
|
当开启该属性时,`elem` 指定的元素需要设置成以下结构:
|
||||||
|
@ -65,13 +65,13 @@ code content
|
||||||
<tr>
|
<tr>
|
||||||
<td>layout <sup>2.8+</sup></td>
|
<td>layout <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
开启预览后的面板布局方式,值为一个数组,数组的可选成员有:
|
开启预览后的面板布局方式,值为一个数组,数组的可选成员有:
|
||||||
|
|
||||||
- `code` 代码区域
|
- `code` 代码区域
|
||||||
- `preview` 预览区域
|
- `preview` 预览区域
|
||||||
|
|
||||||
面板将根据数组的排列顺序来显示,如:
|
面板将根据数组的排列顺序来显示,如:
|
||||||
|
|
||||||
```
|
```
|
||||||
layout: ['code', 'preview']
|
layout: ['code', 'preview']
|
||||||
|
@ -84,7 +84,7 @@ layout: ['code', 'preview']
|
||||||
<tr>
|
<tr>
|
||||||
<td>style <sup>2.8+</sup></td>
|
<td>style <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
设置 Code 和预览区域的公共样式
|
设置 Code 和预览区域的公共样式
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -94,7 +94,7 @@ layout: ['code', 'preview']
|
||||||
<tr>
|
<tr>
|
||||||
<td>codeStyle <sup>2.8+</sup></td>
|
<td>codeStyle <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
设置 Code 区域的局部样式,优先级高于 `style` 属性
|
设置 Code 区域的局部样式,优先级高于 `style` 属性
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -104,7 +104,7 @@ layout: ['code', 'preview']
|
||||||
<tr>
|
<tr>
|
||||||
<td>previewStyle <sup>2.8+</sup></td>
|
<td>previewStyle <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
设置预览区域的局部样式,优先级高于 `style` 属性
|
设置预览区域的局部样式,优先级高于 `style` 属性
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -114,7 +114,7 @@ layout: ['code', 'preview']
|
||||||
<tr>
|
<tr>
|
||||||
<td>id <sup>2.8+</sup></td>
|
<td>id <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
设置实例的唯一索引,以便用于其他操作
|
设置实例的唯一索引,以便用于其他操作
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -124,7 +124,7 @@ layout: ['code', 'preview']
|
||||||
<tr>
|
<tr>
|
||||||
<td>className <sup>2.8+</sup></td>
|
<td>className <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
追加实例面板的 `className`,以便对其自定义样式
|
追加实例面板的 `className`,以便对其自定义样式
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -134,7 +134,7 @@ layout: ['code', 'preview']
|
||||||
<tr>
|
<tr>
|
||||||
<td>tools <sup>2.8+</sup></td>
|
<td>tools <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
用于开启 `preview` 属性后的面板头部右侧区域工具栏图标,值为一个数组,内置成员:
|
用于开启 `preview` 属性后的面板头部右侧区域工具栏图标,值为一个数组,内置成员:
|
||||||
|
|
||||||
- `copy` <sup>2.8.2+</sup> : 代码复制
|
- `copy` <sup>2.8.2+</sup> : 代码复制
|
||||||
|
@ -168,7 +168,7 @@ tools: [
|
||||||
<tr>
|
<tr>
|
||||||
<td>toolsEvent <sup>2.8+</sup></td>
|
<td>toolsEvent <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
点击工具栏的回调函数,功能同 `tools` 中的 `event`,只是需通过 `type` 属性来区分是哪个工具菜单。
|
点击工具栏的回调函数,功能同 `tools` 中的 `event`,只是需通过 `type` 属性来区分是哪个工具菜单。
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -187,7 +187,7 @@ toolsEvent: function(obj){
|
||||||
<tr>
|
<tr>
|
||||||
<td>copy <sup>2.8.2+</sup></td>
|
<td>copy <sup>2.8.2+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
用于开启代码复制功能图标。若开启 `priview`,则自动放置在 `tools` 属性中,复制图标将显示在容器右上角工具栏;若未开启 `priview`,则显示在 code 区域右上角。
|
用于开启代码复制功能图标。若开启 `priview`,则自动放置在 `tools` 属性中,复制图标将显示在容器右上角工具栏;若未开启 `priview`,则显示在 code 区域右上角。
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -201,7 +201,7 @@ toolsEvent: function(obj){
|
||||||
<tr>
|
<tr>
|
||||||
<td>text <sup>2.8+</sup></td>
|
<td>text <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
自定义默认文本,值为一个对象,可选成员有:
|
自定义默认文本,值为一个对象,可选成员有:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -218,7 +218,7 @@ text: {
|
||||||
<tr>
|
<tr>
|
||||||
<td>header <sup>2.8+</sup></td>
|
<td>header <sup>2.8+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
是否开启 Code 栏头部区域。
|
是否开启 Code 栏头部区域。
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -232,7 +232,7 @@ text: {
|
||||||
<tr>
|
<tr>
|
||||||
<td>ln</td>
|
<td>ln</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
是否显示 Code 区域的行号
|
是否显示 Code 区域的行号
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -246,7 +246,7 @@ text: {
|
||||||
<tr>
|
<tr>
|
||||||
<td>theme <sup>2.8.17+</sup></td>
|
<td>theme <sup>2.8.17+</sup></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Code 容器的主题风格,可选值有:
|
Code 容器的主题风格,可选值有:
|
||||||
|
|
||||||
- `light` 浅色模式(默认)
|
- `light` 浅色模式(默认)
|
||||||
|
@ -259,7 +259,7 @@ Code 容器的主题风格,可选值有:
|
||||||
<tr>
|
<tr>
|
||||||
<td>encode</td>
|
<td>encode</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
是否对 code 中的 html 进行编码(转义)。
|
是否对 code 中的 html 进行编码(转义)。
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
@ -358,7 +358,7 @@ code 组件语法高亮相关示例:
|
||||||
</td>
|
</td>
|
||||||
<td colspan="3">
|
<td colspan="3">
|
||||||
|
|
||||||
<div id="options.done" lay-pid="options" class="ws-anchor">
|
<div id="options.done" lay-pid="options" class="ws-anchor">
|
||||||
组件渲染完毕的回调函数,函数返回一个 object 类型参数
|
组件渲染完毕的回调函数,函数返回一个 object 类型参数
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ done: function(obj){
|
||||||
</td>
|
</td>
|
||||||
<td colspan="3">
|
<td colspan="3">
|
||||||
|
|
||||||
<div id="options.onCopy" lay-pid="options" class="ws-anchor">
|
<div id="options.onCopy" lay-pid="options" class="ws-anchor">
|
||||||
点击复制图标时的回调函数。
|
点击复制图标时的回调函数。
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -393,6 +393,49 @@ onCopy: function(code, copied){
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
[highlightLine](#options.highlightLine) <sup>2.12+</sup>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td colspan="3">
|
||||||
|
|
||||||
|
<div id="options.highlightLine" lay-pid="options" class="ws-anchor">
|
||||||
|
|
||||||
|
设置行高亮,可选项:
|
||||||
|
- `hl` : 高亮
|
||||||
|
- `++` : diff++
|
||||||
|
- `--` : diff--
|
||||||
|
- `focus` : 聚焦
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
可通过 `hl.range` 选项来设置行高亮范围:
|
||||||
|
|
||||||
|
```
|
||||||
|
highlightLine: {
|
||||||
|
hl: {
|
||||||
|
range: '1,3-5,8', // 指定行高亮范围 '1,3,4,5,8'
|
||||||
|
comment: true, // 是否解析行中的高亮注释
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
或通过特定注释格式: `[!code <type>:<lines>]` 指定行高亮范围,规则解释:
|
||||||
|
- `<type>` : `highlightLine` 的可选项,如 `h1, focus` 等
|
||||||
|
- `<lines>` : 行数(含本行)
|
||||||
|
|
||||||
|
```
|
||||||
|
111 聚焦 2 行(含本行) // [!code focus:2]
|
||||||
|
222 高亮本行 // [!code hl]
|
||||||
|
333
|
||||||
|
```
|
||||||
|
|
||||||
|
highlightLine 选项的详细用法可参考:<a href="https://stackblitz.com/edit/iw6hx7mi?file=index.html" rel="nofollow" target="_blank">highlightLine 行高亮在线示例</a>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -4,15 +4,16 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
<title>Code blocks adorn - Layui</title>
|
<title>Code blocks adorn - Layui</title>
|
||||||
|
|
||||||
<link href="../src/css/layui.css" rel="stylesheet">
|
<link href="../src/css/layui.css" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
body{padding: 32px;}
|
|
||||||
pre{margin: 16px 0;}
|
pre{margin: 16px 0;}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="layui-padding-3">
|
||||||
|
|
||||||
|
<div class="layui-text">
|
||||||
|
<h2>代码高亮</h2>
|
||||||
|
</div>
|
||||||
<pre id="test" class="layui-test">
|
<pre id="test" class="layui-test">
|
||||||
<textarea class="layui-hide">
|
<textarea class="layui-hide">
|
||||||
<div class="layui-btn-container">
|
<div class="layui-btn-container">
|
||||||
|
@ -54,6 +55,104 @@ Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
</textarea>
|
</textarea>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<div class="layui-text">
|
||||||
|
<h2>行高亮和聚焦</h2>
|
||||||
|
</div>
|
||||||
|
<pre
|
||||||
|
class="layui-code"
|
||||||
|
lay-options="{
|
||||||
|
highlightLine: {
|
||||||
|
hl: {
|
||||||
|
range: '1,3-5,8', // 指定行高亮范围 '1,3,4,5,8'
|
||||||
|
comment: true, // 是否解析行中的高亮注释
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
<textarea class="layui-hide">
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Quick Start - Layui</title>
|
||||||
|
<link href="//unpkg.com/layui@2.11.4/dist/css/layui.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- HTML Content -->
|
||||||
|
<script src="//unpkg.com/layui@2.11.4/dist/layui.js"></script>
|
||||||
|
<script>
|
||||||
|
// Usage // [!code focus:6]
|
||||||
|
layui.use(function(){
|
||||||
|
var layer = layui.layer;
|
||||||
|
// Welcome
|
||||||
|
layer.msg('Hello World', {icon: 6});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</textarea>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<div class="layui-text">
|
||||||
|
<h2>diff</h2>
|
||||||
|
</div>
|
||||||
|
<pre
|
||||||
|
class="layui-code"
|
||||||
|
lay-options="{
|
||||||
|
highlightLine: {
|
||||||
|
hl:{range: '38-40'},
|
||||||
|
'++':{comment: true},
|
||||||
|
'--':{comment: true}
|
||||||
|
}
|
||||||
|
}">
|
||||||
|
<textarea class="layui-hide">
|
||||||
|
<template id="test">
|
||||||
|
<p>转义输出:{{= d.desc }}</p>
|
||||||
|
<p>原文输出:{{- d.desc }}</p>
|
||||||
|
{{# 注释标签 - 仅在模板中显示,不在视图中输出 }} // [!code ++]
|
||||||
|
<p>{{! 忽略标签,可显示原始标签:
|
||||||
|
{{# let a = 0; }} // [!code --]
|
||||||
|
{{ let a = 0; }} // [!code ++]
|
||||||
|
!}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
条件语句:
|
||||||
|
{{= d.list.length ? d.title : '' }}
|
||||||
|
{{# if(d.title){}} - #AAAA{{='A'}}{{# } }} //[!code --]
|
||||||
|
{{ if(d.title){}} - #AAAA{{='A'}}{{ } }} //[!code ++]
|
||||||
|
</p>
|
||||||
|
<p>循环语句:</p>
|
||||||
|
<ul>
|
||||||
|
{{# d.list.forEach(function(item) { }} //[!code --]
|
||||||
|
{{ d.list.forEach(function(item) { }} //[!code ++]
|
||||||
|
</p>
|
||||||
|
<li>
|
||||||
|
<span>{{= item.title }}</span>
|
||||||
|
<span>{{= item.name }}</span>
|
||||||
|
</li>
|
||||||
|
{{# }); }} //[!code --]
|
||||||
|
{{ }); }} //[!code ++]
|
||||||
|
</ul>
|
||||||
|
{{# if (d.list.length === 0) { }} //[!code --]
|
||||||
|
{{ if (d.list.length === 0) { }} //[!code ++]
|
||||||
|
无数据
|
||||||
|
{{#} }} //[!code --]
|
||||||
|
{{} }} //[!code ++]
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
layui.use(function(){
|
||||||
|
var laytpl = layui.laytpl;
|
||||||
|
|
||||||
|
laytpl.config({
|
||||||
|
tagStyle: 'modern'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</textarea>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2>普通示例</h2>
|
||||||
|
|
||||||
<pre><code class="layui-code" lay-options="{header: true}">
|
<pre><code class="layui-code" lay-options="{header: true}">
|
||||||
code line
|
code line
|
||||||
code line
|
code line
|
||||||
|
|
|
@ -71,3 +71,12 @@ html #layuicss-skincodecss{display: none; position: absolute; width: 1989px;}
|
||||||
.layui-code-view.layui-code-hl > .layui-code-ln-side{background-color: transparent;}
|
.layui-code-view.layui-code-hl > .layui-code-ln-side{background-color: transparent;}
|
||||||
.layui-code-theme-dark.layui-code-hl,
|
.layui-code-theme-dark.layui-code-hl,
|
||||||
.layui-code-theme-dark.layui-code-hl > .layui-code-ln-side{border-color: rgb(126 122 122 / 15%);}
|
.layui-code-theme-dark.layui-code-hl > .layui-code-ln-side{border-color: rgb(126 122 122 / 15%);}
|
||||||
|
|
||||||
|
/*行高亮*/
|
||||||
|
.layui-code-line-highlighted{background-color:rgba(142, 150, 170, .14)}
|
||||||
|
.layui-code-line-diff-add{background-color: rgba(16, 185, 129, .14);}
|
||||||
|
.layui-code-line-diff-remove{background-color: rgba(244, 63, 94, .14);}
|
||||||
|
.layui-code-line-diff-add:before{position:absolute; content: "+"; color: #18794e;}
|
||||||
|
.layui-code-line-diff-remove:before{position:absolute; content: "-"; color: #b8272c;}
|
||||||
|
.layui-code-has-focused-lines .layui-code-line:not(.layui-code-line-has-focus) {filter: blur(.095rem); opacity: .7; -webkit-transition: filter .35s, opacity .35s; transition: filter .35s, opacity .35s;}
|
||||||
|
.layui-code-has-focused-lines:hover .layui-code-line:not(.layui-code-line-has-focus) {filter: blur(); opacity: 1;}
|
||||||
|
|
|
@ -48,6 +48,30 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
|
||||||
lang: 'text', // 指定语言类型
|
lang: 'text', // 指定语言类型
|
||||||
highlighter: false, // 是否开启语法高亮,'hljs','prism','shiki'
|
highlighter: false, // 是否开启语法高亮,'hljs','prism','shiki'
|
||||||
langMarker: false, // 代码区域是否显示语言类型标记
|
langMarker: false, // 代码区域是否显示语言类型标记
|
||||||
|
highlightLine: { // 行高亮
|
||||||
|
// 聚焦
|
||||||
|
focus: {
|
||||||
|
range: '', // 高亮范围,不可全局设置值 '1,3-5,8'
|
||||||
|
comment: false, // 是否解析注释,性能敏感不可全局开启 [!code type:<lines>]
|
||||||
|
classActiveLine: 'layui-code-line-has-focus', // 添加到高亮行上的类
|
||||||
|
classActivePre: 'layui-code-has-focused-lines' // 有高亮行时向根元素添加的类
|
||||||
|
},
|
||||||
|
// 高亮
|
||||||
|
hl: {
|
||||||
|
comment: false,
|
||||||
|
classActiveLine: 'layui-code-line-highlighted',
|
||||||
|
},
|
||||||
|
// diff++
|
||||||
|
'++':{
|
||||||
|
comment: false,
|
||||||
|
classActiveLine: 'layui-code-line-diff-add',
|
||||||
|
},
|
||||||
|
// diff--
|
||||||
|
'--': {
|
||||||
|
comment: false,
|
||||||
|
classActiveLine: 'layui-code-line-diff-remove',
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始索引
|
// 初始索引
|
||||||
|
@ -61,6 +85,91 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
|
||||||
var trim = function(str){
|
var trim = function(str){
|
||||||
return trimEnd(str).replace(/^\n|\n$/, '');
|
return trimEnd(str).replace(/^\n|\n$/, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// '1,3-5,8' -> [1,3,4,5,8]
|
||||||
|
var parseHighlightedLines = function(rangeStr){
|
||||||
|
if (typeof rangeStr !== 'string') return [];
|
||||||
|
var lines = $.map(rangeStr.split(','), function(v){
|
||||||
|
var range = v.split('-');
|
||||||
|
var start = parseInt(range[0], 10);
|
||||||
|
var end = parseInt(range[1], 10);
|
||||||
|
return start && end
|
||||||
|
? $.map(new Array(end - start + 1), function(_, index){ return start + index })
|
||||||
|
: start ? start : undefined
|
||||||
|
})
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 引用自 https://github.com/innocenzi/shiki-processor/blob/efa20624be415c866cc8e350d1ada886b6b5cd52/src/utils/create-range-processor.ts#L7
|
||||||
|
// 添加了 HTML 注释支持,用来处理预览场景
|
||||||
|
var highlightLineRegex = /(?:\/\/|\/\*{1,2}|<!--|<!--) *\[!code ([\w+-]+)(?::(\d+))?] *(?:\*{1,2}\/|-->|-->)?/;
|
||||||
|
var preprocessHighlightLine = function (highlightLineOptions, codeLines) {
|
||||||
|
var hasHighlightLine = false;
|
||||||
|
var needParseComment = false;
|
||||||
|
var lineClassMap = Object.create(null);
|
||||||
|
var preClassMap = Object.create(null);
|
||||||
|
|
||||||
|
var updateLineClassMap = function (lineNumber, className) {
|
||||||
|
if (!lineClassMap[lineNumber]) {
|
||||||
|
lineClassMap[lineNumber] = [CONST.ELEM_LINE];
|
||||||
|
}
|
||||||
|
lineClassMap[lineNumber].push(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收集高亮行 className
|
||||||
|
$.each(highlightLineOptions, function (type, opts) {
|
||||||
|
if (opts.range) {
|
||||||
|
var highlightLines = parseHighlightedLines(opts.range);
|
||||||
|
if (highlightLines.length > 0) {
|
||||||
|
hasHighlightLine = true;
|
||||||
|
if (opts.classActivePre) {
|
||||||
|
preClassMap[opts.classActivePre] = true;
|
||||||
|
}
|
||||||
|
$.each(highlightLines, function (i, lineNumber) {
|
||||||
|
updateLineClassMap(lineNumber, opts.classActiveLine);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opts.comment) {
|
||||||
|
needParseComment = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 解析行高亮注释并收集 className
|
||||||
|
if (needParseComment) {
|
||||||
|
$.each(codeLines, function (i, line) {
|
||||||
|
var match = line.match(highlightLineRegex);
|
||||||
|
if (match && match[1] && lay.hasOwn(highlightLineOptions, match[1])) {
|
||||||
|
var opts = highlightLineOptions[match[1]];
|
||||||
|
hasHighlightLine = true;
|
||||||
|
if (opts.classActivePre) {
|
||||||
|
preClassMap[opts.classActivePre] = true;
|
||||||
|
}
|
||||||
|
// 高亮的行数
|
||||||
|
var lines = parseInt(match[2], 10)
|
||||||
|
if (match[2] && lines && lines > 1) {
|
||||||
|
var startLine = i + 1;
|
||||||
|
var endLine = startLine + lines - 1;
|
||||||
|
var highlightLines = parseHighlightedLines(startLine + '-' + endLine);
|
||||||
|
if (highlightLines.length > 0) {
|
||||||
|
$.each(highlightLines, function (i, lineNumber) {
|
||||||
|
updateLineClassMap(lineNumber, opts.classActiveLine);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
updateLineClassMap(i + 1, opts.classActiveLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
needParseComment: needParseComment,
|
||||||
|
hasHighlightLine: hasHighlightLine,
|
||||||
|
preClass: Object.keys(preClassMap).join(' '),
|
||||||
|
lineClassMap: lineClassMap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// export api
|
// export api
|
||||||
exports('code', function(options, mode){
|
exports('code', function(options, mode){
|
||||||
|
@ -142,10 +251,16 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
|
||||||
// code 行
|
// code 行
|
||||||
var lines = String(html).split(/\r?\n/g);
|
var lines = String(html).split(/\r?\n/g);
|
||||||
|
|
||||||
|
// 预处理行高亮
|
||||||
|
var highlightLineInfo = preprocessHighlightLine(options.highlightLine, lines);
|
||||||
|
|
||||||
// 包裹 code 行结构
|
// 包裹 code 行结构
|
||||||
html = $.map(lines, function(line, num) {
|
html = $.map(lines, function(line, num) {
|
||||||
|
var lineClass = (highlightLineInfo.hasHighlightLine && highlightLineInfo.lineClassMap[num + 1])
|
||||||
|
? highlightLineInfo.lineClassMap[num + 1].join(' ')
|
||||||
|
: CONST.ELEM_LINE;
|
||||||
return [
|
return [
|
||||||
'<div class="'+ CONST.ELEM_LINE +'">',
|
'<div class="'+ lineClass + '">',
|
||||||
(
|
(
|
||||||
options.ln ? [
|
options.ln ? [
|
||||||
'<div class="'+ CONST.ELEM_LINE_NUM +'">',
|
'<div class="'+ CONST.ELEM_LINE_NUM +'">',
|
||||||
|
@ -154,12 +269,16 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
|
||||||
].join('') : ''
|
].join('') : ''
|
||||||
),
|
),
|
||||||
'<div class="layui-code-line-content">',
|
'<div class="layui-code-line-content">',
|
||||||
(line || ' '),
|
(highlightLineInfo.needParseComment ? line.replace(highlightLineRegex, '') : line) || ' ',
|
||||||
'</div>',
|
'</div>',
|
||||||
'</div>'
|
'</div>'
|
||||||
].join('');
|
].join('');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(highlightLineInfo.preClass){
|
||||||
|
othis.addClass(highlightLineInfo.preClass)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
lines: lines,
|
lines: lines,
|
||||||
html: html
|
html: html
|
||||||
|
|
Loading…
Reference in New Issue