From 1dc48629d6030137c6da7166cc7c6e1062b2a7d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B4=A4=E5=BF=83?=
<3277200+sentsim@users.noreply.github.com>
Date: Tue, 5 Sep 2023 16:30:07 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20code=20=E8=8B=A5=E5=B9=B2?=
=?UTF-8?q?=E5=B0=8F=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/css/layui.css | 4 +-
src/css/modules/code.css | 36 +-
src/modules/code.js | 701 +++++++++++++++++++++------------------
3 files changed, 395 insertions(+), 346 deletions(-)
diff --git a/src/css/layui.css b/src/css/layui.css
index 5fa04183..7ae264d8 100644
--- a/src/css/layui.css
+++ b/src/css/layui.css
@@ -665,7 +665,7 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-text a:not(.layui-btn){color: #01AAED;}
.layui-text a:not(.layui-btn):hover{text-decoration: underline;}
.layui-text blockquote:not(.layui-elem-quote){padding: 5px 15px; border-left: 5px solid #eee;}
-.layui-text pre > code:not(.layui-code){padding: 15px; font-family: Courier New,Lucida Console,Consolas; background-color: #fafafa;}
+.layui-text pre > code:not(.layui-code){padding: 15px; font-family: "Courier New",Consolas,monospace;}
/* 字体大小 */
.layui-font-12{font-size: 12px !important;}
@@ -1470,7 +1470,7 @@ body .layui-util-face .layui-layer-content{padding:0; background-color:#fff; co
.layui-util-face ul li:hover{position: relative; z-index: 2; border: 1px solid #eb7350; background: #fff9ec;}
/** 代码文本修饰 **/
-.layui-code{position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border: 1px solid #eee; border-left-width: 6px; background-color: #fafafa; color: #333; font-family: Courier New,Lucida Console,Consolas; font-size: 12px;}
+.layui-code{display: block; position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border: 1px solid #eee; border-left-width: 6px; background-color: #fff; color: #333; font-family: "Courier New",Consolas,monospace; font-size: 12px;}
/** 穿梭框 **/
.layui-transfer-box,
diff --git a/src/css/modules/code.css b/src/css/modules/code.css
index cb798110..3c9dd498 100644
--- a/src/css/modules/code.css
+++ b/src/css/modules/code.css
@@ -5,28 +5,32 @@
/* 加载就绪标志 */
html #layuicss-skincodecss{display:none; position: absolute; width:1989px;}
-/* 默认风格 */
-.layui-code-view{display: block; position: relative; margin: 11px 0; padding: 0 !important; border: 1px solid #eee; border-left-width: 6px; background-color: #FAFAFA; color: #333; font-family: 'Courier New'; font-size: 13px; white-space: pre; overflow: auto;}
-.layui-code-view.layui-code-line-numbers-mode{padding-left: 45px !important;}
+/* 字体 */
+.layui-code-view,
+.layui-code-view > .layui-code-lines{font-size: 13px; font-family: "Courier New",Consolas,monospace;}
+
+/* 基础结构 */
+.layui-code-view{display: block; position: relative; margin: 11px 0; padding: 0; border: 1px solid #eee; border-left-width: 6px; background-color: #fff; color: #333; white-space: pre; overflow: auto;}
+.layui-code-view.layui-code-line-numbers-mode{padding-left: 45px;}
.layui-code-title{position: relative; padding: 0 10px; height: 40px; line-height: 40px; border-bottom: 1px solid #eee; font-size: 12px;}
.layui-code-title > .layui-code-about{position: absolute; right: 10px; top: 0; color: #B7B7B7;}
.layui-code-line-numbers-mode .layui-code-title{margin-left: -45px;}
.layui-code-title ~ .layui-code-line-numbers{margin-top: 40px;}
.layui-code-about > a{padding-left: 10px;}
-.layui-code-view > .layui-code-lines{display:block; max-height: 100%; padding: 15px 10px !important; position: relative;background-color: #fff;font-family: 'Courier New'}
+.layui-code-view > .layui-code-lines{display: block; position: relative; max-height: 100%; padding: 15px 10px !important;}
.layui-code-view > .layui-code-lines > .layui-code-line{position: relative; display: block; line-height: 20px;}
.layui-code-view pre{margin: 0;}
-.layui-code-line-numbers{position: absolute;top: 0;bottom: 0;left: 0;width: 45px; border-right: 1px solid #e2e2e2; text-align: center; padding: 15px 0; line-height: 20px; user-select: none;}
+.layui-code-line-numbers{position: absolute; top: 0; bottom: 0; left: 0; min-width: 45px; border-right: 1px solid #eee; border-color: rgb(126 122 122 / 15%); text-align: center; padding: 15px 8px; line-height: 20px; background-color: #fafafa; user-select: none;}
.layui-code-line-number{display: block;}
.layui-code-lang-marker{position: absolute; top: 2px; right: 11px; color: currentColor;}
.layui-code-view:hover > .layui-code-lang-marker{display: none;}
-/* 深色风格 */
-.layui-code-dark{border: 1px solid #0C0C0C; border-left-color: #3F3F3F; background-color: #0C0C0C; color: #C2BE9E}
-.layui-code-dark > .layui-code-title{border-bottom: none;}
-.layui-code-dark > .layui-code-lines{background-color: #3F3F3F !important; border-left: none !important;}
-.layui-code-dark > .layui-code-lines{margin-left: 6px;}
-.layui-code-dark.layui-code-line-numbers-mode > .layui-code-lines{margin-left: 0;}
+/* 深色主题 */
+.layui-code-theme-dark{border: 1px solid #2a2a2a; border-left-color: #2a2a2a; background-color: #1f1f1f; color: #ccc;}
+.layui-code-theme-dark > .layui-code-title{border-bottom: none;}
+.layui-code-theme-dark > .layui-code-line-numbers{border-right-color: #2a2a2a; background: none; color: #6e7681;}
+.layui-code-theme-dark > .layui-code-lines{margin-left: 0; background: none;}
+
/* 代码预览 */
.layui-code textarea{display: none;}
@@ -51,21 +55,19 @@ html #layuicss-skincodecss{display:none; position: absolute; width:1989px;}
.layui-code-copy .layui-icon{color: #777; transition: all .3s;}
.layui-code-copy:hover .layui-icon{color: #16b777;}
.layui-code-view:hover > .layui-code-copy{display: block;}
-.layui-code-copy-offset{margin-right: 17px;}
.layui-code-preview > .layui-code-view > .layui-code-copy{display: none !important;}
/* 全屏风格 */
.layui-code-full{position: fixed; left: 0; top: 0; z-index: 1111111; width: 100%; height: 100%; background-color: #fff;}
.layui-code-full .layui-code-item{width: 100% !important; border-width: 0 !important; border-top-width: 1px !important;}
.layui-code-full .layui-code-item,
-.layui-code-full .layui-code-view{max-height: calc(100vh - 51px) !important; box-sizing: border-box;}
+.layui-code-full .layui-code-view{height: calc(100vh - 51px) !important; box-sizing: border-box;}
/* 代码高亮重置 */
-.layui-code-view[class*=language-]{
- font-size: 13px !important;
+.layui-code-view.layui-code-hl{
line-height: 20px !important;
}
-.layui-code-view[class*=language-] > .layui-code-lines,
-.layui-code-view[class*=language-] > .layui-code-line-numbers{
+.layui-code-view.layui-code-hl > .layui-code-lines,
+.layui-code-view.layui-code-hl > .layui-code-line-numbers{
background-color: transparent;
}
diff --git a/src/modules/code.js b/src/modules/code.js
index f437f96e..4c73f800 100644
--- a/src/modules/code.js
+++ b/src/modules/code.js
@@ -24,6 +24,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
ELEM_SHOW: 'layui-show',
ELEM_LINE: 'layui-code-line',
ELEM_LINES: 'layui-code-lines',
+ ELEM_LINE_NUMS: 'layui-code-line-numbers',
ELEM_LINE_NUMBERS_MODE: 'layui-code-line-numbers-mode',
};
@@ -45,8 +46,12 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
langMarker: false, // 代码区域是否显示语言类型标记
};
+ // 初始索引
+ var codeIndex = layui.code ? (layui.code.index + 10000) : 0;
+
+ // 去除尾部空格
var trimEnd = function(str){
- return String(str).replace(/\s+$/, '');
+ return String(str).replace(/\s+$/, '');
}
// 保留首行缩进
var trim = function(str){
@@ -57,381 +62,423 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
exports('code', function(options){
var opts = options = $.extend(true, {}, config, options);
- // 目标元素是否存在
- options.elem = $(options.elem);
- if(!options.elem[0]) return;
-
- // 从内至外渲染
- layui.each(options.elem.get().reverse(), function(index, item){
- var othis = $(item);
-
- // 合并属性上的参数,并兼容旧版本属性写法 lay-*
- var options = $.extend(true, {}, opts, lay.options(item), function(obj){
- var attrs = ['title', 'height', 'encode', 'skin', 'about'];
- layui.each(attrs, function(i, attr){
- var value = othis.attr('lay-'+ attr);
- if(typeof value === 'string'){
- obj[attr] = value;
- }
- })
- return obj;
- }({}));
-
- // codeRender 需要关闭编码
- // 未使用 codeRender 时若开启了预览,则强制开启编码
- options.encode = (options.encode || options.preview) && !options.codeRender;
-
- // 最终显示的代码
- var finalCode;
-
- // 获得初始代码
- var rawCode = othis.data('code') || function(){
- var arr = [];
- var textarea = othis.children('textarea');
-
- // 若内容放置在 textarea 中
- textarea.each(function(){
- arr.push(trim(this.value));
- });
-
- // 内容直接放置在元素外层
- if(arr.length === 0){
- arr.push(trim(othis.html()));
- }
-
- return arr;
- }();
-
- othis.data('code', rawCode);
-
- // code
- var html = finalCode = rawCode.join('');
-
- // 外部重新解析 code
- if(typeof options.codeParse === 'function'){
- html = finalCode = options.codeParse(html);
+ // 实例对象
+ var inst = {
+ reload: function(sets) { // 重载
+ sets = sets || {};
+ delete sets.elem;
+ sets = $.extend(true, options, sets);
+ layui.code(sets);
}
+ };
+
+ // 若 elem 非唯一
+ var elem = $(options.elem);
+ if(elem.length > 1){
+ // 是否正向渲染
+ layui.each(options.obverse ? elem : elem.get().reverse(), function(){
+ layui.code($.extend({}, options, {
+ elem: this
+ }));
+ });
+ return inst;
+ }
+
+ // 目标元素是否存在
+ var othis = options.elem = $(options.elem);
+ var item = othis[0];
+ if(!othis[0]) return inst;
+
+ // 合并属性上的参数,并兼容旧版本属性写法 lay-*
+ var options = $.extend(true, {}, opts, lay.options(item), function(obj){
+ var attrs = ['title', 'height', 'encode', 'skin', 'about'];
+ layui.each(attrs, function(i, attr){
+ var value = othis.attr('lay-'+ attr);
+ if(typeof value === 'string'){
+ obj[attr] = value;
+ }
+ })
+ return obj;
+ }({}));
+
+ var index = layui.code.index = ++codeIndex;
+
+ // codeRender 需要关闭编码
+ // 未使用 codeRender 时若开启了预览,则强制开启编码
+ options.encode = (options.encode || options.preview) && !options.codeRender;
+
+ // 最终显示的代码
+ var finalCode;
+
+ // 获得初始代码
+ var rawCode = othis.data('code') || function(){
+ var arr = [];
+ var textarea = othis.children('textarea');
+
+ // 若内容放置在 textarea 中
+ textarea.each(function(){
+ arr.push(trim(this.value));
+ });
+
+ // 内容直接放置在元素外层
+ if(arr.length === 0){
+ arr.push(trim(othis.html()));
+ }
+
+ return arr;
+ }();
+
+ othis.data('code', rawCode);
+
+ // code
+ var html = finalCode = rawCode.join('');
+
+ // 外部重新解析 code
+ if(typeof options.codeParse === 'function'){
+ html = finalCode = options.codeParse(html);
+ }
+
+ // 工具栏
+ var tools = {
+ copy: {
+ className: 'file-b',
+ title: ['复制代码'],
+ event: function(el, type){
+ var code = util.unescape(finalCode);
+
+ // 写入剪切板
+ lay.clipboard.writeText({
+ text: code,
+ done: function() {
+ layer.msg('已复制', {icon: 1});
+ },
+ error: function() {
+ layer.msg('复制失败', {icon: 2});
+ }
+ });
+
+ typeof options.onCopy === 'function' && options.onCopy(code);
+ }
+ }
+ };
+
+ // 是否开启预览
+ if(options.preview){
+ var FILTER_VALUE = 'LAY-CODE-DF-'+ index;
+ var layout = options.layout || ['code', 'preview'];
+ var isIframePreview = options.preview === 'iframe';
+
+ // 追加 Tab 组件
+ var elemView = $('
');
+ var elemTabView = $('
');
+ var elemHeaderView = $('
');
+ var elemPreviewView = $('
');
+ var elemToolbar = $('
');
+ var elemViewHas = othis.parent('.' + CONST.ELEM_PREVIEW);
+ var elemTabHas = othis.prev('.'+ CONST.ELEM_TAB);
+ var elemPreviewViewHas = othis.next('.' + CONST.ELEM_ITEM +'-preview');
+
+ if(options.id) elemView.attr('id', options.id);
+ elemView.addClass(options.className);
+ elemTabView.attr('lay-filter', FILTER_VALUE);
+
+ // 标签头
+ layui.each(layout, function(i, v){
+ var li = $('
');
+ if(i === 0) li.addClass('layui-this');
+ li.html(options.text[v]);
+ elemHeaderView.append(li);
+ });
// 工具栏
- var tools = {
- copy: {
- className: 'file-b',
- title: ['复制代码'],
+ $.extend(tools, {
+ 'full': {
+ className: 'screen-full',
+ title: ['最大化显示', '还原显示'],
event: function(el, type){
- var code = util.unescape(finalCode);
+ var elemView = el.closest('.'+ CONST.ELEM_PREVIEW);
+ var classNameFull = 'layui-icon-'+ this.className;
+ var classNameRestore = 'layui-icon-screen-restore';
+ var title = this.title;
+ var html = $('html,body');
+ var ELEM_SCROLLBAR_HIDE = 'layui-scrollbar-hide';
- // 写入剪切板
- lay.clipboard.writeText({
- text: code,
- done: function() {
- layer.msg('已复制', {icon: 1});
- },
- error: function() {
- layer.msg('复制失败', {icon: 2});
- }
+ if(el.hasClass(classNameFull)){
+ elemView.addClass(CONST.ELEM_FULL);
+ el.removeClass(classNameFull).addClass(classNameRestore);
+ el.attr('title', title[1]);
+ html.addClass(ELEM_SCROLLBAR_HIDE);
+ } else {
+ elemView.removeClass(CONST.ELEM_FULL);
+ el.removeClass(classNameRestore).addClass(classNameFull);
+ el.attr('title', title[0]);
+ html.removeClass(ELEM_SCROLLBAR_HIDE);
+ }
+ }
+ },
+ 'window': {
+ className: 'release',
+ title: ['在新窗口预览'],
+ event: function(el, type){
+ util.openWin({
+ content: finalCode
});
-
- typeof options.onCopy === 'function' && options.onCopy(code);
}
}
- };
+ });
- // 是否开启预览
- if(options.preview){
- var FILTER_VALUE = 'LAY-CODE-DF-'+ index;
- var layout = options.layout || ['code', 'preview'];
- var isIframePreview = options.preview === 'iframe';
-
- // 追加 Tab 组件
- var elemView = $('');
- var elemTabView = $('
');
- var elemHeaderView = $('
');
- var elemPreviewView = $('
');
- var elemToolbar = $('
');
- var elemViewHas = othis.parent('.' + CONST.ELEM_PREVIEW);
- var elemTabHas = othis.prev('.'+ CONST.ELEM_TAB);
- var elemPreviewViewHas = othis.next('.' + CONST.ELEM_ITEM +'-preview');
-
- if(options.id) elemView.attr('id', options.id);
- elemView.addClass(options.className);
- elemTabView.attr('lay-filter', FILTER_VALUE);
-
- // 标签头
- layui.each(layout, function(i, v){
- var li = $('
');
- if(i === 0) li.addClass('layui-this');
- li.html(options.text[v]);
- elemHeaderView.append(li);
- });
-
- // 工具栏
- $.extend(tools, {
- 'full': {
- className: 'screen-full',
- title: ['最大化显示', '还原显示'],
- event: function(el, type){
- var elemView = el.closest('.'+ CONST.ELEM_PREVIEW);
- var classNameFull = 'layui-icon-'+ this.className;
- var classNameRestore = 'layui-icon-screen-restore';
- var title = this.title;
- var html = $('html,body');
- var ELEM_SCROLLBAR_HIDE = 'layui-scrollbar-hide';
-
- if(el.hasClass(classNameFull)){
- elemView.addClass(CONST.ELEM_FULL);
- el.removeClass(classNameFull).addClass(classNameRestore);
- el.attr('title', title[1]);
- html.addClass(ELEM_SCROLLBAR_HIDE);
- } else {
- elemView.removeClass(CONST.ELEM_FULL);
- el.removeClass(classNameRestore).addClass(classNameFull);
- el.attr('title', title[0]);
- html.removeClass(ELEM_SCROLLBAR_HIDE);
- }
- }
- },
- 'window': {
- className: 'release',
- title: ['在新窗口预览'],
- event: function(el, type){
- util.openWin({
- content: finalCode
- });
- }
- }
- });
-
- // copy
- if(options.copy){
- if(layui.type(options.tools) === 'array'){
- // 若 copy 未存在于 tools 中,则追加到最前
- if(options.tools.indexOf('copy') === -1){
- options.tools.unshift('copy');
- }
- } else {
- options.tools = ['copy'];
+ // copy
+ if(options.copy){
+ if(layui.type(options.tools) === 'array'){
+ // 若 copy 未存在于 tools 中,则追加到最前
+ if(options.tools.indexOf('copy') === -1){
+ options.tools.unshift('copy');
}
+ } else {
+ options.tools = ['copy'];
}
+ }
- // 工具栏事件
- elemToolbar.on('click', '>i', function(){
- var oi = $(this);
- var type = oi.data('type');
+ // 工具栏事件
+ elemToolbar.on('click', '>i', function(){
+ var oi = $(this);
+ var type = oi.data('type');
- // 内部 tools event
- tools[type] && typeof tools[type].event === 'function' && tools[type].event(oi, type);
+ // 内部 tools event
+ tools[type] && typeof tools[type].event === 'function' && tools[type].event(oi, type);
- // 外部 tools event
- typeof options.toolsEvent === 'function' && options.toolsEvent({
- elem: oi,
- type: type,
- rawCode: rawCode.join(''), // 原始 code
- finalCode: util.unescape(finalCode) // 最终 code
- });
+ // 外部 tools event
+ typeof options.toolsEvent === 'function' && options.toolsEvent({
+ elem: oi,
+ type: type,
+ rawCode: rawCode.join(''), // 原始 code
+ finalCode: util.unescape(finalCode) // 最终 code
});
+ });
- // 渲染工具栏
- layui.each(options.tools, function(i, v){
- var viso = typeof v === 'object'; // 若为 object 值,则可自定义更多属性
- var tool = viso ? v : (
- tools[v] || {
- className: v,
- title: [v]
- }
- );
-
- var className = tool.className || tool.type;
- var title = tool.title || [''];
- var type = viso ? ( tool.type || className ) : v;
-
- if (!type) return;
-
- elemToolbar.append(
- ''
- );
- });
-
- // 移除旧结构
- if(elemTabHas[0]) elemTabHas.remove(); // 移除 tab
- if(elemPreviewViewHas[0]) elemPreviewViewHas.remove(); // 移除预览区域
- if(elemViewHas[0]) othis.unwrap(); // 移除外层容器
-
- elemTabView.append(elemHeaderView); // 追加标签头
- options.tools && elemTabView.append(elemToolbar); // 追加工具栏
- othis.wrap(elemView).addClass(CONST.ELEM_ITEM).before(elemTabView); // 追加标签结构
-
-
- // 追加预览
- if(isIframePreview){
- elemPreviewView.html('');
- }
-
- // 执行预览
- var run = function(thisItemBody){
- var iframe = thisItemBody.children('iframe')[0];
- if(isIframePreview && iframe){
- iframe.srcdoc = finalCode;
- } else {
- thisItemBody.html(rawCode.join(''));
+ // 渲染工具栏
+ layui.each(options.tools, function(i, v){
+ var viso = typeof v === 'object'; // 若为 object 值,则可自定义更多属性
+ var tool = viso ? v : (
+ tools[v] || {
+ className: v,
+ title: [v]
+ }
+ );
+
+ var className = tool.className || tool.type;
+ var title = tool.title || [''];
+ var type = viso ? ( tool.type || className ) : v;
+
+ if (!type) return;
+
+ elemToolbar.append(
+ ''
+ );
+ });
+
+ // 移除旧结构
+ if(elemTabHas[0]) elemTabHas.remove(); // 移除 tab
+ if(elemPreviewViewHas[0]) elemPreviewViewHas.remove(); // 移除预览区域
+ if(elemViewHas[0]) othis.unwrap(); // 移除外层容器
+
+ elemTabView.append(elemHeaderView); // 追加标签头
+ options.tools && elemTabView.append(elemToolbar); // 追加工具栏
+ othis.wrap(elemView).addClass(CONST.ELEM_ITEM).before(elemTabView); // 追加标签结构
+
+
+ // 追加预览
+ if(isIframePreview){
+ elemPreviewView.html('');
+ }
+
+ // 执行预览
+ var run = function(thisItemBody){
+ var iframe = thisItemBody.children('iframe')[0];
+ if(isIframePreview && iframe){
+ iframe.srcdoc = finalCode;
+ } else {
+ thisItemBody.html(rawCode.join(''));
+ }
+ // 回调的返回参数
+ var params = {
+ container: thisItemBody,
+ render: function(){
+ form.render(thisItemBody.find('.layui-form'));
+ element.render();
}
- // 回调的返回参数
- var params = {
- container: thisItemBody,
- render: function(){
- form.render(thisItemBody.find('.layui-form'));
- element.render();
- }
- };
- // 当前实例预览完毕后的回调
- setTimeout(function(){
- typeof options.done === 'function' && options.done(params);
- },3);
};
- if(layout[0] === 'preview'){
- elemPreviewView.addClass(CONST.ELEM_SHOW);
- othis.before(elemPreviewView);
- run(elemPreviewView);
- } else {
- othis.addClass(CONST.ELEM_SHOW).after(elemPreviewView);
+ // 当前实例预览完毕后的回调
+ setTimeout(function(){
+ typeof options.done === 'function' && options.done(params);
+ },3);
+ };
+
+ if(layout[0] === 'preview'){
+ elemPreviewView.addClass(CONST.ELEM_SHOW);
+ othis.before(elemPreviewView);
+ run(elemPreviewView);
+ } else {
+ othis.addClass(CONST.ELEM_SHOW).after(elemPreviewView);
+ }
+
+ // 内容项初始化样式
+ options.codeStyle = [options.style, options.codeStyle].join('');
+ options.previewStyle = [options.style, options.previewStyle].join('');
+ // othis.attr('style', options.codeStyle);
+ elemPreviewView.attr('style', options.previewStyle);
+
+ // tab change
+ element.on('tab('+ FILTER_VALUE +')', function(data){
+ var $this = $(this);
+ var thisElem = $(data.elem).closest('.'+ CONST.ELEM_PREVIEW);
+ var elemItemBody = thisElem.find('.'+ CONST.ELEM_ITEM);
+ var thisItemBody = elemItemBody.eq(data.index);
+
+ elemItemBody.removeClass(CONST.ELEM_SHOW);
+ thisItemBody.addClass(CONST.ELEM_SHOW);
+
+ if($this.attr('lay-id') === 'preview'){
+ run(thisItemBody);
}
- // 内容项初始化样式
- options.codeStyle = [options.style, options.codeStyle].join('');
- options.previewStyle = [options.style, options.previewStyle].join('');
- // othis.attr('style', options.codeStyle);
- elemPreviewView.attr('style', options.previewStyle);
+ setCodeLayout();
+ });
+ }
- // tab change
- element.on('tab('+ FILTER_VALUE +')', function(data){
- var $this = $(this);
- var thisElem = $(data.elem).closest('.'+ CONST.ELEM_PREVIEW);
- var elemItemBody = thisElem.find('.'+ CONST.ELEM_ITEM);
- var thisItemBody = elemItemBody.eq(data.index);
+ // 创建 code 容器
+ var codeElem = $('
'); // 此处的闭合标签是为了兼容 IE8
- elemItemBody.removeClass(CONST.ELEM_SHOW);
- thisItemBody.addClass(CONST.ELEM_SHOW);
+ // 添加主容器 className
+ othis.addClass('layui-code-view layui-border-box');
- if($this.attr('lay-id') === 'preview'){
- run(thisItemBody);
- }
- });
- }
+ // code 主题风格
+ var theme = options.theme || options.skin;
+ if (theme) {
+ othis.removeClass('layui-code-theme-dark layui-code-theme-light');
+ othis.addClass('layui-code-theme-'+ theme);
+ }
- var listElem = $('
'); // 此处的闭合标签是为了兼容 IE8
+ // 添加高亮必要的 className
+ if (options.highlighter) {
+ othis.addClass([
+ options.highlighter,
+ 'language-' + options.lang,
+ 'layui-code-hl'
+ ].join(' '));
+ }
- // header
- var headerElem = $('');
+ // 转义 HTML 标签
+ if(options.encode) html = util.escape(html); // 编码
- // 添加组件 className
- othis.addClass('layui-code-view layui-box');
+ // codeRender
+ if(typeof options.codeRender === 'function') html = options.codeRender(html, options);
- // 自定义风格
- if(options.skin){
- if(options.skin === 'notepad') options.skin = 'dark';
- othis.removeClass('layui-code-dark layui-code-light');
- othis.addClass('layui-code-'+ options.skin);
- }
+ // code 行
+ var lines = String(html).split(/\r?\n/g);
- // 高亮
- if(options.highlighter) othis.addClass(options.highlighter + ' language-' + options.lang);
+ // 包裹 code 行元素
+ html = (options.codeRender && !options.highlighter)
+ ? html
+ : $.map(lines, function(line){
+ return ['
', (line || ' '), '
'].join(''); // 空行填充空格,以保证换行效果
+ }).join('')
- // 转义 HTML 标签
- if(options.encode) html = util.escape(html); // 编码
+ // 插入 code
+ othis.html(codeElem.html(html));
- // code 转 html
- if(typeof options.codeRender === 'function') html = options.codeRender(html, options);
- var lines = html.split(/\r?\n/g);
- html = (options.codeRender && !options.highlighter)
- ? html
- : $.map(lines, function(line){
- return ['
', (line || ' '), '
'].join(''); // 空行填充空格,以保证换行效果
- }).join('')
+ // code 区域样式
+ if (options.codeStyle) {
+ othis.attr('style', function(i, val) {
+ return (val || '') + options.codeStyle;
+ });
+ }
- // 生成列表
- othis.html(listElem.html(html));
+ // 兼容旧版本 height 属性
+ if (options.height) othis.css('max-height', options.height);
- // 创建行号
- if(options.ln) {
- var lineNumbersCode = ['
']
+ // 创建行号
+ var lineNumsElem = function() {
+ if (options.ln) {
+ var lineNumbersCode = ['
']
layui.each(lines, function(index){
lineNumbersCode.push('' + util.digit(index + 1) +'.')
});
lineNumbersCode.push('
');
othis.addClass(CONST.ELEM_LINE_NUMBERS_MODE);
- othis.append(lineNumbersCode.join(''));
- othis.children('.layui-code-line-numbers').css({
- height: listElem.height(),
- })
+ othis.prepend(lineNumbersCode.join(''));
}
+ return othis.children('.'+ CONST.ELEM_LINE_NUMS);
+ }()
- // 创建 header
- if(options.header && !othis.children('.'+ CONST.ELEM_TITLE)[0]){
- headerElem.html((options.title || options.text.code) + (
- options.about
- ? '
' + options.about + '
'
- : ''
- ));
- othis.prepend(headerElem);
- }
+ // 设置 code 布局
+ var setCodeLayout = (function fn() {
+ lineNumsElem.css({
+ height: othis.prop('scrollHeight') // 与外容器高度保持一致
+ });
- // 所有实例渲染完毕后的回调
- if(options.elem.length === index + 1){
- typeof options.allDone === 'function' && options.allDone();
- }
+ // 根据行号容器宽度,适配 code 容器左内边距
+ othis.css('padding-left', function(multiLine) {
+ var width = lineNumsElem.outerWidth();
+ return multiLine && width > 45 ? width : null;
+ }(Math.floor(lines.length / 100) && options.ln));
- // 按行数适配左边距
- (function(autoIncNums){
- if(autoIncNums > 0){
- othis.css('margin-left', autoIncNums + 'px');
- }
- })(Math.floor(listElem.find('.' + CONST.ELEM_LINE).length/100));
+ return fn;
+ })();
- // 限制 Code 最大高度
- if(options.height){ // 兼容旧版本
- othis.css('max-height', options.height);
- }
- // Code 内容区域样式
- if(options.codeStyle){
- othis.attr('style', function(_, origVal){
- return (origVal || '') + options.codeStyle;
- });
- }
+ // 创建 header --- 后续版本将废弃该属性
+ if(options.header && !othis.children('.'+ CONST.ELEM_TITLE)[0]){
+ var headerElem = $('
');
+ headerElem.html((options.title || options.text.code) + (
+ options.about
+ ? '
' + options.about + '
'
+ : ''
+ ));
+ othis.prepend(headerElem);
+ }
- // 是否开启代码复制
- if(options.copy && !options.preview){
- var elemCopy = $(['
',
- '',
- ''].join(''));
- var elemCopyHas = othis.children('.'+ CONST.ELEM_COPY);
- var isHeight = othis[0].style.height || othis[0].style.maxHeight;
+ // 所有实例渲染完毕后的回调
+ if(options.elem.length === index + 1){
+ typeof options.allDone === 'function' && options.allDone();
+ }
- if(isHeight) elemCopy.addClass(CONST.ELEM_COPY + '-offset'); // 偏移
- if(elemCopyHas[0]) elemCopyHas.remove(); // 移除旧的复制元素
- othis.append(elemCopy);
+ // 若开启复制,且未开启预览时,单独生成复制图标
+ if(options.copy && !options.preview){
+ var elemCopy = $(['
',
+ '',
+ ''].join(''));
+ var elemCopyHas = othis.children('.'+ CONST.ELEM_COPY);
- // 点击复制
- elemCopy.on('click', function(){
- tools.copy.event();
- });
- }
+ if(elemCopyHas[0]) elemCopyHas.remove(); // 移除旧的复制元素
+ othis.append(elemCopy);
- // language marker
- if(options.langMarker){
- var elemMarker = $('
' + options.lang + '')
- var isHeight = othis[0].style.height || othis[0].style.maxHeight;
- var elemMarkerHas = othis.children("." + CONST.ELEM_MARKER);
- if(isHeight) elemMarker.css('margin-right', '17px')
- if(elemMarkerHas) elemMarkerHas.remove();
- othis.append(elemMarker);
- }
+ // 点击复制
+ elemCopy.on('click', function(){
+ tools.copy.event();
+ });
+ }
- });
+ // language marker
+ if(options.langMarker){
+ var elemMarker = $('
' + options.lang + '')
+ var elemMarkerHas = othis.children("." + CONST.ELEM_MARKER);
+ if(elemMarkerHas[0]) elemMarkerHas.remove();
+ othis.append(elemMarker);
+ }
+ // code 渲染完毕后的回调
+ if (!options.preview) {
+ setTimeout(function(){
+ typeof options.done === 'function' && options.done({});
+ },3);
+ }
+
+ return inst;
});
});