2021-05-08 06:31:19 +08:00
|
|
|
|
/**
|
2023-09-03 21:25:03 +08:00
|
|
|
|
* code
|
2023-01-29 01:12:39 +08:00
|
|
|
|
* Code 预览组件
|
2017-08-21 08:51:13 +08:00
|
|
|
|
*/
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2023-01-29 01:12:39 +08:00
|
|
|
|
layui.define(['lay', 'util', 'element', 'form'], function(exports){
|
2017-08-21 08:51:13 +08:00
|
|
|
|
"use strict";
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2017-08-21 08:51:13 +08:00
|
|
|
|
var $ = layui.$;
|
2022-06-24 10:16:50 +08:00
|
|
|
|
var util = layui.util;
|
2023-01-29 01:12:39 +08:00
|
|
|
|
var element = layui.element;
|
|
|
|
|
var form = layui.form;
|
2023-05-04 09:52:13 +08:00
|
|
|
|
var layer = layui.layer;
|
2023-09-06 20:58:48 +08:00
|
|
|
|
var hint = layui.hint();
|
2022-06-29 20:24:51 +08:00
|
|
|
|
|
2023-01-29 01:12:39 +08:00
|
|
|
|
// 常量
|
|
|
|
|
var CONST = {
|
|
|
|
|
ELEM_VIEW: 'layui-code-view',
|
2023-03-14 09:55:13 +08:00
|
|
|
|
ELEM_TAB: 'layui-tab',
|
2023-09-06 20:58:48 +08:00
|
|
|
|
ELEM_HEADER: 'layui-code-header',
|
2023-01-29 01:12:39 +08:00
|
|
|
|
ELEM_FULL: 'layui-code-full',
|
|
|
|
|
ELEM_PREVIEW: 'layui-code-preview',
|
|
|
|
|
ELEM_ITEM: 'layui-code-item',
|
2023-09-03 21:25:03 +08:00
|
|
|
|
ELEM_SHOW: 'layui-show',
|
|
|
|
|
ELEM_LINE: 'layui-code-line',
|
2023-09-06 20:58:48 +08:00
|
|
|
|
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 保持一致
|
2023-01-29 01:12:39 +08:00
|
|
|
|
};
|
2022-06-29 20:24:51 +08:00
|
|
|
|
|
|
|
|
|
// 默认参数项
|
|
|
|
|
var config = {
|
2023-09-06 20:58:48 +08:00
|
|
|
|
elem: '', // 元素选择器
|
2023-03-14 09:55:13 +08:00
|
|
|
|
about: '', // 代码栏右上角信息
|
|
|
|
|
ln: true, // 代码区域是否显示行号
|
|
|
|
|
header: false, // 是否显示代码栏头部区域
|
2023-05-04 09:52:13 +08:00
|
|
|
|
encode: true, // 是否对 code 进行编码(若开启预览,则强制开启)
|
|
|
|
|
copy: true, // 是否开启代码区域复制功能图标
|
2023-03-14 09:55:13 +08:00
|
|
|
|
// 默认文本
|
2023-01-29 01:12:39 +08:00
|
|
|
|
text: {
|
|
|
|
|
code: util.escape('</>'),
|
2023-09-03 21:25:03 +08:00
|
|
|
|
preview: 'Preview',
|
|
|
|
|
},
|
2023-09-06 20:58:48 +08:00
|
|
|
|
wordWrap: true, // 是否自动换行
|
2023-09-03 21:25:03 +08:00
|
|
|
|
lang: 'text', // 指定语言类型
|
2023-09-06 20:58:48 +08:00
|
|
|
|
highlighter: false, // 是否开启语法高亮,'hljs','prism','shiki'
|
2023-09-03 21:25:03 +08:00
|
|
|
|
langMarker: false, // 代码区域是否显示语言类型标记
|
2022-06-29 20:24:51 +08:00
|
|
|
|
};
|
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 初始索引
|
|
|
|
|
var codeIndex = layui.code ? (layui.code.index + 10000) : 0;
|
|
|
|
|
|
|
|
|
|
// 去除尾部空格
|
2023-09-03 21:25:03 +08:00
|
|
|
|
var trimEnd = function(str){
|
2023-09-05 16:30:07 +08:00
|
|
|
|
return String(str).replace(/\s+$/, '');
|
2023-09-03 21:25:03 +08:00
|
|
|
|
}
|
|
|
|
|
// 保留首行缩进
|
2022-06-29 20:24:51 +08:00
|
|
|
|
var trim = function(str){
|
2023-09-03 21:25:03 +08:00
|
|
|
|
return trimEnd(str).replace(/^\n|\n$/, '');
|
2022-06-29 20:24:51 +08:00
|
|
|
|
};
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2022-06-29 20:24:51 +08:00
|
|
|
|
// export api
|
2023-09-06 20:58:48 +08:00
|
|
|
|
exports('code', function(options, mode){
|
|
|
|
|
options = $.extend(true, {}, config, options);
|
|
|
|
|
|
|
|
|
|
// 返回对象
|
|
|
|
|
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');
|
2023-09-05 16:30:07 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 若 elem 非唯一
|
|
|
|
|
var elem = $(options.elem);
|
|
|
|
|
if(elem.length > 1){
|
|
|
|
|
// 是否正向渲染
|
|
|
|
|
layui.each(options.obverse ? elem : elem.get().reverse(), function(){
|
|
|
|
|
layui.code($.extend({}, options, {
|
|
|
|
|
elem: this
|
2023-09-06 20:58:48 +08:00
|
|
|
|
}), mode);
|
2023-09-05 16:30:07 +08:00
|
|
|
|
});
|
2023-09-06 20:58:48 +08:00
|
|
|
|
return ret;
|
2023-09-05 16:30:07 +08:00
|
|
|
|
}
|
2022-06-29 20:24:51 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 目标元素是否存在
|
|
|
|
|
var othis = options.elem = $(options.elem);
|
2023-09-06 20:58:48 +08:00
|
|
|
|
if(!othis[0]) return ret;
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
|
|
|
|
// 合并属性上的参数,并兼容旧版本属性写法 lay-*
|
2023-09-06 20:58:48 +08:00
|
|
|
|
$.extend(true, options, lay.options(othis[0]), function(obj){
|
2023-09-05 16:30:07 +08:00
|
|
|
|
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;
|
|
|
|
|
}({}));
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// codeRender 需要关闭编码
|
|
|
|
|
// 未使用 codeRender 时若开启了预览,则强制开启编码
|
|
|
|
|
options.encode = (options.encode || options.preview) && !options.codeRender;
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 最终显示的代码
|
|
|
|
|
var finalCode;
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 获得初始 code
|
|
|
|
|
var rawCode = othis.data(CONST.CDDE_DATA_CODE) || function(){
|
2023-09-05 16:30:07 +08:00
|
|
|
|
var arr = [];
|
|
|
|
|
var textarea = othis.children('textarea');
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 若内容放置在 textarea 中
|
|
|
|
|
textarea.each(function(){
|
|
|
|
|
arr.push(trim(this.value));
|
|
|
|
|
});
|
2023-01-29 01:12:39 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 内容直接放置在元素外层
|
|
|
|
|
if(arr.length === 0){
|
|
|
|
|
arr.push(trim(othis.html()));
|
|
|
|
|
}
|
2023-03-14 09:55:13 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
return arr;
|
|
|
|
|
}();
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 记录初始 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'));
|
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
|
|
|
|
// code
|
|
|
|
|
var html = finalCode = rawCode.join('');
|
|
|
|
|
|
|
|
|
|
// 外部重新解析 code
|
|
|
|
|
if(typeof options.codeParse === 'function'){
|
|
|
|
|
html = finalCode = options.codeParse(html);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 工具栏
|
|
|
|
|
var tools = {
|
|
|
|
|
copy: {
|
|
|
|
|
className: 'file-b',
|
|
|
|
|
title: ['复制代码'],
|
2023-09-06 20:58:48 +08:00
|
|
|
|
event: function(obj){
|
2023-09-05 16:30:07 +08:00
|
|
|
|
var code = util.unescape(finalCode);
|
|
|
|
|
|
|
|
|
|
// 写入剪切板
|
|
|
|
|
lay.clipboard.writeText({
|
|
|
|
|
text: code,
|
|
|
|
|
done: function() {
|
|
|
|
|
layer.msg('已复制', {icon: 1});
|
|
|
|
|
},
|
|
|
|
|
error: function() {
|
|
|
|
|
layer.msg('复制失败', {icon: 2});
|
|
|
|
|
}
|
|
|
|
|
});
|
2023-06-24 23:47:25 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
typeof options.onCopy === 'function' && options.onCopy(code);
|
|
|
|
|
}
|
2023-06-24 23:47:25 +08:00
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
};
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 移除包裹结构
|
|
|
|
|
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;
|
|
|
|
|
})();
|
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 是否开启预览
|
|
|
|
|
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>');
|
2023-09-06 20:58:48 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
|
|
|
|
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 = $('<li lay-id="'+ v +'">');
|
|
|
|
|
if(i === 0) li.addClass('layui-this');
|
|
|
|
|
li.html(options.text[v]);
|
|
|
|
|
elemHeaderView.append(li);
|
|
|
|
|
});
|
2023-06-24 23:47:25 +08:00
|
|
|
|
|
2023-05-04 09:52:13 +08:00
|
|
|
|
// 工具栏
|
2023-09-05 16:30:07 +08:00
|
|
|
|
$.extend(tools, {
|
|
|
|
|
'full': {
|
|
|
|
|
className: 'screen-full',
|
|
|
|
|
title: ['最大化显示', '还原显示'],
|
2023-09-06 20:58:48 +08:00
|
|
|
|
event: function(obj){
|
|
|
|
|
var el = obj.elem;
|
2023-09-05 16:30:07 +08:00
|
|
|
|
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: ['在新窗口预览'],
|
2023-09-06 20:58:48 +08:00
|
|
|
|
event: function(obj){
|
2023-09-05 16:30:07 +08:00
|
|
|
|
util.openWin({
|
|
|
|
|
content: finalCode
|
2023-09-01 23:45:00 +08:00
|
|
|
|
});
|
2023-05-04 09:52:13 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// copy
|
|
|
|
|
if(options.copy){
|
|
|
|
|
if(layui.type(options.tools) === 'array'){
|
|
|
|
|
// 若 copy 未存在于 tools 中,则追加到最前
|
|
|
|
|
if(options.tools.indexOf('copy') === -1){
|
|
|
|
|
options.tools.unshift('copy');
|
2023-05-26 12:17:19 +08:00
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
} else {
|
|
|
|
|
options.tools = ['copy'];
|
2023-05-04 09:52:13 +08:00
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
}
|
2023-05-04 09:52:13 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 工具栏事件
|
|
|
|
|
elemToolbar.on('click', '>i', function(){
|
|
|
|
|
var oi = $(this);
|
|
|
|
|
var type = oi.data('type');
|
2023-09-06 20:58:48 +08:00
|
|
|
|
var parameters = {
|
2023-09-05 16:30:07 +08:00
|
|
|
|
elem: oi,
|
|
|
|
|
type: type,
|
2023-09-10 20:21:22 +08:00
|
|
|
|
options: options, // 当前属性选项
|
2023-09-05 16:30:07 +08:00
|
|
|
|
rawCode: rawCode.join(''), // 原始 code
|
|
|
|
|
finalCode: util.unescape(finalCode) // 最终 code
|
2023-09-06 20:58:48 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 内部 tools event
|
|
|
|
|
tools[type] && typeof tools[type].event === 'function' && tools[type].event(parameters);
|
|
|
|
|
|
|
|
|
|
// 外部 tools event
|
|
|
|
|
typeof options.toolsEvent === 'function' && options.toolsEvent(parameters);
|
2023-09-05 16:30:07 +08:00
|
|
|
|
});
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 增加工具栏
|
|
|
|
|
if (options.addTools) {
|
|
|
|
|
options.tools = [].concat(options.tools || [], options.addTools);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 渲染工具栏
|
|
|
|
|
layui.each(options.tools, function(i, v){
|
|
|
|
|
var viso = typeof v === 'object'; // 若为 object 值,则可自定义更多属性
|
|
|
|
|
var tool = viso ? v : (
|
|
|
|
|
tools[v] || {
|
|
|
|
|
className: v,
|
|
|
|
|
title: [v]
|
|
|
|
|
}
|
|
|
|
|
);
|
2023-09-02 23:45:00 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
var className = tool.className || tool.type;
|
|
|
|
|
var title = tool.title || [''];
|
|
|
|
|
var type = viso ? ( tool.type || className ) : v;
|
2023-09-02 23:45:00 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
if (!type) return;
|
2023-01-29 01:12:39 +08:00
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 若非内置 tool,则合并到 tools 中
|
|
|
|
|
if (!tools[type]) {
|
|
|
|
|
var obj = {};
|
|
|
|
|
obj[type] = tool;
|
|
|
|
|
$.extend(tools, obj);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
elemToolbar.append(
|
|
|
|
|
'<i class="layui-icon layui-icon-'+ className +'" data-type="'+ type +'" title="'+ title[0] +'"></i>'
|
|
|
|
|
);
|
|
|
|
|
});
|
2023-01-29 01:12:39 +08:00
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
othis.addClass(CONST.ELEM_ITEM).wrap(elemView); // 包裹外层容器
|
2023-09-05 16:30:07 +08:00
|
|
|
|
elemTabView.append(elemHeaderView); // 追加标签头
|
|
|
|
|
options.tools && elemTabView.append(elemToolbar); // 追加工具栏
|
2023-09-06 20:58:48 +08:00
|
|
|
|
othis.before(elemTabView); // 追加标签结构
|
2023-01-29 01:12:39 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 追加预览
|
|
|
|
|
if(isIframePreview){
|
|
|
|
|
elemPreviewView.html('<iframe allowtransparency="true" frameborder="0"></iframe>');
|
|
|
|
|
}
|
2023-01-29 01:12:39 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 执行预览
|
|
|
|
|
var run = function(thisItemBody){
|
|
|
|
|
var iframe = thisItemBody.children('iframe')[0];
|
|
|
|
|
if(isIframePreview && iframe){
|
|
|
|
|
iframe.srcdoc = finalCode;
|
2023-01-29 01:12:39 +08:00
|
|
|
|
} else {
|
2023-09-05 16:30:07 +08:00
|
|
|
|
thisItemBody.html(rawCode.join(''));
|
2023-01-29 01:12:39 +08:00
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 回调的返回参数
|
|
|
|
|
var params = {
|
|
|
|
|
container: thisItemBody,
|
|
|
|
|
render: function(){
|
|
|
|
|
form.render(thisItemBody.find('.layui-form'));
|
|
|
|
|
element.render();
|
2023-01-29 01:12:39 +08:00
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
};
|
2022-06-29 20:24:51 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 当前实例预览完毕后的回调
|
|
|
|
|
setTimeout(function(){
|
|
|
|
|
typeof options.done === 'function' && options.done(params);
|
|
|
|
|
},3);
|
|
|
|
|
};
|
2022-06-29 20:24:51 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
if(layout[0] === 'preview'){
|
|
|
|
|
elemPreviewView.addClass(CONST.ELEM_SHOW);
|
|
|
|
|
othis.before(elemPreviewView);
|
|
|
|
|
run(elemPreviewView);
|
|
|
|
|
} else {
|
|
|
|
|
othis.addClass(CONST.ELEM_SHOW).after(elemPreviewView);
|
2023-08-29 10:36:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 内容项初始化样式
|
|
|
|
|
options.previewStyle = [options.style, options.previewStyle].join('');
|
|
|
|
|
elemPreviewView.attr('style', options.previewStyle);
|
2023-03-14 09:55:13 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// 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);
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
elemItemBody.removeClass(CONST.ELEM_SHOW);
|
|
|
|
|
thisItemBody.addClass(CONST.ELEM_SHOW);
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
if($this.attr('lay-id') === 'preview'){
|
|
|
|
|
run(thisItemBody);
|
|
|
|
|
}
|
2023-09-03 21:25:03 +08:00
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
setCodeLayout();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建 code 容器
|
2023-09-06 20:58:48 +08:00
|
|
|
|
var codeElem = $('<code class="layui-code-wrap"></code>'); // 此处的闭合标签是为了兼容 IE8
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
|
|
|
|
// 添加主容器 className
|
2023-09-06 20:58:48 +08:00
|
|
|
|
othis.addClass(function(arr) {
|
|
|
|
|
if (!options.wordWrap) arr.push('layui-code-nowrap');
|
|
|
|
|
return arr.join(' ')
|
|
|
|
|
}(['layui-code-view layui-border-box']));
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加高亮必要的 className
|
|
|
|
|
if (options.highlighter) {
|
|
|
|
|
othis.addClass([
|
|
|
|
|
options.highlighter,
|
|
|
|
|
'language-' + options.lang,
|
|
|
|
|
'layui-code-hl'
|
|
|
|
|
].join(' '));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 转义 HTML 标签
|
|
|
|
|
if(options.encode) html = util.escape(html); // 编码
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
var createCodeRst = createCode(html);
|
|
|
|
|
var lines = createCodeRst.lines;
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 插入 code
|
|
|
|
|
othis.html(codeElem.html(createCodeRst.html));
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 插入行号边栏
|
|
|
|
|
if (options.ln) {
|
|
|
|
|
othis.append('<div class="layui-code-ln-side"></div>');
|
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 兼容旧版本 height 属性
|
|
|
|
|
if (options.height) {
|
|
|
|
|
codeElem.css('max-height', options.height);
|
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
|
|
|
|
// code 区域样式
|
2023-09-06 20:58:48 +08:00
|
|
|
|
options.codeStyle = [options.style, options.codeStyle].join('');
|
2023-09-05 16:30:07 +08:00
|
|
|
|
if (options.codeStyle) {
|
2023-09-06 20:58:48 +08:00
|
|
|
|
codeElem.attr('style', function(i, val) {
|
2023-09-05 16:30:07 +08:00
|
|
|
|
return (val || '') + options.codeStyle;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 动态设置样式
|
|
|
|
|
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';
|
|
|
|
|
}
|
2023-09-03 21:25:03 +08:00
|
|
|
|
}
|
2023-09-06 20:58:48 +08:00
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 生成初始 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('')
|
|
|
|
|
})
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 动态设置 code 布局
|
2023-09-05 16:30:07 +08:00
|
|
|
|
var setCodeLayout = (function fn() {
|
2023-09-06 20:58:48 +08:00
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
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) { }
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
|
|
|
|
return fn;
|
|
|
|
|
})();
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 创建 code header
|
|
|
|
|
if (options.header) {
|
|
|
|
|
var headerElem = $('<div class="'+ CONST.ELEM_HEADER +'"></div>');
|
|
|
|
|
headerElem.html(options.title || options.text.code);
|
2023-09-05 16:30:07 +08:00
|
|
|
|
othis.prepend(headerElem);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 创建 code 区域固定条
|
|
|
|
|
var elemFixbar = $('<div class="layui-code-fixbar"></div>');
|
2023-09-05 16:30:07 +08:00
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 若开启复制,且未开启预览,则单独生成复制图标
|
2023-09-05 16:30:07 +08:00
|
|
|
|
if(options.copy && !options.preview){
|
2023-09-06 20:58:48 +08:00
|
|
|
|
var copyElem = $(['<span class="layui-code-copy">',
|
2023-09-05 16:30:07 +08:00
|
|
|
|
'<i class="layui-icon layui-icon-file-b" title="复制"></i>',
|
|
|
|
|
'</span>'].join(''));
|
|
|
|
|
|
|
|
|
|
// 点击复制
|
2023-09-06 20:58:48 +08:00
|
|
|
|
copyElem.on('click', function(){
|
2023-09-05 16:30:07 +08:00
|
|
|
|
tools.copy.event();
|
|
|
|
|
});
|
2023-09-06 20:58:48 +08:00
|
|
|
|
|
|
|
|
|
elemFixbar.append(copyElem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建 language marker
|
|
|
|
|
if (options.langMarker) {
|
|
|
|
|
elemFixbar.append('<span class="layui-code-lang-marker">' + options.lang + '</span>');
|
2023-09-05 16:30:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 创建 about 自定义内容
|
|
|
|
|
if (options.about) {
|
|
|
|
|
elemFixbar.append(options.about);
|
2023-09-05 16:30:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 生成 code fixbar
|
|
|
|
|
othis.append(elemFixbar);
|
|
|
|
|
|
2023-09-05 16:30:07 +08:00
|
|
|
|
// code 渲染完毕后的回调
|
|
|
|
|
if (!options.preview) {
|
|
|
|
|
setTimeout(function(){
|
|
|
|
|
typeof options.done === 'function' && options.done({});
|
|
|
|
|
},3);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 20:58:48 +08:00
|
|
|
|
// 所有实例渲染完毕后的回调
|
|
|
|
|
if(options.elem.length === index + 1){
|
|
|
|
|
typeof options.allDone === 'function' && options.allDone();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
2017-08-21 08:51:13 +08:00
|
|
|
|
});
|
2022-08-31 01:45:37 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 若为源码版,则自动加载该组件依赖的 css 文件
|
|
|
|
|
if(!layui['layui.all']){
|
2023-09-07 10:25:33 +08:00
|
|
|
|
layui.addcss('modules/code.css?v=6', 'skincodecss');
|
2023-08-29 10:36:38 +08:00
|
|
|
|
}
|