mirror of https://github.com/layui/layui
重构 code 组件:
- 进一步加强语法高亮的适配 - 提升 `tools` 可扩展性 - 新增 wordWrap 属性,用于设置 code 是否自动换行 - 新增 `layui.code()` 的返回对象,包含对实例进行完整重载和仅重载 code 等操作 - 优化 code 结构pull/1368/head
parent
b809eee28e
commit
ad5935c02c
|
@ -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){color: #01AAED;}
|
||||||
.layui-text a:not(.layui-btn):hover{text-decoration: underline;}
|
.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 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;}
|
.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-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,
|
.layui-transfer-box,
|
||||||
|
|
|
@ -6,68 +6,66 @@
|
||||||
html #layuicss-skincodecss{display:none; position: absolute; width:1989px;}
|
html #layuicss-skincodecss{display:none; position: absolute; width:1989px;}
|
||||||
|
|
||||||
/* 字体 */
|
/* 字体 */
|
||||||
.layui-code-view,
|
.layui-code-wrap{font-size: 13px; font-family: "Courier New",Consolas,"Lucida Console";}
|
||||||
.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{display: block; position: relative; padding: 0 !important; border: 1px solid #eee; border-left-width: 6px; background-color: #fff; color: #333;}
|
||||||
.layui-code-view.layui-code-line-numbers-mode{padding-left: 45px;}
|
.layui-code-view pre{margin: 0 !important;}
|
||||||
.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-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-line-numbers-mode .layui-code-title{margin-left: -45px;}
|
.layui-code-header > .layui-code-header-about{position: absolute; right: 11px; top: 0; color: #B7B7B7;}
|
||||||
.layui-code-title ~ .layui-code-line-numbers{margin-top: 40px;}
|
.layui-code-header-about > a{padding-left: 10px;}
|
||||||
.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-wrap{position: relative; display: block; z-index: 1; margin: 0 !important; padding: 11px 0 !important; overflow-x: hidden; overflow-y: auto;}
|
||||||
.layui-code-view > .layui-code-lines > .layui-code-line{position: relative; display: block; line-height: 20px;}
|
.layui-code-line{position: relative; line-height: 19px; margin: 0 !important;}
|
||||||
.layui-code-view pre{margin: 0;}
|
.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-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-content{padding: 0 11px; word-wrap: break-word; white-space: pre-wrap;}
|
||||||
.layui-code-line-number{display: block;}
|
|
||||||
.layui-code-lang-marker{position: absolute; top: 2px; right: 11px; color: currentColor;}
|
.layui-code-ln-mode > .layui-code-wrap > .layui-code-line{padding-left: 45px;}
|
||||||
.layui-code-view:hover > .layui-code-lang-marker{display: none;}
|
.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{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-ln-side{border-right-color: #2a2a2a; background: none; color: #6e7681;}
|
||||||
.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;}
|
.layui-code textarea{display: none;}
|
||||||
.layui-code-preview > .layui-code,
|
.layui-code-preview > .layui-code,
|
||||||
.layui-code-preview > .layui-code-view{margin: 0;}
|
.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{position: relative; z-index: 1; margin-bottom: -1px;}
|
||||||
.layui-code-preview > .layui-tab > .layui-tab-title{border-bottom: none;}
|
.layui-code-preview > .layui-code-view > .layui-code-header{display: none;}
|
||||||
.layui-code-preview > .layui-code > .layui-code-title{display: none;}
|
|
||||||
.layui-code-preview .layui-code-item{display: none;}
|
.layui-code-preview .layui-code-item{display: none;}
|
||||||
.layui-code-preview .layui-code-view > .layui-code-lines > .layui-code-line{}
|
.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{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-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{display: inline-block; margin-left: 6px; padding: 3px; cursor: pointer;}
|
||||||
.layui-code-tools > i.layui-icon-file-b{color: #999;}
|
.layui-code-tools > i.layui-icon-file-b{color: #999;}
|
||||||
.layui-code-tools > i:hover{color: #16b777;}
|
.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{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{width: 100% !important; border-width: 0 !important; border-top-width: 1px !important;}
|
||||||
.layui-code-full .layui-code-item,
|
.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{
|
.layui-code-view.layui-code-hl{line-height: 20px !important; border-left-width: 1px;}
|
||||||
line-height: 20px !important;
|
.layui-code-view.layui-code-hl > .layui-code-ln-side{background-color: transparent;}
|
||||||
}
|
|
||||||
.layui-code-view.layui-code-hl > .layui-code-lines,
|
|
||||||
.layui-code-view.layui-code-hl > .layui-code-line-numbers{
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,26 +11,28 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
var element = layui.element;
|
var element = layui.element;
|
||||||
var form = layui.form;
|
var form = layui.form;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
|
var hint = layui.hint();
|
||||||
|
|
||||||
// 常量
|
// 常量
|
||||||
var CONST = {
|
var CONST = {
|
||||||
ELEM_VIEW: 'layui-code-view',
|
ELEM_VIEW: 'layui-code-view',
|
||||||
ELEM_COPY: 'layui-code-copy',
|
|
||||||
ELEM_TAB: 'layui-tab',
|
ELEM_TAB: 'layui-tab',
|
||||||
ELEM_TITLE: 'layui-code-title',
|
ELEM_HEADER: 'layui-code-header',
|
||||||
ELEM_FULL: 'layui-code-full',
|
ELEM_FULL: 'layui-code-full',
|
||||||
ELEM_PREVIEW: 'layui-code-preview',
|
ELEM_PREVIEW: 'layui-code-preview',
|
||||||
ELEM_ITEM: 'layui-code-item',
|
ELEM_ITEM: 'layui-code-item',
|
||||||
ELEM_SHOW: 'layui-show',
|
ELEM_SHOW: 'layui-show',
|
||||||
ELEM_LINE: 'layui-code-line',
|
ELEM_LINE: 'layui-code-line',
|
||||||
ELEM_LINES: 'layui-code-lines',
|
ELEM_LINE_NUM: 'layui-code-line-number',
|
||||||
ELEM_LINE_NUMS: 'layui-code-line-numbers',
|
ELEM_LN_MODE: 'layui-code-ln-mode',
|
||||||
ELEM_LINE_NUMBERS_MODE: 'layui-code-line-numbers-mode',
|
CDDE_DATA_CODE: 'LayuiCodeDataCode',
|
||||||
|
CDDE_DATA_CLASS: 'LayuiCodeDataClass',
|
||||||
|
LINE_RAW_WIDTH: 45, // 行号初始宽度,需与 css 保持一致
|
||||||
};
|
};
|
||||||
|
|
||||||
// 默认参数项
|
// 默认参数项
|
||||||
var config = {
|
var config = {
|
||||||
elem: '.layui-code', // 元素选择器
|
elem: '', // 元素选择器
|
||||||
about: '', // 代码栏右上角信息
|
about: '', // 代码栏右上角信息
|
||||||
ln: true, // 代码区域是否显示行号
|
ln: true, // 代码区域是否显示行号
|
||||||
header: false, // 是否显示代码栏头部区域
|
header: false, // 是否显示代码栏头部区域
|
||||||
|
@ -41,8 +43,9 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
code: util.escape('</>'),
|
code: util.escape('</>'),
|
||||||
preview: 'Preview',
|
preview: 'Preview',
|
||||||
},
|
},
|
||||||
|
wordWrap: true, // 是否自动换行
|
||||||
lang: 'text', // 指定语言类型
|
lang: 'text', // 指定语言类型
|
||||||
highlighter: false, // 是否开启语法高亮,'prism','hljs','shiki'
|
highlighter: false, // 是否开启语法高亮,'hljs','prism','shiki'
|
||||||
langMarker: false, // 代码区域是否显示语言类型标记
|
langMarker: false, // 代码区域是否显示语言类型标记
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,16 +62,22 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
};
|
};
|
||||||
|
|
||||||
// export api
|
// export api
|
||||||
exports('code', function(options){
|
exports('code', function(options, mode){
|
||||||
var opts = options = $.extend(true, {}, config, options);
|
options = $.extend(true, {}, config, options);
|
||||||
|
|
||||||
// 实例对象
|
// 返回对象
|
||||||
var inst = {
|
var ret = {
|
||||||
reload: function(sets) { // 重载
|
config: options,
|
||||||
sets = sets || {};
|
reload: function(opts) { // 重载
|
||||||
delete sets.elem;
|
layui.code(this.updateOptions(opts));
|
||||||
sets = $.extend(true, options, sets);
|
},
|
||||||
layui.code(sets);
|
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.each(options.obverse ? elem : elem.get().reverse(), function(){
|
||||||
layui.code($.extend({}, options, {
|
layui.code($.extend({}, options, {
|
||||||
elem: this
|
elem: this
|
||||||
}));
|
}), mode);
|
||||||
});
|
});
|
||||||
return inst;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 目标元素是否存在
|
// 目标元素是否存在
|
||||||
var othis = options.elem = $(options.elem);
|
var othis = options.elem = $(options.elem);
|
||||||
var item = othis[0];
|
if(!othis[0]) return ret;
|
||||||
if(!othis[0]) return inst;
|
|
||||||
|
|
||||||
// 合并属性上的参数,并兼容旧版本属性写法 lay-*
|
// 合并属性上的参数,并兼容旧版本属性写法 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'];
|
var attrs = ['title', 'height', 'encode', 'skin', 'about'];
|
||||||
layui.each(attrs, function(i, attr){
|
layui.each(attrs, function(i, attr){
|
||||||
var value = othis.attr('lay-'+ attr);
|
var value = othis.attr('lay-'+ attr);
|
||||||
|
@ -101,8 +109,6 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
return obj;
|
return obj;
|
||||||
}({}));
|
}({}));
|
||||||
|
|
||||||
var index = layui.code.index = ++codeIndex;
|
|
||||||
|
|
||||||
// codeRender 需要关闭编码
|
// codeRender 需要关闭编码
|
||||||
// 未使用 codeRender 时若开启了预览,则强制开启编码
|
// 未使用 codeRender 时若开启了预览,则强制开启编码
|
||||||
options.encode = (options.encode || options.preview) && !options.codeRender;
|
options.encode = (options.encode || options.preview) && !options.codeRender;
|
||||||
|
@ -110,8 +116,8 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
// 最终显示的代码
|
// 最终显示的代码
|
||||||
var finalCode;
|
var finalCode;
|
||||||
|
|
||||||
// 获得初始代码
|
// 获得初始 code
|
||||||
var rawCode = othis.data('code') || function(){
|
var rawCode = othis.data(CONST.CDDE_DATA_CODE) || function(){
|
||||||
var arr = [];
|
var arr = [];
|
||||||
var textarea = othis.children('textarea');
|
var textarea = othis.children('textarea');
|
||||||
|
|
||||||
|
@ -128,7 +134,66 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
return arr;
|
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 [
|
||||||
|
'<div class="'+ CONST.ELEM_LINE +'">',
|
||||||
|
(
|
||||||
|
options.ln ? [
|
||||||
|
'<div class="'+ CONST.ELEM_LINE_NUM +'">',
|
||||||
|
(util.digit(num + 1) + '.'),
|
||||||
|
'</div>',
|
||||||
|
].join('') : ''
|
||||||
|
),
|
||||||
|
'<div class="layui-code-line-content">',
|
||||||
|
(line || ' '),
|
||||||
|
'</div>',
|
||||||
|
'</div>'
|
||||||
|
].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
|
// code
|
||||||
var html = finalCode = rawCode.join('');
|
var html = finalCode = rawCode.join('');
|
||||||
|
@ -143,7 +208,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
copy: {
|
copy: {
|
||||||
className: 'file-b',
|
className: 'file-b',
|
||||||
title: ['复制代码'],
|
title: ['复制代码'],
|
||||||
event: function(el, type){
|
event: function(obj){
|
||||||
var code = util.unescape(finalCode);
|
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){
|
if(options.preview){
|
||||||
var FILTER_VALUE = 'LAY-CODE-DF-'+ index;
|
var FILTER_VALUE = 'LAY-CODE-DF-'+ index;
|
||||||
|
@ -178,9 +257,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
'layui-border'
|
'layui-border'
|
||||||
].join(' ') +'">');
|
].join(' ') +'">');
|
||||||
var elemToolbar = $('<div class="layui-code-tools"></div>');
|
var elemToolbar = $('<div class="layui-code-tools"></div>');
|
||||||
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);
|
if(options.id) elemView.attr('id', options.id);
|
||||||
elemView.addClass(options.className);
|
elemView.addClass(options.className);
|
||||||
|
@ -199,7 +276,8 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
'full': {
|
'full': {
|
||||||
className: 'screen-full',
|
className: 'screen-full',
|
||||||
title: ['最大化显示', '还原显示'],
|
title: ['最大化显示', '还原显示'],
|
||||||
event: function(el, type){
|
event: function(obj){
|
||||||
|
var el = obj.elem;
|
||||||
var elemView = el.closest('.'+ CONST.ELEM_PREVIEW);
|
var elemView = el.closest('.'+ CONST.ELEM_PREVIEW);
|
||||||
var classNameFull = 'layui-icon-'+ this.className;
|
var classNameFull = 'layui-icon-'+ this.className;
|
||||||
var classNameRestore = 'layui-icon-screen-restore';
|
var classNameRestore = 'layui-icon-screen-restore';
|
||||||
|
@ -223,7 +301,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
'window': {
|
'window': {
|
||||||
className: 'release',
|
className: 'release',
|
||||||
title: ['在新窗口预览'],
|
title: ['在新窗口预览'],
|
||||||
event: function(el, type){
|
event: function(obj){
|
||||||
util.openWin({
|
util.openWin({
|
||||||
content: finalCode
|
content: finalCode
|
||||||
});
|
});
|
||||||
|
@ -247,19 +325,25 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
elemToolbar.on('click', '>i', function(){
|
elemToolbar.on('click', '>i', function(){
|
||||||
var oi = $(this);
|
var oi = $(this);
|
||||||
var type = oi.data('type');
|
var type = oi.data('type');
|
||||||
|
var parameters = {
|
||||||
// 内部 tools event
|
|
||||||
tools[type] && typeof tools[type].event === 'function' && tools[type].event(oi, type);
|
|
||||||
|
|
||||||
// 外部 tools event
|
|
||||||
typeof options.toolsEvent === 'function' && options.toolsEvent({
|
|
||||||
elem: oi,
|
elem: oi,
|
||||||
type: type,
|
type: type,
|
||||||
rawCode: rawCode.join(''), // 原始 code
|
rawCode: rawCode.join(''), // 原始 code
|
||||||
finalCode: util.unescape(finalCode) // 最终 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){
|
layui.each(options.tools, function(i, v){
|
||||||
var viso = typeof v === 'object'; // 若为 object 值,则可自定义更多属性
|
var viso = typeof v === 'object'; // 若为 object 值,则可自定义更多属性
|
||||||
|
@ -276,20 +360,22 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
|
|
||||||
if (!type) return;
|
if (!type) return;
|
||||||
|
|
||||||
|
// 若非内置 tool,则合并到 tools 中
|
||||||
|
if (!tools[type]) {
|
||||||
|
var obj = {};
|
||||||
|
obj[type] = tool;
|
||||||
|
$.extend(tools, obj);
|
||||||
|
}
|
||||||
|
|
||||||
elemToolbar.append(
|
elemToolbar.append(
|
||||||
'<i class="layui-icon layui-icon-'+ className +'" data-type="'+ type +'" title="'+ title[0] +'"></i>'
|
'<i class="layui-icon layui-icon-'+ className +'" data-type="'+ type +'" title="'+ title[0] +'"></i>'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 移除旧结构
|
othis.addClass(CONST.ELEM_ITEM).wrap(elemView); // 包裹外层容器
|
||||||
if(elemTabHas[0]) elemTabHas.remove(); // 移除 tab
|
|
||||||
if(elemPreviewViewHas[0]) elemPreviewViewHas.remove(); // 移除预览区域
|
|
||||||
if(elemViewHas[0]) othis.unwrap(); // 移除外层容器
|
|
||||||
|
|
||||||
elemTabView.append(elemHeaderView); // 追加标签头
|
elemTabView.append(elemHeaderView); // 追加标签头
|
||||||
options.tools && elemTabView.append(elemToolbar); // 追加工具栏
|
options.tools && elemTabView.append(elemToolbar); // 追加工具栏
|
||||||
othis.wrap(elemView).addClass(CONST.ELEM_ITEM).before(elemTabView); // 追加标签结构
|
othis.before(elemTabView); // 追加标签结构
|
||||||
|
|
||||||
|
|
||||||
// 追加预览
|
// 追加预览
|
||||||
if(isIframePreview){
|
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('');
|
options.previewStyle = [options.style, options.previewStyle].join('');
|
||||||
// othis.attr('style', options.codeStyle);
|
|
||||||
elemPreviewView.attr('style', options.previewStyle);
|
elemPreviewView.attr('style', options.previewStyle);
|
||||||
|
|
||||||
// tab change
|
// tab change
|
||||||
|
@ -352,10 +436,13 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建 code 容器
|
// 创建 code 容器
|
||||||
var codeElem = $('<code class="'+ CONST.ELEM_LINES +'"></code>'); // 此处的闭合标签是为了兼容 IE8
|
var codeElem = $('<code class="layui-code-wrap"></code>'); // 此处的闭合标签是为了兼容 IE8
|
||||||
|
|
||||||
// 添加主容器 className
|
// 添加主容器 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 主题风格
|
// code 主题风格
|
||||||
var theme = options.theme || options.skin;
|
var theme = options.theme || options.skin;
|
||||||
|
@ -376,101 +463,122 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
// 转义 HTML 标签
|
// 转义 HTML 标签
|
||||||
if(options.encode) html = util.escape(html); // 编码
|
if(options.encode) html = util.escape(html); // 编码
|
||||||
|
|
||||||
// codeRender
|
var createCodeRst = createCode(html);
|
||||||
if(typeof options.codeRender === 'function') html = options.codeRender(html, options);
|
var lines = createCodeRst.lines;
|
||||||
|
|
||||||
// code 行
|
|
||||||
var lines = String(html).split(/\r?\n/g);
|
|
||||||
|
|
||||||
// 包裹 code 行元素
|
|
||||||
html = (options.codeRender && !options.highlighter)
|
|
||||||
? html
|
|
||||||
: $.map(lines, function(line){
|
|
||||||
return ['<div class="', CONST.ELEM_LINE, '">', (line || ' '), '</div>'].join(''); // 空行填充空格,以保证换行效果
|
|
||||||
}).join('')
|
|
||||||
|
|
||||||
// 插入 code
|
// 插入 code
|
||||||
othis.html(codeElem.html(html));
|
othis.html(codeElem.html(createCodeRst.html));
|
||||||
|
|
||||||
|
// 插入行号边栏
|
||||||
|
if (options.ln) {
|
||||||
|
othis.append('<div class="layui-code-ln-side"></div>');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兼容旧版本 height 属性
|
||||||
|
if (options.height) {
|
||||||
|
codeElem.css('max-height', options.height);
|
||||||
|
}
|
||||||
|
|
||||||
// code 区域样式
|
// code 区域样式
|
||||||
|
options.codeStyle = [options.style, options.codeStyle].join('');
|
||||||
if (options.codeStyle) {
|
if (options.codeStyle) {
|
||||||
othis.attr('style', function(i, val) {
|
codeElem.attr('style', function(i, val) {
|
||||||
return (val || '') + options.codeStyle;
|
return (val || '') + options.codeStyle;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 兼容旧版本 height 属性
|
// 动态设置样式
|
||||||
if (options.height) othis.css('max-height', options.height);
|
var cssRules = [
|
||||||
|
{
|
||||||
// 创建行号
|
selector: '>.layui-code-wrap>.layui-code-line{}',
|
||||||
var lineNumsElem = function() {
|
setValue: function(item, value) {
|
||||||
if (options.ln) {
|
item.style['padding-left'] = value + 'px';
|
||||||
var lineNumbersCode = ['<div class="'+ CONST.ELEM_LINE_NUMS +'">']
|
}
|
||||||
layui.each(lines, function(index){
|
},
|
||||||
lineNumbersCode.push('<span class="layui-code-line-number">' + util.digit(index + 1) +'.</span>')
|
{
|
||||||
});
|
selector: '>.layui-code-wrap>.layui-code-line>.layui-code-line-number{}',
|
||||||
lineNumbersCode.push('</div>');
|
setValue: function(item, value) {
|
||||||
othis.addClass(CONST.ELEM_LINE_NUMBERS_MODE);
|
item.style.width = value + 'px';
|
||||||
othis.prepend(lineNumbersCode.join(''));
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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() {
|
var setCodeLayout = (function fn() {
|
||||||
lineNumsElem.css({
|
if (options.ln) {
|
||||||
height: othis.prop('scrollHeight') // 与外容器高度保持一致
|
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.addClass(CONST.ELEM_LN_MODE);
|
||||||
othis.css('padding-left', function(multiLine) {
|
|
||||||
var width = lineNumsElem.outerWidth();
|
// 若超出 100 行
|
||||||
return multiLine && width > 45 ? width : null;
|
if (multiLine && width > CONST.LINE_RAW_WIDTH) {
|
||||||
}(Math.floor(lines.length / 100) && options.ln));
|
lay.getStyleRules(styleElem, function(item, i) {
|
||||||
|
try {
|
||||||
|
cssRules[i].setValue(item, width);
|
||||||
|
} catch(e) { }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return fn;
|
return fn;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// 创建 header --- 后续版本将废弃该属性
|
// 创建 code header
|
||||||
if(options.header && !othis.children('.'+ CONST.ELEM_TITLE)[0]){
|
if (options.header) {
|
||||||
var headerElem = $('<div class="'+ CONST.ELEM_TITLE +'">');
|
var headerElem = $('<div class="'+ CONST.ELEM_HEADER +'"></div>');
|
||||||
headerElem.html((options.title || options.text.code) + (
|
headerElem.html(options.title || options.text.code);
|
||||||
options.about
|
|
||||||
? '<div class="layui-code-about">' + options.about + '</div>'
|
|
||||||
: ''
|
|
||||||
));
|
|
||||||
othis.prepend(headerElem);
|
othis.prepend(headerElem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 所有实例渲染完毕后的回调
|
// 创建 code 区域固定条
|
||||||
if(options.elem.length === index + 1){
|
var elemFixbar = $('<div class="layui-code-fixbar"></div>');
|
||||||
typeof options.allDone === 'function' && options.allDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 若开启复制,且未开启预览时,单独生成复制图标
|
// 若开启复制,且未开启预览,则单独生成复制图标
|
||||||
if(options.copy && !options.preview){
|
if(options.copy && !options.preview){
|
||||||
var elemCopy = $(['<span class="'+ CONST.ELEM_COPY +'">',
|
var copyElem = $(['<span class="layui-code-copy">',
|
||||||
'<i class="layui-icon layui-icon-file-b" title="复制"></i>',
|
'<i class="layui-icon layui-icon-file-b" title="复制"></i>',
|
||||||
'</span>'].join(''));
|
'</span>'].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();
|
tools.copy.event();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
elemFixbar.append(copyElem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// language marker
|
// 创建 language marker
|
||||||
if(options.langMarker){
|
if (options.langMarker) {
|
||||||
var elemMarker = $('<span class="layui-code-lang-marker">' + options.lang + '</span>')
|
elemFixbar.append('<span class="layui-code-lang-marker">' + options.lang + '</span>');
|
||||||
var elemMarkerHas = othis.children("." + CONST.ELEM_MARKER);
|
|
||||||
if(elemMarkerHas[0]) elemMarkerHas.remove();
|
|
||||||
othis.append(elemMarker);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建 about 自定义内容
|
||||||
|
if (options.about) {
|
||||||
|
elemFixbar.append(options.about);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成 code fixbar
|
||||||
|
othis.append(elemFixbar);
|
||||||
|
|
||||||
// code 渲染完毕后的回调
|
// code 渲染完毕后的回调
|
||||||
if (!options.preview) {
|
if (!options.preview) {
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
|
@ -478,7 +586,12 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
},3);
|
},3);
|
||||||
}
|
}
|
||||||
|
|
||||||
return inst;
|
// 所有实例渲染完毕后的回调
|
||||||
|
if(options.elem.length === index + 1){
|
||||||
|
typeof options.allDone === 'function' && options.allDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue