mirror of https://github.com/layui/layui
加强 code 代码预览组件功能
parent
7be36d05c6
commit
067a9a4c78
|
@ -6,18 +6,18 @@
|
||||||
html #layuicss-skincodecss{display:none; position: absolute; width:1989px;}
|
html #layuicss-skincodecss{display:none; position: absolute; width:1989px;}
|
||||||
|
|
||||||
/* 默认风格 */
|
/* 默认风格 */
|
||||||
.layui-code-view{display: block; position: relative; margin: 10px 0; padding: 0; border: 1px solid #eee; border-left-width: 6px; background-color: #FAFAFA; color: #333; font-family: Courier New; font-size: 13px;}
|
.layui-code-view{display: block; position: relative; margin: 11px 0; padding: 0; border: 1px solid #eee; border-left-width: 6px; background-color: #FAFAFA; color: #333; font-family: Courier New; font-size: 13px;}
|
||||||
.layui-code-title{position: relative; padding: 0 10px; height: 40px; line-height: 40px; border-bottom: 1px solid #eee; font-size: 12px;}
|
.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-title > .layui-code-about{position: absolute; right: 10px; top: 0; color: #B7B7B7;}
|
||||||
.layui-code-about > a{padding-left: 10px;}
|
.layui-code-about > a{padding-left: 10px;}
|
||||||
.layui-code-view > .layui-code-ol,
|
.layui-code-view > .layui-code-ol,
|
||||||
.layui-code-view > .layui-code-ul{position: relative; overflow: auto;}
|
.layui-code-view > .layui-code-ul{max-height: 100%; padding: 0 !important; position: relative; overflow: auto;}
|
||||||
.layui-code-view > .layui-code-ol > li{position: relative; margin-left: 45px; line-height: 20px; padding: 0 10px; border-left: 1px solid #e2e2e2; list-style-type: decimal-leading-zero; *list-style-type: decimal; background-color: #fff;}
|
.layui-code-view > .layui-code-ol > li{position: relative; margin-top: 0 !important; margin-left: 45px !important; line-height: 20px; padding: 0 10px !important; border-left: 1px solid #e2e2e2; list-style-type: decimal-leading-zero; *list-style-type: decimal; background-color: #fff;}
|
||||||
.layui-code-view > .layui-code-ol > li:first-child,
|
.layui-code-view > .layui-code-ol > li:first-child,
|
||||||
.layui-code-view > .layui-code-ul > li:first-child{padding-top: 10px;}
|
.layui-code-view > .layui-code-ul > li:first-child{padding-top: 10px !important;}
|
||||||
.layui-code-view > .layui-code-ol > li:last-child,
|
.layui-code-view > .layui-code-ol > li:last-child,
|
||||||
.layui-code-view > .layui-code-ul > li:last-child{padding-bottom: 10px;}
|
.layui-code-view > .layui-code-ul > li:last-child{padding-bottom: 10px !important;}
|
||||||
.layui-code-view > .layui-code-ul > li{position: relative; line-height: 20px; padding: 0 10px; list-style-type: none; *list-style-type: none; background-color: #fff;}
|
.layui-code-view > .layui-code-ul > li{position: relative; line-height: 20px; padding: 0 10px !important; list-style-type: none; *list-style-type: none; background-color: #fff;}
|
||||||
.layui-code-view pre{margin: 0;}
|
.layui-code-view pre{margin: 0;}
|
||||||
|
|
||||||
/* 深色风格 */
|
/* 深色风格 */
|
||||||
|
@ -28,5 +28,23 @@ html #layuicss-skincodecss{display:none; position: absolute; width:1989px;}
|
||||||
.layui-code-dark > .layui-code-ul > li{margin-left: 6px;}
|
.layui-code-dark > .layui-code-ul > li{margin-left: 6px;}
|
||||||
|
|
||||||
/* 代码预览 */
|
/* 代码预览 */
|
||||||
.layui-code-demo .layui-code{visibility: visible !important; margin: -15px; border-top: none; border-right: none; border-bottom: none;}
|
.layui-code textarea{display: none;}
|
||||||
.layui-code-demo .layui-tab-content{padding: 15px; border-top: none}
|
.layui-code-preview > .layui-code{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-code-item{display: none;}
|
||||||
|
.layui-code-preview .layui-code-view > .layui-code-ol > li{}
|
||||||
|
.layui-code-item-preview{position: relative; padding: 16px;}
|
||||||
|
.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 > i{display: inline-block; margin-left: 6px; padding: 3px; cursor: pointer;}
|
||||||
|
|
||||||
|
/* 全屏风格 */
|
||||||
|
.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-ol,
|
||||||
|
.layui-code-full .layui-code-ul{height: calc(100vh - 51px) !important; box-sizing: border-box;}
|
|
@ -1,22 +1,38 @@
|
||||||
/**
|
/**
|
||||||
* code
|
* code
|
||||||
* 代码块简易修饰
|
* Code 预览组件
|
||||||
*/
|
*/
|
||||||
|
|
||||||
layui.define(['lay', 'util'], function(exports){
|
layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var $ = layui.$;
|
var $ = layui.$;
|
||||||
var util = layui.util;
|
var util = layui.util;
|
||||||
|
var element = layui.element;
|
||||||
|
var form = layui.form;
|
||||||
|
|
||||||
var ELEM_TITLE = 'layui-code-title';
|
// 常量
|
||||||
|
var CONST = {
|
||||||
|
ELEM_VIEW: 'layui-code-view',
|
||||||
|
ELEM_TITLE: 'layui-code-title',
|
||||||
|
ELEM_FULL: 'layui-code-full',
|
||||||
|
ELEM_PREVIEW: 'layui-code-preview',
|
||||||
|
ELEM_ITEM: 'layui-code-item',
|
||||||
|
ELEM_SHOW: 'layui-show'
|
||||||
|
};
|
||||||
|
|
||||||
// 默认参数项
|
// 默认参数项
|
||||||
var config = {
|
var config = {
|
||||||
elem: '.layui-code', // 元素选择器
|
elem: '.layui-code', // 元素选择器
|
||||||
title: '</>', // 标题
|
title: '</>', // 标题
|
||||||
about: '', // 右上角信息
|
about: '', // 右上角信息
|
||||||
ln: true // 是否显示行号
|
ln: true, // 是否显示行号
|
||||||
|
header: false, // 是否显示头部区域
|
||||||
|
|
||||||
|
text: {
|
||||||
|
code: util.escape('</>'),
|
||||||
|
preview: 'Preview'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var trim = function(str){
|
var trim = function(str){
|
||||||
|
@ -25,7 +41,7 @@ layui.define(['lay', 'util'], function(exports){
|
||||||
|
|
||||||
// export api
|
// export api
|
||||||
exports('code', function(options){
|
exports('code', function(options){
|
||||||
var opts = options = $.extend({}, config, options);
|
var opts = options = $.extend(true, {}, config, options);
|
||||||
|
|
||||||
// 目标元素是否存在
|
// 目标元素是否存在
|
||||||
options.elem = $(options.elem);
|
options.elem = $(options.elem);
|
||||||
|
@ -37,7 +53,7 @@ layui.define(['lay', 'util'], function(exports){
|
||||||
var html = trim(othis.html());
|
var html = trim(othis.html());
|
||||||
|
|
||||||
// 合并属性上的参数,并兼容旧版本属性写法 lay-*
|
// 合并属性上的参数,并兼容旧版本属性写法 lay-*
|
||||||
var options = $.extend({}, opts, lay.options(item), function(obj){
|
var options = $.extend(true, {}, opts, lay.options(item), 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);
|
||||||
|
@ -48,12 +64,181 @@ layui.define(['lay', 'util'], function(exports){
|
||||||
return obj;
|
return obj;
|
||||||
}({}));
|
}({}));
|
||||||
|
|
||||||
|
// 获得代码
|
||||||
|
var codes = function(){
|
||||||
|
var arr = [];
|
||||||
|
var textarea = othis.children('textarea');
|
||||||
|
|
||||||
|
// 若内容放置在 textarea 中
|
||||||
|
textarea.each(function(){
|
||||||
|
arr.push(trim(this.value));
|
||||||
|
});
|
||||||
|
|
||||||
|
if(textarea[0]){
|
||||||
|
html = util.escape(arr.join(''));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内容直接放置在元素外层
|
||||||
|
if(arr.length === 0){
|
||||||
|
arr.push(trim(othis.html()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}();
|
||||||
|
|
||||||
|
// 是否开启预览
|
||||||
|
if(options.preview){
|
||||||
|
var FILTER_VALUE = 'LAY-CODE-DF-'+ index;
|
||||||
|
var layout = options.layout || ['code', 'preview'];
|
||||||
|
var isIframePreview = options.preview === 'iframe';
|
||||||
|
|
||||||
|
// 追加 Tab 组件
|
||||||
|
var elemView = $('<div class="'+ CONST.ELEM_PREVIEW +'">');
|
||||||
|
var elemTabView = $('<div class="layui-tab layui-tab-brief">');
|
||||||
|
var elemHeaderView = $('<div class="layui-tab-title">');
|
||||||
|
var elemPreviewView = $('<div class="'+ [
|
||||||
|
CONST.ELEM_ITEM,
|
||||||
|
CONST.ELEM_ITEM +'-preview',
|
||||||
|
'layui-border'
|
||||||
|
].join(' ') +'">');
|
||||||
|
var elemToolbar = $('<div class="layui-code-tools"></div>');
|
||||||
|
var elemViewHas = othis.prev('.' + CONST.ELEM_PREVIEW);
|
||||||
|
var elemPreviewViewHas = othis.next('.' + CONST.ELEM_ITEM +'-preview');
|
||||||
|
|
||||||
|
if(options.id) elemView.attr('id', options.id);
|
||||||
|
elemTabView.attr('lay-filter', FILTER_VALUE);
|
||||||
|
|
||||||
|
// 标签头
|
||||||
|
layui.each(layout, function(i, v){
|
||||||
|
var li = $('<li lay-id="'+ v +'">');
|
||||||
|
if(i === 0) li.addClass('layui-this');
|
||||||
|
li.html(options.text[v]);
|
||||||
|
elemHeaderView.append(li);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 工具栏
|
||||||
|
var 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_SCOLLBAR_HIDE = 'layui-scollbar-hide';
|
||||||
|
|
||||||
|
if(el.hasClass(classNameFull)){
|
||||||
|
elemView.addClass(CONST.ELEM_FULL);
|
||||||
|
el.removeClass(classNameFull).addClass(classNameRestore);
|
||||||
|
el.attr('title', title[1]);
|
||||||
|
html.addClass(ELEM_SCOLLBAR_HIDE);
|
||||||
|
} else {
|
||||||
|
elemView.removeClass(CONST.ELEM_FULL);
|
||||||
|
el.removeClass(classNameRestore).addClass(classNameFull);
|
||||||
|
el.attr('title', title[0]);
|
||||||
|
html.removeClass(ELEM_SCOLLBAR_HIDE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'window': {
|
||||||
|
className: 'release',
|
||||||
|
title: ['在新窗口预览'],
|
||||||
|
event: function(el, type){
|
||||||
|
util.openWin({
|
||||||
|
content: codes.join('')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
elemToolbar.on('click', '>i', function(){ // 工具栏事件
|
||||||
|
var oi = $(this);
|
||||||
|
var type = oi.data('type');
|
||||||
|
typeof tools[type].event === 'function' && tools[type].event(oi, type);
|
||||||
|
typeof options.toolsEvent === 'function' && options.toolsEvent(oi, type);
|
||||||
|
});
|
||||||
|
layui.each(options.tools, function(i, v){
|
||||||
|
var className = (tools[v] && tools[v].className) || v;
|
||||||
|
var title = tools[v].title || [''];
|
||||||
|
elemToolbar.append(
|
||||||
|
'<i class="layui-icon layui-icon-'+ className +'" data-type="'+ v +'" title="'+ title[0] +'"></i>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 移除旧结构
|
||||||
|
if(elemViewHas[0]) elemViewHas.remove();
|
||||||
|
if(elemPreviewViewHas[0]) elemPreviewViewHas.remove();
|
||||||
|
|
||||||
|
elemTabView.append(elemHeaderView); // 追加标签头
|
||||||
|
options.tools && elemTabView.append(elemToolbar); // 追加工具栏
|
||||||
|
othis.wrap(elemView).addClass(CONST.ELEM_ITEM).before(elemTabView); // 追加标签结构
|
||||||
|
|
||||||
|
|
||||||
|
// 追加预览
|
||||||
|
if(isIframePreview){
|
||||||
|
elemPreviewView.html('<iframe></iframe>');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行预览
|
||||||
|
var run = function(thisItemBody){
|
||||||
|
var iframe = thisItemBody.children('iframe')[0];
|
||||||
|
if(isIframePreview && iframe){
|
||||||
|
iframe.srcdoc = codes.join('');
|
||||||
|
} else {
|
||||||
|
thisItemBody.html(codes.join(''));
|
||||||
|
}
|
||||||
|
// 回调的返回参数
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内容项初始化样式
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// 有序或无序列表
|
// 有序或无序列表
|
||||||
var listTag = options.ln ? 'ol' : 'ul';
|
var listTag = options.ln ? 'ol' : 'ul';
|
||||||
var listElem = $('<'+ listTag +' class="layui-code-'+ listTag +'">');
|
var listElem = $('<'+ listTag +' class="layui-code-'+ listTag +'">');
|
||||||
|
|
||||||
// header
|
// header
|
||||||
var headerElem = $('<div class="'+ ELEM_TITLE +'">');
|
var headerElem = $('<div class="'+ CONST.ELEM_TITLE +'">');
|
||||||
|
|
||||||
// 添加组件 clasName
|
// 添加组件 clasName
|
||||||
othis.addClass('layui-code-view layui-box');
|
othis.addClass('layui-code-view layui-box');
|
||||||
|
@ -72,7 +257,7 @@ layui.define(['lay', 'util'], function(exports){
|
||||||
othis.html(listElem.html('<li>' + html + '</li>'));
|
othis.html(listElem.html('<li>' + html + '</li>'));
|
||||||
|
|
||||||
// 创建 header
|
// 创建 header
|
||||||
if(!othis.children('.'+ ELEM_TITLE)[0]){
|
if(options.header && !othis.children('.'+ CONST.ELEM_TITLE)[0]){
|
||||||
headerElem.html(options.title + (
|
headerElem.html(options.title + (
|
||||||
options.about
|
options.about
|
||||||
? '<div class="layui-code-about">' + options.about + '</div>'
|
? '<div class="layui-code-about">' + options.about + '</div>'
|
||||||
|
@ -81,6 +266,11 @@ layui.define(['lay', 'util'], function(exports){
|
||||||
othis.prepend(headerElem);
|
othis.prepend(headerElem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 所有实例渲染完毕后的回调
|
||||||
|
if(options.elem.length === index + 1){
|
||||||
|
typeof options.allDone === 'function' && options.allDone();
|
||||||
|
}
|
||||||
|
|
||||||
// 按行数适配左边距
|
// 按行数适配左边距
|
||||||
(function(autoIncNums){
|
(function(autoIncNums){
|
||||||
if(autoIncNums > 0){
|
if(autoIncNums > 0){
|
||||||
|
@ -88,10 +278,12 @@ layui.define(['lay', 'util'], function(exports){
|
||||||
}
|
}
|
||||||
})(Math.floor(listElem.find('li').length/100));
|
})(Math.floor(listElem.find('li').length/100));
|
||||||
|
|
||||||
// 限制最大高度
|
// 限制 Code 最大高度
|
||||||
if(options.height){
|
if(options.height){ // 兼容旧版本
|
||||||
listElem.css('max-height', options.height);
|
listElem.css('max-height', options.height);
|
||||||
}
|
}
|
||||||
|
// Code 内容区域样式
|
||||||
|
listElem.attr('style', options.codeStyle);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue