From ad5935c02c9529cf69ec6b9967cca05ca57057c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B4=A4=E5=BF=83?= <3277200+sentsim@users.noreply.github.com> Date: Wed, 6 Sep 2023 20:58:48 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=20code=20=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=9A=20-=20=E8=BF=9B=E4=B8=80=E6=AD=A5=E5=8A=A0=E5=BC=BA?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=E9=AB=98=E4=BA=AE=E7=9A=84=E9=80=82=E9=85=8D?= =?UTF-8?q?=20-=20=E6=8F=90=E5=8D=87=20`tools`=20=E5=8F=AF=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E6=80=A7=20-=20=E6=96=B0=E5=A2=9E=20wordWrap=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=20code=20=E6=98=AF=E5=90=A6=E8=87=AA=E5=8A=A8=E6=8D=A2?= =?UTF-8?q?=E8=A1=8C=20-=20=E6=96=B0=E5=A2=9E=20`layui.code()`=20=E7=9A=84?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=AF=B9=E8=B1=A1=EF=BC=8C=E5=8C=85=E5=90=AB?= =?UTF-8?q?=E5=AF=B9=E5=AE=9E=E4=BE=8B=E8=BF=9B=E8=A1=8C=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E9=87=8D=E8=BD=BD=E5=92=8C=E4=BB=85=E9=87=8D=E8=BD=BD=20code?= =?UTF-8?q?=20=E7=AD=89=E6=93=8D=E4=BD=9C=20-=20=E4=BC=98=E5=8C=96=20code?= =?UTF-8?q?=20=E7=BB=93=E6=9E=84?= 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 | 74 +++++---- src/modules/code.js | 341 ++++++++++++++++++++++++++------------- 3 files changed, 265 insertions(+), 154 deletions(-) diff --git a/src/css/layui.css b/src/css/layui.css index 7ae264d8..d611bef5 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",Consolas,monospace;} +.layui-text pre > code:not(.layui-code){padding: 15px; font-family: "Courier New",Consolas,"Lucida Console";} /* 字体大小 */ .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{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-code{display: block; position: relative; padding: 15px; line-height: 20px; border: 1px solid #eee; border-left-width: 6px; background-color: #fff; color: #333; font-family: "Courier New",Consolas,"Lucida Console"; font-size: 12px;} /** 穿梭框 **/ .layui-transfer-box, diff --git a/src/css/modules/code.css b/src/css/modules/code.css index 3c9dd498..53dfa2ee 100644 --- a/src/css/modules/code.css +++ b/src/css/modules/code.css @@ -6,68 +6,66 @@ html #layuicss-skincodecss{display:none; position: absolute; width:1989px;} /* 字体 */ -.layui-code-view, -.layui-code-view > .layui-code-lines{font-size: 13px; font-family: "Courier New",Consolas,monospace;} +.layui-code-wrap{font-size: 13px; font-family: "Courier New",Consolas,"Lucida Console";} /* 基础结构 */ -.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; 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; 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-view{display: block; position: relative; padding: 0 !important; border: 1px solid #eee; border-left-width: 6px; background-color: #fff; color: #333;} +.layui-code-view pre{margin: 0 !important;} + +.layui-code-header{position: relative; z-index: 3; padding: 0 11px; height: 40px; line-height: 40px; border-bottom: 1px solid #eee; background-color: #fafafa; font-size: 12px;} +.layui-code-header > .layui-code-header-about{position: absolute; right: 11px; top: 0; color: #B7B7B7;} +.layui-code-header-about > a{padding-left: 10px;} + +.layui-code-wrap{position: relative; display: block; z-index: 1; margin: 0 !important; padding: 11px 0 !important; overflow-x: hidden; overflow-y: auto;} +.layui-code-line{position: relative; line-height: 19px; margin: 0 !important;} +.layui-code-line-number{position: absolute; left: 0; top: 0; padding: 0 8px; min-width: 45px; height: 100%; text-align: right; user-select: none; white-space: nowrap; overflow: hidden;} +.layui-code-line-content{padding: 0 11px; word-wrap: break-word; white-space: pre-wrap;} + +.layui-code-ln-mode > .layui-code-wrap > .layui-code-line{padding-left: 45px;} +.layui-code-ln-side{position: absolute; left: 0; top: 0; bottom: 0; z-index: 0; width: 45px; border-right: 1px solid #eee; border-color: rgb(126 122 122 / 15%); background-color: #fafafa; pointer-events: none;} + +/* 不自动换行 */ +.layui-code-nowrap > .layui-code-wrap{overflow: auto;} +.layui-code-nowrap > .layui-code-wrap > .layui-code-line > .layui-code-line-content{white-space: pre; word-wrap: normal;} +.layui-code-nowrap > .layui-code-ln-side{border-right-width: 0 !important; background: none !important;} + +.layui-code-fixbar{position: absolute; top: 8px; right: 11px; padding-right: 45px; z-index: 5;} +.layui-code-fixbar > span{position: absolute; right: 0; top: 0; padding: 0 8px; color: #777; transition: all .3s;} +.layui-code-fixbar > span:hover{color: #16b777;} +.layui-code-copy{display: none; cursor: pointer;} +.layui-code-preview > .layui-code-view > .layui-code-fixbar .layui-code-copy{display: none !important;} +.layui-code-view:hover > .layui-code-fixbar .layui-code-copy{display: block;} +.layui-code-view:hover > .layui-code-fixbar .layui-code-lang-marker{display: none;} /* 深色主题 */ .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-theme-dark > .layui-code-ln-side{border-right-color: #2a2a2a; background: none; color: #6e7681;} /* 代码预览 */ .layui-code textarea{display: none;} .layui-code-preview > .layui-code, .layui-code-preview > .layui-code-view{margin: 0;} -.layui-code-preview > .layui-tab{position: relative; z-index: 1; margin-bottom: 0;} -.layui-code-preview > .layui-tab > .layui-tab-title{border-bottom: none;} -.layui-code-preview > .layui-code > .layui-code-title{display: none;} +.layui-code-preview > .layui-tab{position: relative; z-index: 1; margin-bottom: -1px;} +.layui-code-preview > .layui-code-view > .layui-code-header{display: none;} .layui-code-preview .layui-code-item{display: none;} .layui-code-preview .layui-code-view > .layui-code-lines > .layui-code-line{} .layui-code-item-preview{position: relative; padding: 16px; overflow: auto;} .layui-code-item-preview > iframe{position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;} /* 工具栏 */ -.layui-code-tools{position: absolute; right: 11px; top: 3px;} +.layui-code-tools{position: absolute; right: 11px; top: 8px; line-height: normal;} .layui-code-tools > i{display: inline-block; margin-left: 6px; padding: 3px; cursor: pointer;} .layui-code-tools > i.layui-icon-file-b{color: #999;} .layui-code-tools > i:hover{color: #16b777;} -/* 复制 */ -.layui-code-copy{position: absolute; right: 6px; top: 6px; cursor: pointer; display: none;} -.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-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{height: calc(100vh - 51px) !important; box-sizing: border-box;} +.layui-code-full .layui-code-view, +.layui-code-full .layui-code-wrap{height: calc(100vh - 51px) !important; box-sizing: border-box;} /* 代码高亮重置 */ -.layui-code-view.layui-code-hl{ - line-height: 20px !important; -} -.layui-code-view.layui-code-hl > .layui-code-lines, -.layui-code-view.layui-code-hl > .layui-code-line-numbers{ - background-color: transparent; -} +.layui-code-view.layui-code-hl{line-height: 20px !important; border-left-width: 1px;} +.layui-code-view.layui-code-hl > .layui-code-ln-side{background-color: transparent;} diff --git a/src/modules/code.js b/src/modules/code.js index 4c73f800..1127136b 100644 --- a/src/modules/code.js +++ b/src/modules/code.js @@ -11,26 +11,28 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ var element = layui.element; var form = layui.form; var layer = layui.layer; + var hint = layui.hint(); // 常量 var CONST = { ELEM_VIEW: 'layui-code-view', - ELEM_COPY: 'layui-code-copy', ELEM_TAB: 'layui-tab', - ELEM_TITLE: 'layui-code-title', + ELEM_HEADER: 'layui-code-header', ELEM_FULL: 'layui-code-full', ELEM_PREVIEW: 'layui-code-preview', ELEM_ITEM: 'layui-code-item', 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', + ELEM_LINE_NUM: 'layui-code-line-number', + ELEM_LN_MODE: 'layui-code-ln-mode', + CDDE_DATA_CODE: 'LayuiCodeDataCode', + CDDE_DATA_CLASS: 'LayuiCodeDataClass', + LINE_RAW_WIDTH: 45, // 行号初始宽度,需与 css 保持一致 }; // 默认参数项 var config = { - elem: '.layui-code', // 元素选择器 + elem: '', // 元素选择器 about: '', // 代码栏右上角信息 ln: true, // 代码区域是否显示行号 header: false, // 是否显示代码栏头部区域 @@ -41,8 +43,9 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ code: util.escape(''), preview: 'Preview', }, + wordWrap: true, // 是否自动换行 lang: 'text', // 指定语言类型 - highlighter: false, // 是否开启语法高亮,'prism','hljs','shiki' + highlighter: false, // 是否开启语法高亮,'hljs','prism','shiki' langMarker: false, // 代码区域是否显示语言类型标记 }; @@ -59,16 +62,22 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ }; // export api - exports('code', function(options){ - var opts = options = $.extend(true, {}, config, options); + exports('code', function(options, mode){ + options = $.extend(true, {}, config, options); - // 实例对象 - var inst = { - reload: function(sets) { // 重载 - sets = sets || {}; - delete sets.elem; - sets = $.extend(true, options, sets); - layui.code(sets); + // 返回对象 + var ret = { + config: options, + reload: function(opts) { // 重载 + layui.code(this.updateOptions(opts)); + }, + updateOptions: function(opts) { // 更新属性(选项) + opts = opts || {}; + delete opts.elem; + return $.extend(true, options, opts); + }, + reloadCode: function(opts) { // 仅重载 code + layui.code(this.updateOptions(opts), 'reloadCode'); } }; @@ -79,18 +88,17 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ layui.each(options.obverse ? elem : elem.get().reverse(), function(){ layui.code($.extend({}, options, { elem: this - })); + }), mode); }); - return inst; + return ret; } // 目标元素是否存在 var othis = options.elem = $(options.elem); - var item = othis[0]; - if(!othis[0]) return inst; + if(!othis[0]) return ret; // 合并属性上的参数,并兼容旧版本属性写法 lay-* - var options = $.extend(true, {}, opts, lay.options(item), function(obj){ + $.extend(true, options, lay.options(othis[0]), function(obj){ var attrs = ['title', 'height', 'encode', 'skin', 'about']; layui.each(attrs, function(i, attr){ var value = othis.attr('lay-'+ attr); @@ -101,8 +109,6 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ return obj; }({})); - var index = layui.code.index = ++codeIndex; - // codeRender 需要关闭编码 // 未使用 codeRender 时若开启了预览,则强制开启编码 options.encode = (options.encode || options.preview) && !options.codeRender; @@ -110,8 +116,8 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ // 最终显示的代码 var finalCode; - // 获得初始代码 - var rawCode = othis.data('code') || function(){ + // 获得初始 code + var rawCode = othis.data(CONST.CDDE_DATA_CODE) || function(){ var arr = []; var textarea = othis.children('textarea'); @@ -128,7 +134,66 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ return arr; }(); - othis.data('code', rawCode); + // 记录初始 code + othis.data(CONST.CDDE_DATA_CODE, rawCode); + + // 创建 code 行结构 + var createCode = function(html) { + // codeRender + if(typeof options.codeRender === 'function') { + html = options.codeRender(String(html), options); + } + + // code 行 + var lines = String(html).split(/\r?\n/g); + + // 包裹 code 行结构 + html = $.map(lines, function(line, num) { + return [ + '
', + ( + options.ln ? [ + '
', + (util.digit(num + 1) + '.'), + '
', + ].join('') : '' + ), + '
', + (line || ' '), + '
', + '
' + ].join(''); + }); + + return { + lines: lines, + html: html + }; + }; + + // 仅重载 code + if (mode === 'reloadCode') { + (function(html) { + var rst = createCode(html); + othis.children('.layui-code-wrap').html(rst.html); + })(rawCode.join('')) + return ret; + } + + // 自增索引 + var index = layui.code.index = ++codeIndex; + othis.attr('lay-code-index', index); + + // 初始化 className + var hasDataClass = CONST.CDDE_DATA_CLASS in othis.data(); + if (hasDataClass) { + othis.attr('class', othis.data(CONST.CDDE_DATA_CLASS) || ''); + } + + // 记录初始 className + if (!hasDataClass) { + othis.data(CONST.CDDE_DATA_CLASS, othis.attr('class')); + } // code var html = finalCode = rawCode.join(''); @@ -143,7 +208,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ copy: { className: 'file-b', title: ['复制代码'], - event: function(el, type){ + event: function(obj){ var code = util.unescape(finalCode); // 写入剪切板 @@ -162,6 +227,20 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ } }; + // 移除包裹结构 + var unwrap = (function fn() { + var elemViewHas = othis.parent('.' + CONST.ELEM_PREVIEW); + var elemTabHas = elemViewHas.children('.'+ CONST.ELEM_TAB); + var elemPreviewViewHas = elemViewHas.children('.' + CONST.ELEM_ITEM +'-preview'); + + // 移除旧结构 + elemTabHas.remove(); // 移除 tab + elemPreviewViewHas.remove(); // 移除预览区域 + if (elemViewHas[0]) othis.unwrap(); // 移除外层容器 + + return fn; + })(); + // 是否开启预览 if(options.preview){ var FILTER_VALUE = 'LAY-CODE-DF-'+ index; @@ -178,9 +257,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ 'layui-border' ].join(' ') +'">'); 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); @@ -199,7 +276,8 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ 'full': { className: 'screen-full', title: ['最大化显示', '还原显示'], - event: function(el, type){ + event: function(obj){ + var el = obj.elem; var elemView = el.closest('.'+ CONST.ELEM_PREVIEW); var classNameFull = 'layui-icon-'+ this.className; var classNameRestore = 'layui-icon-screen-restore'; @@ -223,7 +301,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ 'window': { className: 'release', title: ['在新窗口预览'], - event: function(el, type){ + event: function(obj){ util.openWin({ content: finalCode }); @@ -247,19 +325,25 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ 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 - typeof options.toolsEvent === 'function' && options.toolsEvent({ + var parameters = { elem: oi, type: type, rawCode: rawCode.join(''), // 原始 code finalCode: util.unescape(finalCode) // 最终 code - }); + }; + + // 内部 tools event + tools[type] && typeof tools[type].event === 'function' && tools[type].event(parameters); + + // 外部 tools event + typeof options.toolsEvent === 'function' && options.toolsEvent(parameters); }); + // 增加工具栏 + if (options.addTools) { + options.tools = [].concat(options.tools || [], options.addTools); + } + // 渲染工具栏 layui.each(options.tools, function(i, v){ var viso = typeof v === 'object'; // 若为 object 值,则可自定义更多属性 @@ -276,20 +360,22 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ if (!type) return; + // 若非内置 tool,则合并到 tools 中 + if (!tools[type]) { + var obj = {}; + obj[type] = tool; + $.extend(tools, obj); + } + elemToolbar.append( '' ); }); - // 移除旧结构 - if(elemTabHas[0]) elemTabHas.remove(); // 移除 tab - if(elemPreviewViewHas[0]) elemPreviewViewHas.remove(); // 移除预览区域 - if(elemViewHas[0]) othis.unwrap(); // 移除外层容器 - + othis.addClass(CONST.ELEM_ITEM).wrap(elemView); // 包裹外层容器 elemTabView.append(elemHeaderView); // 追加标签头 options.tools && elemTabView.append(elemToolbar); // 追加工具栏 - othis.wrap(elemView).addClass(CONST.ELEM_ITEM).before(elemTabView); // 追加标签结构 - + othis.before(elemTabView); // 追加标签结构 // 追加预览 if(isIframePreview){ @@ -328,9 +414,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ } // 内容项初始化样式 - 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 @@ -352,10 +436,13 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ } // 创建 code 容器 - var codeElem = $(''); // 此处的闭合标签是为了兼容 IE8 + var codeElem = $(''); // 此处的闭合标签是为了兼容 IE8 // 添加主容器 className - othis.addClass('layui-code-view layui-border-box'); + othis.addClass(function(arr) { + if (!options.wordWrap) arr.push('layui-code-nowrap'); + return arr.join(' ') + }(['layui-code-view layui-border-box'])); // code 主题风格 var theme = options.theme || options.skin; @@ -376,101 +463,122 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ // 转义 HTML 标签 if(options.encode) html = util.escape(html); // 编码 - // codeRender - if(typeof options.codeRender === 'function') html = options.codeRender(html, options); - - // code 行 - var lines = String(html).split(/\r?\n/g); - - // 包裹 code 行元素 - html = (options.codeRender && !options.highlighter) - ? html - : $.map(lines, function(line){ - return ['
', (line || ' '), '
'].join(''); // 空行填充空格,以保证换行效果 - }).join('') + var createCodeRst = createCode(html); + var lines = createCodeRst.lines; // 插入 code - othis.html(codeElem.html(html)); + othis.html(codeElem.html(createCodeRst.html)); + + // 插入行号边栏 + if (options.ln) { + othis.append('
'); + } + + // 兼容旧版本 height 属性 + if (options.height) { + codeElem.css('max-height', options.height); + } // code 区域样式 + options.codeStyle = [options.style, options.codeStyle].join(''); if (options.codeStyle) { - othis.attr('style', function(i, val) { + codeElem.attr('style', function(i, val) { return (val || '') + options.codeStyle; }); } - // 兼容旧版本 height 属性 - if (options.height) othis.css('max-height', options.height); - - // 创建行号 - 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.prepend(lineNumbersCode.join('')); + // 动态设置样式 + var cssRules = [ + { + selector: '>.layui-code-wrap>.layui-code-line{}', + setValue: function(item, value) { + item.style['padding-left'] = value + 'px'; + } + }, + { + selector: '>.layui-code-wrap>.layui-code-line>.layui-code-line-number{}', + setValue: function(item, value) { + item.style.width = value + 'px'; + } + }, + { + selector: '>.layui-code-ln-side{}', + setValue: function(item, value) { + item.style.width = value + 'px'; + } } - return othis.children('.'+ CONST.ELEM_LINE_NUMS); - }() + ]; - // 设置 code 布局 + // 生成初始 style 元素 + var styleElem = lay.style({ + target: othis[0], + id: 'DF-code-'+ index, + text: $.map($.map(cssRules, function(val){ + return val.selector; + }), function(val, i) { + return ['.layui-code-view[lay-code-index="'+ index + '"]', val].join(' '); + }).join('') + }) + + // 动态设置 code 布局 var setCodeLayout = (function fn() { - lineNumsElem.css({ - height: othis.prop('scrollHeight') // 与外容器高度保持一致 - }); + if (options.ln) { + var multiLine = Math.floor(lines.length / 100); + var lineElem = codeElem.children('.'+ CONST.ELEM_LINE); + var width = lineElem.last().children('.'+ CONST.ELEM_LINE_NUM).outerWidth(); - // 根据行号容器宽度,适配 code 容器左内边距 - othis.css('padding-left', function(multiLine) { - var width = lineNumsElem.outerWidth(); - return multiLine && width > 45 ? width : null; - }(Math.floor(lines.length / 100) && options.ln)); + othis.addClass(CONST.ELEM_LN_MODE); + + // 若超出 100 行 + if (multiLine && width > CONST.LINE_RAW_WIDTH) { + lay.getStyleRules(styleElem, function(item, i) { + try { + cssRules[i].setValue(item, width); + } catch(e) { } + }); + } + } return fn; })(); - // 创建 header --- 后续版本将废弃该属性 - if(options.header && !othis.children('.'+ CONST.ELEM_TITLE)[0]){ - var headerElem = $('
'); - headerElem.html((options.title || options.text.code) + ( - options.about - ? '
' + options.about + '
' - : '' - )); + // 创建 code header + if (options.header) { + var headerElem = $('
'); + headerElem.html(options.title || options.text.code); othis.prepend(headerElem); } - // 所有实例渲染完毕后的回调 - if(options.elem.length === index + 1){ - typeof options.allDone === 'function' && options.allDone(); - } + // 创建 code 区域固定条 + var elemFixbar = $('
'); - // 若开启复制,且未开启预览时,单独生成复制图标 + // 若开启复制,且未开启预览,则单独生成复制图标 if(options.copy && !options.preview){ - var elemCopy = $(['', + var copyElem = $(['', '', ''].join('')); - var elemCopyHas = othis.children('.'+ CONST.ELEM_COPY); - - if(elemCopyHas[0]) elemCopyHas.remove(); // 移除旧的复制元素 - othis.append(elemCopy); // 点击复制 - elemCopy.on('click', function(){ + copyElem.on('click', function(){ tools.copy.event(); }); + + elemFixbar.append(copyElem); } - // language marker - if(options.langMarker){ - var elemMarker = $('' + options.lang + '') - var elemMarkerHas = othis.children("." + CONST.ELEM_MARKER); - if(elemMarkerHas[0]) elemMarkerHas.remove(); - othis.append(elemMarker); + // 创建 language marker + if (options.langMarker) { + elemFixbar.append('' + options.lang + ''); } + // 创建 about 自定义内容 + if (options.about) { + elemFixbar.append(options.about); + } + + // 生成 code fixbar + othis.append(elemFixbar); + // code 渲染完毕后的回调 if (!options.preview) { setTimeout(function(){ @@ -478,7 +586,12 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){ },3); } - return inst; + // 所有实例渲染完毕后的回调 + if(options.elem.length === index + 1){ + typeof options.allDone === 'function' && options.allDone(); + } + + return ret; }); });