]+>/gi, ''))
body.html(body.html().replace(/<\/span>/gi, ''))
body.html(body.html().replace(//g, ''))
body.html(body.html().replace(/<\/P>/g, ''))
body.html(body.html().replace(/
<\/p>/g, '')) //移除空p
//clean word end
//清除影响版面的css属性
//body.find('*[style]').each(function () {
// var textAlign = this.style.textAlign;
// this.removeAttribute('style');
// $(this).css({
// 'text-align': textAlign || ''
// })
//});
// 移除不安全的标签
// body.find('script,link').remove();
////修饰表格
//body.find('table').addClass('layui-table');
},
//Range对象兼容性处理
Range = function (iframeDOM) {
const selection = iframeDOM.getSelection()
return iframeDOM.selection ? iframeDOM.selection.createRange() : selection.rangeCount && selection.getRangeAt(0)
},
//当前Range对象的endContainer兼容性处理
getContainer = function (range) {
if (!range) return
return range.endContainer || range.parentElement().childNodes[0]
},
//在选区插入内联元素
insertInline = function (tagName, attr, range) {
var iframeDOM = this.document,
elem = document.createElement(tagName)
for (var key in attr) {
elem.setAttribute(key, attr[key])
}
elem.removeAttribute('text')
// be fix by knifeZ
if (device.ie) {
//IE
var text = range.text || attr.text
if (tagName === 'a' && !text) return
if (text) {
elem.innerHTML = text
}
layer.msg('暂不支持IE浏览器')
range.selectNode(this.document.body.childNodes.item(0))
range.insertNode(elem)
} else {
//非IE
var text = range.toString() || attr.text
if (tagName === 'a' && !text) return
if (text) {
elem.innerHTML = text
}
var container = getContainer(range),
parentNode = container.parentNode
//var elep = document.createElement('p');
//if (tagName != "pre" && tagName != "span" && tagName != "p" && tagName != "a" && tagName != "hr" && tagName != "div" && parentNode.tagName != "P" && container.innerHTML != " ") {
// elep.appendChild(elem);
//} else {
// elep = elem;
//}
//处理换行
if (container.innerHTML == ' ') {
range.selectNode(container)
range.deleteContents()
}
range.deleteContents()
range.insertNode(elem)
//图片默认居中
// if (tagName == 'img' && container.innerHTML == ' ') {
// iframeDOM.execCommand('formatBlock', false, '
')
// iframeDOM.execCommand('justifyCenter')
// setTimeout(function () {
// body.focus()
// }, 10)
// }
}
},
// 批量在选区插入内联元素 - 此处服务于图片
insertInlineAll = function (data, range) {
var iframeDOM = this.document
var elems = []
for (var i = 0; i < data.length; i++) {
elems[i] = document.createElement(data[i].tagName)
for (var key in data[i].attr) {
elems[i].setAttribute(key, data[i].attr[key])
}
elems[i].removeAttribute('text')
}
if (iframeDOM.selection) {
//IE
var text = range.text || attr.text
if (tagName === 'a' && !text) return
if (text) {
elem.innerHTML = text
}
range.pasteHTML($(elems).prop('outerHTML'))
range.select()
} else {
//非IE
/*
var text = range.toString() || attr.text;
if (tagName === 'a' && !text) return;
if (text) {
elem.innerHTML = text;
}
*/
range.deleteContents()
for (var j = 0; j < elems.length; j++) {
var text = range.toString() || data[j].attr.text
// if (data[j].tagName === 'a' && !text) return;
if (text) {
elem.innerHTML = text
}
range.insertNode(elems[j])
}
}
},
//工具选中
toolCheck = function (tools, othis) {
var iframeDOM = this.document,
CHECK = 'layedit-tool-active',
container = getContainer(Range(iframeDOM)),
item = function (type) {
return tools.find('.layedit-tool-' + type)
}
if (othis) {
othis[othis.hasClass(CHECK) ? 'removeClass' : 'addClass'](CHECK)
}
tools.find('>i').removeClass(CHECK)
item('unlink').addClass(ABLED)
$(container)
.parents()
.each(function () {
var tagName = this.tagName.toLowerCase(),
textAlign = this.style.textAlign
//be fix by kinfeZ
//文字
//if (tagName === 'b' || tagName === 'strong') {
// item('b').addClass(CHECK)
//}
//if (tagName === 'i' || tagName === 'em') {
// item('i').addClass(CHECK)
//}
//if (tagName === 'u') {
// item('u').addClass(CHECK)
//}
//if (tagName === 'strike') {
// item('d').addClass(CHECK)
//}
//对齐
if (tagName === 'p') {
if (textAlign === 'center') {
item('center').addClass(CHECK)
} else if (textAlign === 'right') {
item('right').addClass(CHECK)
} else {
item('left').addClass(CHECK)
}
}
//超链接
if (tagName === 'a') {
item('link').addClass(CHECK)
item('unlink').removeClass(ABLED)
}
})
},
//触发工具
toolActive = function (iframeWin, editor, set) {
var iframeDOM = iframeWin.document,
body = $(iframeDOM.body),
toolEvent = {
//超链接
link: function (range) {
var container = getContainer(range),
parentNode = $(container).parent()
link.call(
body,
{
href: parentNode.attr('href'),
target: parentNode.attr('target'),
rel: parentNode.attr('rel'),
text: parentNode.attr('text') || range.toString(),
dmode: set.devmode,
},
function (field) {
var parent = parentNode[0]
if (parent.tagName === 'A') {
parent.href = field.url
parent.rel = field.rel
if (field.rel == '') {
parent.removeAttr('rel')
}
parent.target = field.target
if (field.target == '_self' || field.target == undefined) {
parent.removeAttr('target')
}
if (field.text != '') {
parent.text = field.text
}
} else {
var data = {
target: field.target,
href: field.url,
rel: field.rel,
text: field.text,
}
if (field.rel == '' || field.rel == undefined) {
delete data['rel']
}
if (field.target == '_self' || field.target == undefined) {
delete data['target']
}
if (field.text == '') {
data['text'] = data['href']
}
insertInline.call(iframeWin, 'a', data, range)
}
}
)
},
//清除超链接
unlink: function (range) {
iframeDOM.execCommand('unlink')
},
//表情
face: function (range) {
face.call(this, { facePath: set.facePath }, function (img) {
insertInline.call(
iframeWin,
'img',
{
src: img.src,
alt: img.alt,
},
range
)
setTimeout(function () {
body.focus()
}, 10)
})
},
//图片
// image: function (range) {
// var that = this
// layui.use('upload', function (upload) {
// var uploadImage = set.uploadImage || {}
// if (uploadImage.url == '') {
// layer.msg('上传接口配置错误!')
// }
// upload.render({
// url: uploadImage.url,
// method: uploadImage.method,
// field: uploadImage.field,
// data: uploadImage.data,
// headers: uploadImage.headers,
// accept: uploadImage.accept || 'image',
// acceptMime: uploadImage.acceptMime || 'image/*',
// exts: uploadImage.exts || 'jpg|png|gif|bmp|jpeg',
// size: uploadImage.size || 1024 * 10,
// elem: $(that).find('input')[0],
// done: function (res) {
// if (res.code == 0) {
// res.data = res.data || {}
// insertInline.call(
// iframeWin,
// 'img',
// {
// src: res.data.src,
// alt: res.data.title,
// },
// range
// )
// uploadImage.done(res)
// setTimeout(function () {
// body.focus()
// }, 10)
// } else {
// layer.msg(res.msg || '上传失败')
// }
// },
// })
// })
// },
image: function (range) {
var uploadImage = set.uploadImage || {}
var windows = layer.open({type: 2, title: "上传图片", content: uploadImage.url, area: ["90%", "90%"]});
window.callback = function (uri) {
var uriArr = []
uri.forEach(function (item) {
uriArr.push({
tagName: 'img',
attr: {
src: item,
},
})
// insertInline.call(iframeWin, "img", {src: item}, range)
});
insertInlineAll.call(iframeWin, uriArr, range)
};
// window.callbackSetUri = function (uri) {
// console.log(uri)
// insertInline.call(iframeWin, "img", {src: "/" + uri}, range);
// layer.close(windows)
// }
},
//插入代码
code: function (range) {
var codeConfig = set.codeConfig || { hide: false, encode: true, class: 'layui-code' }
code.call(body, { hide: codeConfig.hide, default: codeConfig.default }, function (pre) {
if (codeConfig.encode || true) {
pre.code = pre.code
.replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&')
.replace(//g, '>')
.replace(/'/g, ''')
.replace(/"/g, '"')
}
insertInline.call(
iframeWin,
'pre',
{
text: pre.code,
'lay-lang': pre.lang,
'lay-encode': codeConfig.encode,
class: codeConfig.class || 'layui-code',
},
range
)
setTimeout(function () {
layui.code()
body.focus()
}, 10)
})
},
/*#Extens#*/
//多图上传
images: function (range) {
var that = this
layer.open({
type: 1,
id: 'fly-jie-image-upload',
title: '图片管理',
shade: 0.05,
shadeClose: true,
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 485) {
return ['90%']
} else {
return ['485px']
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return '100px'
}
})(),
skin: 'layui-layer-border',
content: [
'
',
].join(''),
btn: ['确定', '取消'],
btnAlign: 'c',
yes: function (index, layero) {
var styleStr = ''
if (layero.find('input[name="imgWidth"]').val() != '') {
var w = layero.find('input[name="imgWidth"]').val()
styleStr += w.indexOf('%') > 0 ? 'width:' + w + ';' : 'width:' + w + 'px;'
}
if (layero.find('input[name="imgHeight"]').val() != '') {
var h = layero.find('input[name="imgHeight"]').val()
styleStr += h.indexOf('%') > 0 ? 'height:' + h + ';' : 'height:' + h + 'px;'
}
if (layero.find('#imgsPrev').find('img').length === 0) {
layer.msg('请选择要插入的图片')
} else {
/*
if (styleStr != "") styleStr = "style='" + styleStr + "'";
insertInline.call(iframeWin, 'p', {
text: layero.find('#imgsPrev').html().replace(new RegExp(/(style="max-width:70px;margin:2px")/g), styleStr)
}, range);
*/
var list = document.getElementById('imgsPrev').children
var objs = []
for (var i = 0; i < list.length; i++) {
objs.push({
tagName: 'img',
attr: {
src: list[i].src,
alt: list[i].alt,
style: styleStr,
},
})
}
insertInlineAll.call(iframeWin, objs, range)
layer.close(index)
}
},
btn2: function (index, layero) {
if (layero.find('#imgsPrev img').length > 0) {
var imgPaths = ''
for (var i = 0; i < layero.find('#imgsPrev img').length; i++) {
imgPaths += layero.find('#imgsPrev img')[i].src
}
var callDel = set.calldel
if (callDel.url != '') {
$.post(callDel.url, { imgpath: imgPaths }, function (res) {
callDel.done(res)
})
}
}
},
cancel: function (index, layero) {
if (layero.find('#imgsPrev img').length > 0) {
var imgPaths = ''
for (var i = 0; i < layero.find('#imgsPrev img').length; i++) {
imgPaths += layero.find('#imgsPrev img')[i].src
}
var callDel = set.calldel
if (callDel.url != '') {
$.post(callDel.url, { imgpath: imgPaths }, function (res) {
callDel.done(res)
})
}
}
},
success: function (layero, index) {
layui.use('upload', function () {
var upload = layui.upload
var uploadImage = set.uploadImage || {}
if (uploadImage.url == '') {
layer.msg('上传接口配置错误!')
}
var loding
var errorIndex = [] //上传接口出错的文件索引
//执行实例
upload.render({
elem: '#LayEdit_InsertImages',
url: uploadImage.url,
method: uploadImage.method,
data: uploadImage.data,
headers: uploadImage.headers,
accept: uploadImage.accept || 'image',
acceptMime: uploadImage.acceptMime || 'image/*',
exts: uploadImage.exts || 'jpg|png|gif|bmp|jpeg',
size: uploadImage.size || 1024 * 10,
field: uploadImage.field,
multiple: true,
before: function (obj) {
loding = layer.msg('文件上传中,请稍等', { icon: 16, shade: 0.3, time: 0 })
obj.preview(function (index, file, result) {
//由于有时预览会在allDone之后回调,此时所有单个文件的error已经执行,即已经出错的文件id以有,因此需要判断此预览文件id是否是上传出错文件的id,不是才预览
if (errorIndex.indexOf(index) === -1)
$('#imgsPrev').append(
' '
)
})
},
allDone: function () {
//所有上传操作完成后,删除出错的文件
for (var i = 0; i < errorIndex.length; i++) {
$('#imgsPrev')
.find('img[data-index="' + errorIndex[i] + '"]')
.remove()
}
layer.close(loding)
},
error: function (index, upload) {
//某文件上传接口返回错误时,将其错误index记录下来
errorIndex.push(index)
},
done: function (res, index, upload) {
if (res.code == 0) {
res.data = res.data || {}
$('#imgsPrev img[data-index="' + index + '"]').attr('src', res.data.src)
uploadImage.done(res)
} else if (res.code == 2) {
res.data = res.data || {}
$('#imgsPrev img[data-index="' + index + '"]').attr('src', res.data.src)
uploadImage.done(res)
} else {
layer.msg(res.msg || '上传失败')
}
layero.find('#imgsPrev img').on('click', function () {
var imgsrc = this.src
var dataIndex = this.getAttribute('data-index')
layer.confirm('是否删除该图片?', { icon: 3, title: '提示' }, function (index) {
var callDel = set.calldel
if (callDel.url != '') {
$.post(callDel.url, { imgpath: imgsrc }, function (res) {
$('#imgsPrev img[data-index=' + dataIndex + ']')[0].remove()
callDel.done(res)
})
} else {
layer.msg('没有配置回调参数')
$('#imgsPrev img[data-index=' + dataIndex + ']')[0].remove()
}
layer.close(index)
})
})
},
})
})
},
})
},
//图片2
image_alt: function (range) {
//使用通用的图片编辑
imageEditor({
context: {
set: set,
}, //上传成功后,用于删除之前的图片
beforeUpload: function (imageData, context) {
context.deleteImage(imageData)
},
success: function (imageData) {
insertInline.call(
iframeWin,
'img',
{
src: imageData.src,
alt: imageData.alt,
style: imageData.style,
},
range
)
},
})
},
//插入视频
video: function (range) {
var body = this,
customTheme = set.customTheme || { video: [] },
customContent = ''
if (customTheme.video.title.length > 0) {
customContent = AddCustomThemes(customTheme.video.title, customTheme.video.content, customTheme.video.preview)
}
layer.open({
type: 1,
id: 'fly-jie-video-upload',
title: '视频管理',
shade: 0.05,
shadeClose: true,
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 485) {
return ['90%']
} else {
return ['485px']
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return '100px'
}
})(),
skin: 'layui-layer-border',
content: [
'',
].join(''),
btn: ['确定', '取消'],
btnAlign: 'c',
yes: function (index, layero) {
var video = layero.find('input[name="video"]'),
cover = layero.find('input[name="cover"]'),
theme = layero.find('select[name="theme"]')
if (video.val() == '') {
layer.msg('请选择一个视频或输入视频地址')
} else {
var txt =
' 您的浏览器不支持video播放 '
var custclass = ''
if (customTheme.video.title.length > 0 && theme.length > 0) {
//追加样式
custclass = theme[0].options[theme[0].selectedIndex].value
}
insertInline.call(
iframeWin,
'div',
{
text: txt,
class: custclass,
},
range
)
layer.close(index)
}
},
btn2: function (index, layero) {
var callDel = set.calldel
if (callDel.url != '') {
$.post(
callDel.url,
{
imgpath: layero.find('input[name="cover"]').val(),
filepath: layero.find('input[name="video"]').val(),
},
function (res) {
callDel.done(res)
}
)
}
},
cancel: function (index, layero) {
var callDel = set.calldel
if (callDel.url != '') {
$.post(
callDel.url,
{
imgpath: layero.find('input[name="cover"]').val(),
filepath: layero.find('input[name="video"]').val(),
},
function (res) {
callDel.done(res)
}
)
}
},
success: function (layero, index) {
layui.use('upload', function (upload) {
var loding,
video = layero.find('input[name="video"]'),
cover = layero.find('input[name="cover"]'),
upload = layui.upload,
uploadImage = set.uploadImage || {}
if (uploadImage.url == '') {
layer.msg('图片上传接口配置错误!')
}
var uploadfile = set.uploadVideo || {}
if (uploadfile.url == '') {
layer.msg('视频上传接口配置错误!')
}
//执行实例
upload.render({
elem: '#LayEdit_InsertImage',
url: uploadImage.url,
method: uploadImage.method,
data: uploadImage.data,
headers: uploadImage.headers,
accept: uploadImage.accept || 'image',
acceptMime: uploadImage.acceptMime || 'image/*',
exts: uploadImage.exts || 'jpg|png|gif|bmp|jpeg',
size: uploadImage.size || 1024 * 10,
field: uploadImage.field,
before: function (obj) {
loding = layer.msg('文件上传中,请稍等哦', { icon: 16, shade: 0.3, time: 0 })
},
done: function (res, input, upload) {
layer.close(loding)
if (res.code == 0) {
res.data = res.data || {}
cover.val(res.data.src)
uploadImage.done(res)
} else if (res.code == 2) {
var curIndex = layer.open({
type: 1,
anim: 2,
icon: 5,
title: '提示',
area: ['390px', '260px'],
offset: 't',
content:
res.msg +
"确定使用该文件吗?
",
btn: ['确定', '取消'],
yes: function () {
res.data = res.data || {}
cover.val(res.data.src)
layer.close(curIndex)
},
})
} else {
layer.msg(res.msg || '上传失败')
}
},
})
upload.render({
elem: '#LayEdit_InsertVideo',
url: uploadfile.url,
method: uploadfile.method,
data: uploadfile.data,
headers: uploadfile.headers,
field: uploadfile.field,
accept: uploadfile.accept || 'video',
acceptMime: uploadfile.acceptMime || 'video/*',
exts: uploadfile.exts || 'mp4|flv|avi|rm|rmvb',
size: uploadfile.size || 1024 * 20,
before: function (obj) {
loding = layer.msg('文件上传中,请稍等哦', { icon: 16, shade: 0.3, time: 0 })
},
done: function (res, input, upload) {
layer.close(loding)
if (res.code == 0) {
res.data = res.data || {}
video.val(res.data.src)
uploadfile.done(res)
} else if (res.code == 2) {
var curIndex = layer.open({
type: 1,
anim: 2,
icon: 5,
title: '提示',
area: ['390px', '260px'],
offset: 't',
content:
res.msg +
"
确定使用该文件吗?
",
btn: ['确定', '取消'],
yes: function () {
res.data = res.data || {}
video.val(res.data.src)
layer.close(curIndex)
},
})
} else {
layer.msg(res.msg || '上传失败')
}
},
})
var theme = layero.find('select[name="theme"]')
if (customTheme.video.title.length > 0 && theme.length > 0) {
layero.find('select[name="theme"]').on('change mouseover', function () {
layer.tips(" ", this)
})
}
})
},
})
},
//上传附件
attachment: function (range) {
var that = this
layer.open({
type: 1,
id: 'fly-jie-image-upload',
title: '附件上传',
shade: 0.05,
shadeClose: true,
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 485) {
return ['90%']
} else {
return ['485px']
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return '100px'
}
})(),
skin: 'layui-layer-border',
content: [
'',
].join(''),
btn: ['确定', '取消'],
btnAlign: 'c',
yes: function (index, layero) {
if (layero.find('#filesPrev').find('a').length === 0) {
layer.msg('请选择要上传的附件')
} else {
insertInline.call(
iframeWin,
'p',
{
text: layero.find('#filesPrev').html(),
},
range
)
layer.close(index)
}
},
success: function (layero, index) {
layui.use('upload', function () {
var upload = layui.upload
var uploadFiles = set.uploadFiles || {}
if (uploadFiles.url == '') {
layer.msg('上传接口配置错误!')
}
var errorIndex = [] //上传接口出错的文件索引
//执行实例
upload.render({
elem: '#LayEdit_InsertFiles',
url: uploadFiles.url,
field: uploadFiles.field,
headers: uploadFiles.headers,
data: uploadFiles.data,
method: uploadFiles.type,
accept: uploadFiles.accept || 'file',
acceptMime: uploadFiles.acceptMime || 'file/*',
exts: uploadFiles.exts,
size: uploadFiles.size || 1024 * 30,
multiple: true,
before: function (obj) {
obj.preview(function (index, file, result) {
//由于有时预览会在allDone之后回调,此时所有单个文件的error已经执行,即已经出错的文件id以有,因此需要判断此预览文件id是否是上传出错文件的id,不是才预览
if (errorIndex.indexOf(index) === -1)
$('#filesPrev').append(
'' + file.name + ' '
)
})
},
allDone: function () {
//所有上传操作完成后,删除出错的文件
for (var i = 0; i < errorIndex.length; i++) {
$('#filesPrev')
.find('a[data-index="' + errorIndex[i] + '"]')
.remove()
}
//触发自动插入编辑器功能
if (uploadFiles.autoInsert) {
insertInline.call(
iframeWin,
'p',
{
text: layero.find('#filesPrev').html(),
},
range
)
layer.close(index)
}
},
error: function (index, upload) {
//某文件上传接口返回错误时,将其错误index记录下来
errorIndex.push(index)
},
done: function (res, index, upload) {
if (res.code == 0) {
res.data = res.data || {}
$('#filesPrev a[data-index="' + index + '"]').attr('href', res.data.src)
uploadFiles.done(res)
} else if (res.code == 2) {
layer.msg(res.msg || '上传失败')
res.data = res.data || {}
$('#filesPrev a[data-index="' + index + '"]').attr('href', res.data.src)
uploadFiles.done(res)
} else {
layer.msg(res.msg || '上传失败')
}
layero.find('#filesPrev a').on('click', function () {
var dataIndex = this.getAttribute('data-index')
layer.confirm('是否删除该附件?', { icon: 3, title: '提示' }, function (index) {
var callDel = set.calldel
if (callDel.url != '') {
$.post(callDel.url, { filepath: this.href }, function (res) {
$('#filesPrev')
.find('a[data-index="' + dataIndex + '"]')
.remove()
callDel.done(res)
})
} else {
layer.msg('没有配置回调参数')
$('#filesPrev')
.find('a[data-index="' + dataIndex + '"]')
.remove()
}
layer.close(index)
})
})
},
})
})
},
})
},
//源码模式
html: function (range) {
var that = this
if (that.parentElement.nextElementSibling.lastElementChild.id.indexOf('aceHtmleditor') == -1) {
var docs = that.parentElement.nextElementSibling.firstElementChild.contentDocument.body.innerHTML
if (docs.indexOf('') > -1) {
docs = docs
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/'/g, "'")
.replace(/"/g, '"')
}
docs = style_html(docs, 4, ' ', 80)
that.parentElement.nextElementSibling.setAttribute(
'style',
'z-index: 999; overflow: hidden;height:' + that.parentElement.nextElementSibling.clientHeight + 'px'
)
if (this.parentElement.parentElement.getAttribute('style') !== null)
this.parentElement.nextElementSibling.setAttribute(
'style',
'z-index: 999; overflow: hidden;height: ' +
(this.parentElement.parentElement.offsetHeight - this.parentElement.offsetHeight - 14) +
'px'
)
that.parentElement.nextElementSibling.firstElementChild.style = 'position: absolute;left: -32768px;top: -32768px;'
var htmlPanel = document.createElement('div')
htmlPanel.setAttribute('id', that.parentElement.nextElementSibling.firstElementChild.id + 'aceHtmleditor')
htmlPanel.setAttribute('style', 'left: 0px;top: 0px;width: 100%;height: 100%')
that.parentElement.nextElementSibling.appendChild(htmlPanel)
var editor = ace.edit(that.parentElement.nextElementSibling.firstElementChild.id + 'aceHtmleditor')
editor.setFontSize(14)
editor.session.setMode('ace/mode/html')
editor.setTheme('ace/theme/tomorrow')
editor.setValue(docs)
editor.setOption('wrap', 'free')
editor.gotoLine(0)
//工具栏屏蔽
$(that).siblings('i').addClass('layui-disabled')
$(that).siblings('.layedit-tool-fullScreen').removeClass('layui-disabled')
$(that).removeClass('layui-disabled')
} else {
var editor = ace.edit(that.parentElement.nextElementSibling.firstElementChild.id + 'aceHtmleditor')
var doc = editor.getValue()
iframeWin.document.body.innerHTML = doc
iframeWin.document.body.childNodes.forEach(function (item, index, arr) {
if (item.tagName == 'PRE') {
item.innerHTML = item.innerHTML
.replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&')
.replace(//g, '>')
.replace(/'/g, ''')
.replace(/"/g, '"')
}
})
var height = that.parentElement.nextElementSibling.clientHeight
that.parentElement.nextElementSibling.removeAttribute('style')
this.parentElement.nextElementSibling.firstElementChild.style = 'height:' + height + 'px'
this.parentElement.nextElementSibling.lastElementChild.remove()
$(that).siblings('i').removeClass('layui-disabled')
}
},
//全屏
fullScreen: function (range) {
if (this.parentElement.parentElement.getAttribute('style') == null) {
this.parentElement.parentElement.setAttribute(
'style',
'position: fixed;top: 0;left: 0;height: 100%;width: 100%;background-color: #fff;z-index: 9999;'
)
this.parentElement.nextElementSibling.style =
'height:' + (this.parentElement.parentElement.offsetHeight - this.parentElement.offsetHeight - 8) + 'px'
this.parentElement.nextElementSibling.firstElementChild.style = 'height:100%'
//是否源码模式
if (this.parentElement.nextElementSibling.lastElementChild.id.indexOf('aceHtmleditor') > -1) {
this.parentElement.nextElementSibling.firstElementChild.style = 'position: absolute;left: -32768px;top: -32768px;'
this.parentElement.nextElementSibling.setAttribute(
'style',
'z-index: 999; overflow: hidden;height: ' + (this.parentElement.parentElement.offsetHeight - this.parentElement.offsetHeight) + 'px'
)
}
} else {
this.parentElement.parentElement.removeAttribute('style')
this.parentElement.nextElementSibling.removeAttribute('style')
this.parentElement.nextElementSibling.firstElementChild.style = 'height:' + set.height
if (this.parentElement.nextElementSibling.lastElementChild.id.indexOf('aceHtmleditor') > -1) {
this.parentElement.nextElementSibling.setAttribute(
'style',
'z-index: 999; overflow: hidden;height:' + this.parentElement.nextElementSibling.firstElementChild.clientHeight + 'px'
)
this.parentElement.nextElementSibling.firstElementChild.style = 'position: absolute;left: -32768px;top: -32768px;'
}
}
},
preview: function (range) {
var currStyle = []
layui.each(set.quote.style, function (index, item) {
currStyle.push(' ')
})
var setPreview = set.previewAttr || {
area: ['50%', '100%'],
offset: 'r',
}
var docs = this.parentElement.nextElementSibling.firstElementChild.contentDocument.body.innerHTML
layer.open({
type: 1,
id: 'layui-kz-preview',
title: '预览',
shade: 0.05,
maxmin: true,
full: function (index) {
index[0].style.height = $('.layui-layer-shade').offsetHeight + 'px'
index[0].children[1].style.height = $('.layui-layer-shade').offsetHeight - 43 + 'px'
},
min: function (index) {},
restore: function (index) {
index[0].style.height = document.body.clientHeight - 100 + 'px'
index[0].children[1].style.height = document.body.clientHeight - 143 + 'px'
},
shadeClose: true,
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 485) {
return ['90%', '90%']
} else {
return setPreview.area
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return setPreview.offset
}
})(),
content: currStyle.join('') + docs,
success: function (layero, index) {
//layer.full(index);//全屏
layer.setTop(layero) //置顶
},
})
},
removeformat: function (range) {
//if (device.ie)
// iframeDOM.execCommand('backColor', false, "#fff");
//else
// iframeDOM.execCommand('hiliteColor', false, "#fff");
//iframeDOM.execCommand('forecolor', false, "#000");
iframeDOM.execCommand('removeFormat', 'strong', 'color')
setTimeout(function () {
body.focus()
}, 10)
},
fontFomatt: function (range) {
var alt = set.fontFomatt || {
code: ['p', 'h1', 'h2', 'h3', 'h4', 'div'],
text: ['正文(p)', '一级标题(h1)', '二级标题(h2)', '三级标题(h3)', '四级标题(h4)', '块级元素(div)'],
}
var arr = {},
arr2 = {},
codes = alt.code,
texts = alt.text,
fonts = (function () {
layui.each(codes, function (index, item) {
arr[index] = item
})
return arr
})(),
fonttexts = (function () {
layui.each(texts, function (index, item) {
arr2[index] = item
})
return arr2
})()
fontFomatt.call(this, { fonts: fonts, texts: fonttexts }, function (value) {
iframeDOM.execCommand('formatBlock', false, '<' + value + '>')
setTimeout(function () {
body.focus()
}, 10)
})
},
fontfamily: function (range) {
var alt = set.fontfamily || {
code: [
'font-family:宋体,SimSun',
'font-family:微软雅黑,Microsoft YaHei',
'font-family:黑体, SimHei',
'font-family:楷体,楷体_GB2312, SimKai',
'font-family:arial, helvetica,sans-serif',
'font-family:arial black,avant garde',
'font-family:times new roman',
],
text: ['宋体', '微软雅黑', '黑体', '楷体', 'arial', 'arial black', 'times new roman'],
}
var arr = {},
arr2 = {},
codes = alt.code,
texts = alt.text,
fonts = (function () {
layui.each(codes, function (index, item) {
arr[index] = item
})
return arr
})(),
fonttexts = (function () {
layui.each(texts, function (index, item) {
arr2[index] = item
})
return arr2
})()
fontfamily.call(this, { fonts: fonts, texts: fonttexts }, function (value) {
insertInline.call(
iframeWin,
'span',
{
style: value,
text: ' ',
},
range
)
setTimeout(function () {
body.focus()
}, 10)
})
},
/*
, fontSize: function (range) {
var alt = set.fontSize || {
code: ["font-size:10px", "font-size:12px", "font-size:14px", "font-size:16px", "font-size:18px", "font-size:20px", "font-size:24px", "font-size:26px", "font-size:28px", "font-size:30px", "font-size:32px"]
, text: ["10px", "12px", "14px", "16px", "18px", "20px", "24px", "26px", "28px", "30px", "32px"]
};
var arr = {}
, arr2 = {}
, codes = alt.code
, texts = alt.text
, fonts = function () {
layui.each(codes, function (index, item) {
arr[index] = item;
});
return arr;
}()
, fonttexts = function () {
layui.each(texts, function (index, item) {
arr2[index] = item;
});
return arr2;
}();
fontSize.call(this, { fonts: fonts, texts: fonttexts }, function (value) {
insertInline.call(iframeWin, 'span', {
style: value
, text: " "
}, range);
setTimeout(function () {
body.focus();
}, 10);
});
}
*/
// 字体大小
fontSize: function (range) {
var alt = set.fontSize || {
code: ['1', '2', '3', '4', '5', '6', '7'],
text: ['9px', '13px', '16px', '18px', '24px', '32px', '48px'],
},
arr = {},
arr2 = {}
var codes = alt.code
var texts = alt.text
var fonts = (function () {
layui.each(codes, function (index, item) {
arr[index] = item
})
return arr
})()
var fonttexts = (function () {
layui.each(texts, function (index, item) {
arr2[index] = item
})
return arr2
})()
fontSize.call(this, { fonts: fonts, texts: fonttexts, last_value: set.fontSize_value }, function (value) {
set.fontSize_value = value
var fontText = alt.code.indexOf(value)
if (fontText > 0) {
fontText = alt.text[fontText]
} else {
fontText = value
}
// 获取到对应的节点id
var list = getRangeNodes(range)
// window.iframeDOM = iframeDOM;
layer.msg('已成功设置字号为:' + fontText, { icon: 6 })
iframeDOM.execCommand('FontSize', false, value)
// 修改字体样式
for (var i = 0; i < list.length; i++) {
var len = list[i].children.length
if (!len || len == 0) {
continue
}
for (var j = 0; j < len; j++) {
if (list[i].children[j].nodeName == 'FONT') {
list[i].children[j].size = null
list[i].children[j].style.fontSize = fontText
}
}
}
// d.queryCommandValue("FontSize")
// iframeDOM.queryCommandValue('FontSize', false, value)
setTimeout(function () {
body.focus()
// 进行批量更改
}, 10)
})
},
// 间距
lineHeight: function (range) {
var alt = set.lineHeight || {
code: ['1', '1.5', '1.75', '2', '3', '4', '5'],
text: ['1', '1.5', '1.75', '2', '3', '4', '5'],
},
arr = {},
arr2 = {}
var codes = alt.code
var texts = alt.text
var fonts = (function () {
layui.each(codes, function (index, item) {
arr[index] = item
})
return arr
})()
var fonttexts = (function () {
layui.each(texts, function (index, item) {
arr2[index] = item
})
return arr2
})()
lineHeight.call(this, { fonts: fonts, texts: fonttexts, last_value: set.lineHeight_value }, function (value) {
set.lineHeight_value = value
var fontText = alt.code.indexOf(value)
if (fontText > 0) {
fontText = alt.text[fontText]
} else {
fontText = value
}
// 获取到对应的节点id
var list = getRangeNodes(range)
// window.iframeDOM = iframeDOM;
layer.msg('已成功设置行间距为:' + fontText, { icon: 6 })
// iframeDOM.execCommand('FontSize', false, value);
window.list = list
// 修改字体样式
for (var i = 0; i < list.length; i++) {
var len = list[i].children.length
list[i].style.lineHeight = value + 'em'
}
// iframeDOM.execCommand('formatBlock', false, "<" + value + ">");
setTimeout(function () {
body.focus()
}, 10)
})
},
customlink: function (range) {
var container = getContainer(range),
parentNode = $(container).parent()
customlink.call(body, { title: set.customlink.title }, function (field) {
var parent = parentNode[0]
if (parent.tagName === 'A') {
parent.href = field.url
parent.rel = field.rel
} else {
insertInline.call(
iframeWin,
'a',
{
target: '_blank',
href: set.customlink.href,
rel: 'nofollow',
text: field.text,
onmouseup: set.customlink.onmouseup,
},
range
)
}
})
},
anchors: function (range) {
anchors.call(body, {}, function (field) {
insertInline.call(
iframeWin,
'a',
{
name: field.text,
text: ' ',
},
range
)
})
},
table: function (range) {
table.call(this, {}, function (opts) {
var tbody = ''
for (var i = 0; i < opts.cells; i++) {
tbody += ' '
}
tbody += ' '
var tmptr = tbody
for (var i = 0; i < opts.rows; i++) {
tbody += tmptr
}
insertInline.call(
iframeWin,
'table',
{
text: tbody,
},
range
)
})
},
addhr: function (range) {
insertInline.call(iframeWin, 'hr', {}, range)
},
/*End*/
//帮助
help: function () {
layer.open({
type: 2,
title: '帮助',
area: ['600px', '380px'],
shadeClose: true,
shade: 0.1,
offset: '100px',
skin: 'layui-layer-msg',
content: ['http://www.layui.com/about/layedit/help.html', 'no'],
})
},
},
tools = editor.find('.layui-layedit-tool'),
click = function () {
var othis = $(this),
events = othis.attr('layedit-event'),
command = othis.attr('lay-command')
if (othis.hasClass(ABLED)) return
body.focus()
var range = Range(iframeDOM),
container = range.commonAncestorContainer
if (command) {
if (/justifyLeft|justifyCenter|justifyRight/.test(command)) {
if (container.parentNode.tagName === 'BODY') {
iframeDOM.execCommand('formatBlock', false, '')
}
}
iframeDOM.execCommand(command)
setTimeout(function () {
if (/Bold/.test(command)) {
var elem = document.createElement('strong')
body.find('b').each(function () {
elem.innerText = this.innerText
this.outerHTML = elem.outerHTML
})
}
body.focus()
}, 10)
} else {
toolEvent[events] && toolEvent[events].call(this, range, iframeDOM)
}
toolCheck.call(iframeWin, tools, othis)
},
isClick = /image/
tools
.find('>i')
.on('mousedown', function () {
var othis = $(this),
events = othis.attr('layedit-event')
if (isClick.test(events)) return
click.call(this)
})
.on('click', function () {
var othis = $(this),
events = othis.attr('layedit-event')
if (!isClick.test(events)) return
click.call(this)
})
//触发内容区域
body.on('click', function () {
toolCheck.call(iframeWin, tools)
layer.close(face.index)
layer.close(fontFomatt.index)
layer.close(fontfamily.index)
layer.close(fontSize.index)
layer.close(table.index)
})
//右键菜单自定义
var rbtnIndex = null
var contextmenu = function (event) {
var rbtn = set.rightBtn || {
type: 'layBtn',
customEvent: function (tagName, event) {},
}
if (event != null && rbtn.type != 'default') {
layer.close(rbtnIndex)
var currenNode, parentNode
currenNode = event.target
parentNode = currenNode.parentNode
if (rbtn.type == 'custom') {
rbtn.customEvent(currenNode.tagName, event)
return false
}
switch (currenNode.tagName) {
case 'IMG':
imageEditor({
context: {
set: set,
},
data: {
src: event.target.src,
alt: event.target.alt,
width: event.target.style.width || event.target.getAttribute('width'),
height: event.target.style.height || event.target.getAttribute('height'),
}, //打开图片编辑器之前
// beforeOpen: function (options, context) {
// //增加图片删除按钮
// options.btn.push('删除 ')
// options.btn3 = function (index, layero) {
// context.deleteImage(context.getImageData(), { src: 'must-delete' })
// event.toElement.remove()
// layer.close(index)
// }
// }, //上传前,用于删除之前的图片
beforeUpload: function (imageData, context) {
context.deleteImage(imageData)
}, //点击确定后
success: function (imageData, context) {
event.target.src = imageData.src
event.target.alt = imageData.alt
event.target.style.width = imageData.width
event.target.style.height = imageData.height
},
})
break
case 'VIDEO':
var customTheme = set.customTheme || { video: [] },
customContent = ''
if (customTheme.video.title.length > 0) {
customContent = AddCustomThemes(customTheme.video.title, customTheme.video.content, customTheme.video.preview)
}
rbtnIndex = layer.open({
type: 1,
id: 'fly-jie-video-upload',
title: '视频管理',
shade: 0.05,
shadeClose: true,
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 485) {
return ['90%']
} else {
return ['485px']
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return '100px'
}
})(),
skin: 'layui-layer-border',
content: [
'
',
].join(''),
btn: ['确定', '取消', '删除 '],
btnAlign: 'c',
yes: function (index, layero) {
var video = layero.find('input[name="video"]'),
cover = layero.find('input[name="cover"]')
if (video.val() == '') {
layer.msg('请选择一个视频或输入视频地址')
} else {
event.target.src = video.val()
event.target.poster = cover.val()
layer.close(index)
}
},
btn2: function (index, layero) {},
btn3: function (index, layero) {
var callDel = set.calldel
if (callDel.url != '') {
$.post(
callDel.url,
{
filepath: event.target.src,
imgpath: event.target.poster,
},
function (res) {
parentNode.remove()
callDel.done(res)
}
)
} else {
event.toElement.remove()
}
layer.close(index)
},
success: function (layero, index) {
layui.use('upload', function (upload) {
var loding,
video = layero.find('input[name="video"]'),
cover = layero.find('input[name="cover"]'),
upload = layui.upload,
uploadImage = set.uploadImage || {},
uploadfile = set.uploadVideo || {}
if (uploadImage.url == '') {
layer.msg('图片上传接口配置错误!')
}
if (uploadfile.url == '') {
layer.msg('视频上传接口配置错误!')
}
//执行实例
upload.render({
elem: '#LayEdit_InsertImage',
url: uploadImage.url,
method: uploadImage.method,
data: uploadImage.data,
headers: uploadImage.headers,
accept: uploadImage.accept || 'image',
acceptMime: uploadImage.acceptMime || 'image/*',
exts: uploadImage.exts || 'jpg|png|gif|bmp|jpeg',
size: uploadImage.size || 1024 * 10,
field: uploadImage.field,
before: function (obj) {
loding = layer.msg('文件上传中,请稍等哦', { icon: 16, shade: 0.3, time: 0 })
},
done: function (res, input, upload) {
layer.close(loding)
if (res.code == 0) {
res.data = res.data || {}
cover.val(res.data.src)
uploadImage.done(res)
} else if (res.code == 2) {
var curIndex = layer.open({
type: 1,
anim: 2,
icon: 5,
title: '提示',
area: ['390px', '260px'],
offset: 't',
content:
res.msg +
"确定使用该文件吗?
",
btn: ['确定', '取消'],
yes: function () {
res.data = res.data || {}
cover.val(res.data.src)
layer.close(curIndex)
},
})
} else {
layer.msg(res.msg || '上传失败')
}
},
})
upload.render({
elem: '#LayEdit_InsertVideo',
url: uploadfile.url,
method: uploadfile.method,
data: uploadfile.data,
headers: uploadfile.headers,
field: uploadfile.field,
accept: uploadfile.accept || 'video',
acceptMime: uploadfile.acceptMime || 'video/*',
exts: uploadfile.exts || 'mp4|flv|avi|rm|rmvb',
size: uploadfile.size || 1024 * 20,
before: function (obj) {
loding = layer.msg('文件上传中,请稍等哦', { icon: 16, shade: 0.3, time: 0 })
},
done: function (res, input, upload) {
layer.close(loding)
if (res.code == 0) {
res.data = res.data || {}
video.val(res.data.src)
uploadfile.done(res)
} else if (res.code == 2) {
var curIndex = layer.open({
type: 1,
anim: 2,
icon: 5,
title: '提示',
area: ['390px', '260px'],
offset: 't',
content:
res.msg +
"
确定使用该文件吗?
",
btn: ['确定', '取消'],
yes: function () {
res.data = res.data || {}
video.val(res.data.src)
layer.close(curIndex)
},
})
} else {
layer.msg(res.msg || '上传失败')
}
},
})
var theme = layero.find('select[name="theme"]')
if (customTheme.video.title.length > 0 && theme.length > 0) {
layero.find('select[name="theme"]').on('change mouseover', function () {
layer.tips(" ", this)
})
}
})
},
})
break
case 'TD':
rbtnIndex = layer.open({
type: 1,
title: false,
shade: 0,
offset: [event.clientY + 'px', event.clientX + 'px'],
skin: 'layui-box layui-util-face',
content: (function () {
var content = [
,
' 新增行 ',
' 删除行 ',
].join('')
return ''
})(),
success: function (layero, index) {
layero.find('li').on('click', function () {
var othis = $(this),
command = othis.attr('lay-command')
if (command) {
switch (command) {
case 'deltr':
parentNode.remove()
break
case 'addnewtr':
var html = ''
for (var i = 0; i < parentNode.children.length; i++) {
html += ' '
}
html += ' '
$(parentNode).after(html)
break
}
}
layer.close(index)
})
},
})
break
default:
rbtnIndex = layer.open({
type: 1,
title: false,
closeBtn: false,
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
var frame = set._elem.next().find('iframe').get(0)
return [
frame.offsetTop + event.clientY + parentNode.getBoundingClientRect().y + 'px',
frame.offsetLeft + event.clientX + parentNode.getBoundingClientRect().x + 'px',
]
}
})(),
shade: function () {
if (/mobile/i.test(navigator.userAgent)) {
return 0.1
}
return 0
},
shadeClose: true,
content: [
'',
'',
].join(''),
success: function (layero, index) {
var callDel = set.calldel
layero.find('.layui-btn-primary').on('click', function () {
var othis = $(this),
command = othis.attr('lay-command')
if (command) {
if (currenNode.tagName == 'VIDEO') {
parentNode.style = 'text-align:' + command
} else {
currenNode.style = 'text-align:' + command
}
}
layer.close(index)
})
layero.find('.context-menu-delete').on('click', function () {
if (currenNode.tagName == 'BODY') {
layer.msg('不能再删除了')
} else if (currenNode.tagName == 'VIDEO') {
if (callDel.url != '') {
$.post(
callDel.url,
{
filepath: event.target.src,
imgpath: event.target.poster,
},
function (res) {
parentNode.remove()
callDel.done(res)
}
)
} else {
parentNode.remove()
}
} else if (currenNode.tagName == 'IMG') {
if (callDel.url != '') {
$.post(callDel.url, { para: event.target.src }, function (res) {
currenNode.remove()
callDel.done(res)
})
} else {
currenNode.remove()
}
} else {
currenNode.remove()
}
layer.close(index)
})
},
})
break
//return true;
}
return false
}
}
if (/mobile/i.test(navigator.userAgent)) {
var timeOutEvent
body.on({
touchstart: function (e) {
// 长按事件触发
timeOutEvent = setTimeout(function () {
contextmenu(e)
clearTimeout(timeOutEvent)
}, 300)
//长按300毫秒
e.preventDefault()
},
touchmove: function () {
clearTimeout(timeOutEvent)
},
touchend: function () {
clearTimeout(timeOutEvent)
},
})
} else {
body.on('contextmenu', function (event) {
return contextmenu(event)
})
}
},
//超链接面板
link = function (options, callback) {
var dMode = options.dmode
var body = this,
index = layer.open({
type: 1,
id: 'LAY_layedit_link',
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 460) {
return ['90%']
} else {
return ['460px']
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return '100px'
}
})(),
shade: 0.05,
shadeClose: true,
moveType: 1,
title: '超链接',
skin: 'layui-layer-msg',
content: [
'',
].join(''),
btn: ['确定', '取消'],
btnAlign: 'c',
yes: function (index, layero) {
$('#layedit-link-yes').click()
},
btn1: function (index, layero) {
layer.close(index)
setTimeout(function () {
body.focus()
}, 10)
},
success: function (layero, index) {
var eventFilter = 'submit(layedit-link-yes)'
form.render('radio')
form.on(eventFilter, function (data) {
layer.close(link.index)
callback && callback(data.field)
})
},
})
link.index = index
},
customlink = function (options, callback) {
var body = this,
index = layer.open({
type: 1,
id: 'LAY_layedit_customlink',
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 350) {
return ['90%']
} else {
return ['350px']
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return '100px'
}
})(),
shade: 0.05,
shadeClose: true,
moveType: 1,
title: options.title,
skin: 'layui-layer-msg',
content: [
'',
].join(''),
btn: ['确定', '取消'],
btnAlign: 'c',
yes: function (index, layero) {
$('#layedit-link-yes').click()
},
success: function (layero, index) {
var eventFilter = 'submit(layedit-link-yes)'
form.render('radio')
form.on(eventFilter, function (data) {
callback && callback(data.field)
layer.close(customlink.index)
})
},
})
customlink.index = index
},
anchors = function (options, callback) {
var body = this,
index = layer.open({
type: 1,
id: 'LAY_layedit_addmd',
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 350) {
return ['90%']
} else {
return ['350px']
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return '100px'
}
})(),
shade: 0.05,
shadeClose: true,
moveType: 1,
title: '添加锚点',
skin: 'layui-layer-msg',
content: [
'',
].join(''),
btn: ['确定', '取消'],
btnAlign: 'c',
yes: function (index, layero) {
$('#layedit-link-yes').click()
},
success: function (layero, index) {
var eventFilter = 'submit(layedit-link-yes)'
form.render('radio')
form.on(eventFilter, function (data) {
layer.close(anchors.index)
callback && callback(data.field)
})
},
})
anchors.index = index
},
table = function (options, callback) {
table.hide =
table.hide ||
function (e) {
if ($(e.target).attr('layedit-event') !== 'table') {
layer.close(table.index)
}
}
if (!/mobile/i.test(navigator.userAgent)) {
table.index = layer.tips(
(function () {
return (
'0列 x 0行 ' +
'
' +
'' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
'
'
)
})(),
this,
{
tips: 1,
time: 0,
skin: 'layui-box layui-util-face',
maxWidth: 500,
success: function (layero, index) {
layero.find('td').on('mouseover', function () {
layero.find('#laytable_label')[0].innerText = this.cellIndex + 1 + '列X' + (this.parentElement.rowIndex + 1) + '行'
layero.find('td').removeAttr('style')
$(this).attr('style', 'background-color:linen;')
$(this).prevAll().attr('style', 'background-color:linen;')
for (var i = 0; i < $(this.parentElement).prevAll().length; i++) {
for (var j = 0; j < $(this.parentElement).prevAll()[i].childNodes.length; j++) {
if (j <= this.cellIndex) {
$(this.parentElement).prevAll()[i].children[j].style = 'background-color:linen;'
}
}
}
})
layero.find('td').on('click', function () {
callback &&
callback({
cells: this.cellIndex + 1,
rows: this.parentElement.rowIndex,
})
layer.close(index)
})
$(document).off('click', table.hide).on('click', table.hide)
},
}
)
} else {
table.index = layer.open({
type: 1,
title: false,
closeBtn: 0,
shade: 0.05,
shadeClose: true,
content: (function () {
return (
'0列 x 0行 ' +
'
' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ' +
'
'
)
})(),
area: ['85%'],
skin: 'layui-box layui-util-face',
success: function (layero, index) {
layero.find('td').on('touchmove', function (e) {
var realTarget = getTouchElement(e)
if (realTarget != null && realTarget.tagName.toUpperCase() === 'TD') {
layero.find('#laytable_label')[0].innerText = realTarget.cellIndex + 1 + '列X' + (realTarget.parentElement.rowIndex + 1) + '行'
layero.find('td').removeAttr('style')
$(realTarget).attr('style', 'background-color:linen;')
$(realTarget).prevAll().attr('style', 'background-color:linen;')
for (var i = 0; i < $(realTarget.parentElement).prevAll().length; i++) {
for (var j = 0; j < $(realTarget.parentElement).prevAll()[i].childNodes.length; j++) {
if (j <= realTarget.cellIndex) {
$(realTarget.parentElement).prevAll()[i].children[j].style = 'background-color:linen;'
}
}
}
}
})
layero.find('td').on('touchend', function (e) {
var realTarget = getTouchElement(e)
if (realTarget != null && realTarget.tagName.toUpperCase() === 'TD') {
callback &&
callback({
cells: realTarget.cellIndex + 1,
rows: realTarget.parentElement.rowIndex,
})
layer.close(index)
}
})
},
})
}
return table.index
},
//表情面板
face = function (options, callback) {
//表情库
var faces = (function () {
var alt = [
'[微笑]',
'[嘻嘻]',
'[哈哈]',
'[可爱]',
'[可怜]',
'[挖鼻]',
'[吃惊]',
'[害羞]',
'[挤眼]',
'[闭嘴]',
'[鄙视]',
'[爱你]',
'[泪]',
'[偷笑]',
'[亲亲]',
'[生病]',
'[太开心]',
'[白眼]',
'[右哼哼]',
'[左哼哼]',
'[嘘]',
'[衰]',
'[委屈]',
'[吐]',
'[哈欠]',
'[抱抱]',
'[怒]',
'[疑问]',
'[馋嘴]',
'[拜拜]',
'[思考]',
'[汗]',
'[困]',
'[睡]',
'[钱]',
'[失望]',
'[酷]',
'[色]',
'[哼]',
'[鼓掌]',
'[晕]',
'[悲伤]',
'[抓狂]',
'[黑线]',
'[阴险]',
'[怒骂]',
'[互粉]',
'[心]',
'[伤心]',
'[猪头]',
'[熊猫]',
'[兔子]',
'[ok]',
'[耶]',
'[good]',
'[NO]',
'[赞]',
'[来]',
'[弱]',
'[草泥马]',
'[神马]',
'[囧]',
'[浮云]',
'[给力]',
'[围观]',
'[威武]',
'[奥特曼]',
'[礼物]',
'[钟]',
'[话筒]',
'[蜡烛]',
'[蛋糕]',
],
arr = {}
layui.each(alt, function (index, item) {
arr[item] = options.facePath + 'images/face/' + index + '.gif'
})
return arr
})()
face.hide =
face.hide ||
function (e) {
if ($(e.target).attr('layedit-event') !== 'face') {
layer.close(face.index)
}
}
if (!/mobile/i.test(navigator.userAgent)) {
face.index = layer.tips(
(function () {
var content = []
layui.each(faces, function (key, item) {
content.push(' ')
})
return ''
})(),
this,
{
tips: 1,
time: 0,
skin: 'layui-box layui-util-face',
maxWidth: 500,
success: function (layero, index) {
layero
.css({
marginTop: -4,
marginLeft: -10,
})
.find('.layui-clear>li')
.on('click', function () {
callback &&
callback({
src: faces[this.title],
alt: this.title,
})
layer.close(index)
})
$(document).off('click', face.hide).on('click', face.hide)
},
}
)
} else {
face.index = layer.open({
type: 1,
title: false,
closeBtn: 0,
shade: 0.05,
shadeClose: true,
content: (function () {
var content = []
layui.each(faces, function (key, item) {
content.push(' ')
})
return ''
})(),
skin: 'layui-box layui-util-face',
success: function (layero, index) {
layero.find('.layui-clear>li').on('click', function () {
callback &&
callback({
src: faces[this.title],
alt: this.title,
})
layer.close(index)
})
},
})
}
return face.index
},
fontFomatt = function (options, callback) {
fontFomatt.hide =
fontFomatt.hide ||
function (e) {
if ($(e.target).attr('layedit-event') !== 'fontFomatt' && $(e.target).attr('layedit-event') !== 'fontfamily') {
layer.close(fontFomatt.index)
}
}
fontFomatt.index = layer.tips(
(function () {
var content = []
layui.each(options.fonts, function (index, item) {
content.push(
'<' +
options.fonts[index] +
'>' +
options.texts[index] +
'' +
options.fonts[index] +
'> '
)
})
return ''
})(),
this,
{
tips: 1,
time: 0,
skin: 'layui-box layui-util-face',
success: function (layero, index) {
layero
.css({ marginTop: -4, marginLeft: -10 })
.find('.layui-clear>li')
.on('click', function () {
callback && callback(this.title, options.fonts)
layer.close(index)
})
$(document).off('click', fontFomatt.hide).on('click', fontFomatt.hide)
},
}
)
},
fontfamily = function (options, callback) {
fontfamily.hide =
fontfamily.hide ||
function (e) {
if ($(e.target).attr('layedit-event') != 'fontfamily') {
layer.close(fontfamily.index)
}
}
fontfamily.index = layer.tips(
(function () {
var content = []
layui.each(options.fonts, function (index, item) {
content.push(
'<' +
options.fonts[index] +
'>' +
options.texts[index] +
'' +
options.fonts[index] +
'> '
)
})
return ''
})(),
this,
{
tips: 1,
time: 0,
skin: 'layui-box layui-util-face',
success: function (layero, index) {
layero
.css({ marginTop: -4, marginLeft: -10 })
.find('.layui-clear>li')
.on('click', function () {
callback && callback(this.title, options.fonts)
layer.close(index)
})
$(document).off('click', fontfamily.hide).on('click', fontfamily.hide)
},
}
)
},
// 字体大小 显示操作
fontSize = function (options, callback) {
fontSize.hide =
fontSize.hide ||
function (e) {
if ($(e.target).attr('layedit-event') !== 'fontSize') {
layer.close(fontSize.index)
}
}
if (!options.last_value) {
options.last_value = 2
}
fontSize.index = layer.tips(
(function () {
var content = []
layui.each(options.fonts, function (index, item) {
var iHtml = ''
if (options.last_value == options.fonts[index]) {
iHtml = ' '
}
content.push(
'' +
options.fonts[index] +
':' +
options.texts[index] +
iHtml +
'' +
options.fonts[index] +
'> '
)
})
return ''
})(),
this,
{
tips: 1,
time: 0,
skin: 'layui-box layui-util-font',
success: function (layero, index) {
layero
.css({ marginTop: -4, marginLeft: -10 })
.find('.layui-clear>li')
.on('click', function () {
callback && callback(this.title, options.fonts, options.texts)
layer.close(index)
})
$(document).off('click', fontSize.hide).on('click', fontSize.hide)
},
}
)
},
// 间距
lineHeight = function (options, callback) {
lineHeight.hide =
lineHeight.hide ||
function (e) {
if ($(e.target).attr('layedit-event') !== 'lineHeight') {
layer.close(lineHeight.index)
}
}
if (!options.last_value) {
options.last_value = 1
}
lineHeight.index = layer.tips(
(function () {
var content = []
layui.each(options.fonts, function (index, item) {
var iHtml = ''
if (options.last_value == options.fonts[index]) {
iHtml = ' '
}
content.push('' + options.texts[index] + iHtml + '' + options.fonts[index] + '> ')
})
return ''
})(),
this,
{
tips: 1,
time: 0,
skin: 'layui-box layui-util-font',
success: function (layero, index) {
layero
.css({ marginTop: -4, marginLeft: -10 })
.find('.layui-clear>li')
.on('click', function () {
callback && callback(this.title, options.fonts)
layer.close(index)
})
$(document).off('click', lineHeight.hide).on('click', lineHeight.hide)
},
}
)
},
//插入代码面板
code = function (options, callback) {
var objSel = [
'',
'请选择语言 ',
'',
'',
'',
'JavaScript ',
'HTML ',
'CSS ',
'Java ',
'PHP ',
'C# ',
'Python ',
'Ruby ',
'Go ',
' ',
'
',
' ',
].join('')
if (options.hide) {
objSel = [
'',
'请选择语言 ',
'',
'',
'',
options.default,
' ',
' ',
'
',
' ',
].join('')
}
var body = this,
index = layer.open({
type: 1,
id: 'LAY_layedit_code',
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 650) {
return ['90%']
} else {
return ['650px']
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return '100px'
}
})(),
shade: 0.05,
shadeClose: true,
moveType: 1,
title: '插入代码',
skin: 'layui-layer-msg',
content: [
'',
].join(''),
btn: ['确定', '取消'],
btnAlign: 'c',
yes: function (index, layero) {
$('#layedit-code-yes').click()
},
btn1: function (index, layero) {
layer.close(index)
body.focus()
},
success: function (layero, index) {
var eventFilter = 'submit(layedit-code-yes)'
form.render('select')
form.on(eventFilter, function (data) {
layer.close(code.index)
callback && callback(data.field, options.hide, options.default)
})
},
})
code.index = index
},
//全部工具
tools = {
html: ' ',
undo: ' ',
redo: ' ',
strong: ' ',
italic: ' ',
underline: ' ',
del: ' ',
"|": ' ',
left: ' ',
center: ' ',
right: ' ',
link: ' ',
unlink: ' ',
face: ' ',
image: ' ',
code: ' ',
images: ' ',
image_alt: ' ',
video: ' ',
fullScreen: ' ',
colorpicker: ' ',
fontBackColor: ' ',
fontFomatt: 'P ',
fontfamily: '字体 ',
fontSize: '字号 ',
lineHeight: '行高 ',
addhr: ' ',
anchors: ' ',
customlink: ' ',
table: ' ',
attachment: ' ',
preview: ' ',
removeformat: ' ',
help: ' '
},
// 打开图片编辑框
imageEditor = function (options) {
var context = options.context || {},
successCallback = options.success,
beforeUploadCallback = options.beforeUpload,
initialData = (context.initialData = options.data),
formId = (context.formId = 'image-upload-' + parseInt(Math.random() * 1000000)),
formatWidthHeight = function (val) {
var isNum = val.toString().indexOf('%') == -1
return {
value: isNum ? parseInt(val) : val,
string: isNum ? parseInt(val) + 'px' : val,
}
},
getImageData = (context.getImageData = function () {
var imageData =
layui.form.val(formId) ||
(function () {
//老版本layui.form.val无法取值
var itemForm = $('[lay-filter="' + formId + '"]').eq(0),
field = {}
layui.each(itemForm.find('input,select,textarea'), function (_, item) {
field[item.name] = item.value
})
return field
})()
imageData.style = ''
if (imageData.width) {
imageData.width = formatWidthHeight(imageData.width).string
imageData.style += 'width:' + imageData.width + ';'
}
if (imageData.height) {
imageData.height = formatWidthHeight(imageData.height).string
imageData.style += 'height:' + imageData.height + ';'
}
context.logger && context.logger('getImageData', imageData)
return imageData
}),
setImageData = (context.setImageData = function (imageData) {
imageData = imageData || {}
if (!!imageData.width) {
imageData.width = formatWidthHeight(imageData.width).value
}
if (!!imageData.height) {
imageData.height = formatWidthHeight(imageData.height).value
}
form.val(formId, imageData)
//如果没有指定图片尺寸,尝试获取
if (imageData.src && !imageData.isInitialData && !imageData.loaded && !imageData.width && !imageData.height) {
var image = new Image()
image.src = imageData.src
image.onload = function () {
imageData.loaded = true
imageData.width = image.naturalWidth.toString()
imageData.height = image.naturalHeight.toString()
setImageData(imageData)
}
}
}),
checkImageSrc = (context.checkImageSrc = function (imageData) {
if (!imageData.src) {
layer.msg('请先上传图片', { icon: 2, shade: 0.3, time: 1000 })
}
return !!imageData.src
}),
imagePreview = (context.imagePreview = function (imageData, title, callback) {
var image = new Image(),
maxWidth = /mobile/i.test(navigator.userAgent) ? 300 : 640,
maxHeight = /mobile/i.test(navigator.userAgent) ? 600 : 480
image.src = imageData.src
image.onload = function () {
//获取图片实际尺寸,并根据图片原始尺寸调整预览框大小
var width = image.naturalWidth,
height = image.naturalHeight
if (width > maxWidth) {
height = (height * maxWidth) / width
width = maxWidth
}
if (height > maxHeight) {
width = (width * maxHeight) / height
height = maxHeight
}
layer.open({
type: 1,
anim: 2,
icon: 5,
title: title || null,
offset: '100px',
area: [width + 20 + 'px', height + 77 + 'px'],
content: [
'',
'
',
'
',
].join(''),
btn: ['确定', '取消'],
btnAlign: 'c',
yes: function (index) {
callback && callback(imageData)
layer.close(index)
},
btn2: function (index) {
layer.close(index)
},
})
}
}),
deleteImage = (context.deleteImage = function (uploadImage, initialImage) {
uploadImage = uploadImage || getImageData()
initialImage = initialImage || initialData
if (!uploadImage.src) {
//图片不存在
} else if (
!!initialData &&
(uploadImage.src.substring(0 - initialImage.src.length) == initialImage.src ||
initialImage.src.substring(0 - uploadImage.src.length) == uploadImage.src)
) {
//编辑图片时,图片没有做任何修改,不删除
} else {
var callDel = context.set.calldel
$.post(callDel.url, { imgpath: uploadImage.src }, function (res) {
callDel.done(res)
})
}
}),
openOptions = {
type: 1,
id: 'fly-jie-image-upload',
title: null,
shade: 0.05,
shadeClose: true,
area: (function () {
if (/mobile/i.test(navigator.userAgent) || $(window).width() <= 485) {
return ['90%']
} else {
return ['485px']
}
})(),
offset: (function () {
if (/mobile/i.test(navigator.userAgent)) {
return 'auto'
} else {
return '100px'
}
})(),
skin: 'layui-layer-border',
content: [
'',
].join(''),
btn: ['确定', '取消'],
yes: function (index, layero) {
var imageData = getImageData()
if (checkImageSrc(imageData)) {
successCallback(imageData, context)
layer.close(index)
}
},
btn2: function (index) {
deleteImage()
layer.close(index)
},
success: function (layero, index) {
//初始化赋值
initialData && setImageData(initialData)
//预览
$('#preview-' + formId).click(function () {
var imageData = getImageData()
checkImageSrc(imageData) && imagePreview(imageData)
})
//上传
layui.use('upload', function (upload) {
var upload = layui.upload,
loding,
uploadImage = context.set.uploadImage || {}
if (!uploadImage.url) {
layer.msg('上传接口配置错误!')
}
//执行实例
upload.render({
elem: '#upload-' + formId,
url: uploadImage.url,
method: uploadImage.method,
data: uploadImage.data,
headers: uploadImage.headers,
accept: uploadImage.accept || 'image',
acceptMime: uploadImage.acceptMime || 'image/*',
exts: uploadImage.exts || 'jpg|png|gif|bmp|jpeg',
size: uploadImage.size || 1024 * 10,
field: uploadImage.field,
before: function (obj) {
beforeUploadCallback && beforeUploadCallback(getImageData(), context)
loding = layer.msg('文件上传中,请稍等哦', { icon: 16, shade: 0.3, time: 0 })
},
done: function (res) {
layer.close(loding)
res.data = res.data || {}
if (res.code == 0) {
setImageData(res.data)
} else if (res.code == 2) {
imagePreview(res.data, '确定使用该文件吗?', function (imageData) {
setImageData(imageData)
})
} else {
layer.msg(res.msg || '上传失败')
}
},
})
})
},
}
//如果是编辑模式,增加初始数据标识
if (!!initialData) {
initialData.isInitialData = true
}
//通过beforeOpen调整layer.open选项
options.beforeOpen && options.beforeOpen(openOptions, context)
//开启编辑器
layer.open(openOptions)
},
edit = new Edit()
form.render()
exports(MOD_NAME, edit)
})
//Custom Theme Add
function AddCustomThemes(list, contents, pimgs) {
var content = []
layui.each(list, function (index, item) {
content.push('' + item + ' ')
})
return [
'',
'主题选择 ',
'',
'' + content.join('') + ' ',
'
',
' ',
].join('')
}
// 找出当前选中范围的节点
function getRangeNodes(range) {
var cls = range.commonAncestorContainer.nodeName == 'BODY' ? range.commonAncestorContainer.children : [range.commonAncestorContainer.parentElement]
var list = []
var bool = false
for (var i = 0; i < cls.length; i++) {
var start = range.startContainer.parentElement
if (start.nodeName == 'FONT') {
start = start.parentElement
}
var end = range.endContainer.parentElement
if (end.nodeName == 'FONT') {
end = end.parentElement
}
if (!bool && cls[i] == start) {
bool = true
} else if (bool && cls[i] == end) {
list.push(cls[i])
break
}
if (bool) {
list.push(cls[i])
}
}
return list
}
//HTML 格式化
function style_html(html_source, indent_size, indent_character, max_char) {
var Parser, multi_parser
function Parser() {
this.pos = 0
this.token = ''
this.current_mode = 'CONTENT'
this.tags = {
parent: 'parent1',
parentcount: 1,
parent1: '',
}
this.tag_type = ''
this.token_text = this.last_token = this.last_text = this.token_type = ''
this.Utils = {
whitespace: '\n\r\t '.split(''),
single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed'.split(','),
extra_liners: 'head,body,/html'.split(','),
in_array: function (what, arr) {
for (var i = 0; i < arr.length; i++) {
if (what === arr[i]) {
return true
}
}
return false
},
}
this.get_content = function () {
var char = ''
var content = []
var space = false
while (this.input.charAt(this.pos) !== '<') {
if (this.pos >= this.input.length) {
return content.length ? content.join('') : ['', 'TK_EOF']
}
char = this.input.charAt(this.pos)
this.pos++
this.line_char_count++
if (this.Utils.in_array(char, this.Utils.whitespace)) {
if (content.length) {
space = true
}
this.line_char_count--
continue
} else if (space) {
if (this.line_char_count >= this.max_char) {
content.push('\n')
for (var i = 0; i < this.indent_level; i++) {
content.push(this.indent_string)
}
this.line_char_count = 0
} else {
content.push(' ')
this.line_char_count++
}
space = false
}
content.push(char)
}
return content.length ? content.join('') : ''
}
this.get_script = function () {
var char = ''
var content = []
var reg_match = new RegExp('', 'igm') //使用RegExp,无需转义
reg_match.lastIndex = this.pos
var reg_array = reg_match.exec(this.input)
var end_script = reg_array ? reg_array.index : this.input.length
while (this.pos < end_script) {
if (this.pos >= this.input.length) {
return content.length ? content.join('') : ['', 'TK_EOF']
}
char = this.input.charAt(this.pos)
this.pos++
content.push(char)
}
return content.length ? content.join('') : ''
}
this.record_tag = function (tag) {
if (this.tags[tag + 'count']) {
this.tags[tag + 'count']++
this.tags[tag + this.tags[tag + 'count']] = this.indent_level
} else {
this.tags[tag + 'count'] = 1
this.tags[tag + this.tags[tag + 'count']] = this.indent_level
}
this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent
this.tags.parent = tag + this.tags[tag + 'count']
}
this.retrieve_tag = function (tag) {
if (this.tags[tag + 'count']) {
var temp_parent = this.tags.parent
while (temp_parent) {
if (tag + this.tags[tag + 'count'] === temp_parent) {
break
}
temp_parent = this.tags[temp_parent + 'parent']
}
if (temp_parent) {
this.indent_level = this.tags[tag + this.tags[tag + 'count']]
this.tags.parent = this.tags[temp_parent + 'parent']
}
delete this.tags[tag + this.tags[tag + 'count'] + 'parent']
delete this.tags[tag + this.tags[tag + 'count']]
if (this.tags[tag + 'count'] == 1) {
delete this.tags[tag + 'count']
} else {
this.tags[tag + 'count']--
}
}
}
this.get_tag = function () {
var char = ''
var content = []
var space = false
do {
if (this.pos >= this.input.length) {
return content.length ? content.join('') : ['', 'TK_EOF']
}
char = this.input.charAt(this.pos)
this.pos++
this.line_char_count++
if (this.Utils.in_array(char, this.Utils.whitespace)) {
space = true
this.line_char_count--
continue
}
if (char === "'" || char === '"') {
if (!content[1] || content[1] !== '!') {
char += this.get_unformatted(char)
space = true
}
}
if (char === '=') {
space = false
}
if (content.length && content[content.length - 1] !== '=' && char !== '>' && space) {
if (this.line_char_count >= this.max_char) {
this.print_newline(false, content)
this.line_char_count = 0
} else {
content.push(' ')
this.line_char_count++
}
space = false
}
content.push(char)
} while (char !== '>')
var tag_complete = content.join('')
var tag_index
if (tag_complete.indexOf(' ') !== -1) {
tag_index = tag_complete.indexOf(' ')
} else {
tag_index = tag_complete.indexOf('>')
}
var tag_check = tag_complete.substring(1, tag_index).toLowerCase()
if (tag_complete.charAt(tag_complete.length - 2) === '/' || this.Utils.in_array(tag_check, this.Utils.single_token)) {
this.tag_type = 'SINGLE'
} else if (tag_check === 'script') {
this.record_tag(tag_check)
this.tag_type = 'SCRIPT'
} else if (tag_check === 'style') {
this.record_tag(tag_check)
this.tag_type = 'STYLE'
} else if (tag_check.charAt(0) === '!') {
if (tag_check.indexOf('[if') !== -1) {
if (tag_complete.indexOf('!IE') != -1) {
var comment = this.get_unformatted('-->', tag_complete)
content.push(comment)
}
this.tag_type = 'START'
} else if (tag_check.indexOf('[endif') !== -1) {
this.tag_type = 'END'
this.unindent()
} else if (tag_check.indexOf('[cdata[') != -1) {
var comment = this.get_unformatted(']]>', tag_complete)
content.push(comment)
this.tag_type = 'SINGLE'
} else {
var comment = this.get_unformatted('-->', tag_complete)
content.push(comment)
this.tag_type = 'SINGLE'
}
} else {
if (tag_check.charAt(0) === '/') {
this.retrieve_tag(tag_check.substring(1))
this.tag_type = 'END'
} else {
this.record_tag(tag_check)
this.tag_type = 'START'
}
if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) {
this.print_newline(true, this.output)
}
}
return content.join('')
}
this.get_unformatted = function (delimiter, orig_tag) {
if (orig_tag && orig_tag.indexOf(delimiter) != -1) {
return ''
}
var char = ''
var content = ''
var space = true
do {
char = this.input.charAt(this.pos)
this.pos++
if (this.Utils.in_array(char, this.Utils.whitespace)) {
if (!space) {
this.line_char_count--
continue
}
if (char === '\n' || char === '\r') {
content += '\n'
for (var i = 0; i < this.indent_level; i++) {
content += this.indent_string
}
space = false
this.line_char_count = 0
continue
}
}
content += char
this.line_char_count++
space = true
} while (content.indexOf(delimiter) == -1)
return content
}
this.get_token = function () {
var token
if (this.last_token === 'TK_TAG_SCRIPT') {
var temp_token = this.get_script()
if (typeof temp_token !== 'string') {
return temp_token
}
token = js_beautify(temp_token, this.indent_size, this.indent_character, this.indent_level)
return [token, 'TK_CONTENT']
}
if (this.current_mode === 'CONTENT') {
token = this.get_content()
if (typeof token !== 'string') {
return token
} else {
return [token, 'TK_CONTENT']
}
}
if (this.current_mode === 'TAG') {
token = this.get_tag()
if (typeof token !== 'string') {
return token
} else {
var tag_name_type = 'TK_TAG_' + this.tag_type
return [token, tag_name_type]
}
}
}
this.printer = function (js_source, indent_character, indent_size, max_char) {
this.input = js_source || ''
this.output = []
this.indent_character = indent_character || ' '
this.indent_string = ''
this.indent_size = indent_size || 2
this.indent_level = 0
this.max_char = max_char || 7000
this.line_char_count = 0
for (var i = 0; i < this.indent_size; i++) {
this.indent_string += this.indent_character
}
this.print_newline = function (ignore, arr) {
this.line_char_count = 0
if (!arr || !arr.length) {
return
}
if (!ignore) {
while (this.Utils.in_array(arr[arr.length - 1], this.Utils.whitespace)) {
arr.pop()
}
}
arr.push('\n')
for (var i = 0; i < this.indent_level; i++) {
arr.push(this.indent_string)
}
}
this.print_token = function (text) {
this.output.push(text)
}
this.indent = function () {
this.indent_level++
}
this.unindent = function () {
if (this.indent_level > 0) {
this.indent_level--
}
}
}
return this
}
multi_parser = new Parser()
multi_parser.printer(html_source, indent_character, indent_size)
var f = true
while (true) {
var t = multi_parser.get_token()
multi_parser.token_text = t[0]
multi_parser.token_type = t[1]
if (multi_parser.token_type === 'TK_EOF') {
break
}
switch (multi_parser.token_type) {
case 'TK_TAG_START':
case 'TK_TAG_SCRIPT':
case 'TK_TAG_STYLE':
multi_parser.print_newline(false, multi_parser.output)
multi_parser.print_token(multi_parser.token_text)
multi_parser.indent()
multi_parser.current_mode = 'CONTENT'
break
case 'TK_TAG_END':
if (f) multi_parser.print_newline(true, multi_parser.output)
multi_parser.print_token(multi_parser.token_text)
multi_parser.current_mode = 'CONTENT'
f = true
break
case 'TK_TAG_SINGLE':
multi_parser.print_newline(false, multi_parser.output)
multi_parser.print_token(multi_parser.token_text)
multi_parser.current_mode = 'CONTENT'
break
case 'TK_CONTENT':
if (multi_parser.token_text !== '') {
f = false
multi_parser.print_token(multi_parser.token_text)
}
multi_parser.current_mode = 'TAG'
break
}
multi_parser.last_token = multi_parser.token_type
multi_parser.last_text = multi_parser.token_text
}
return multi_parser.output.join('')
}
//JS 格式化
function js_beautify(js_source_text, indent_size, indent_character, indent_level) {
var input, output, token_text, last_type, last_text, last_word, current_mode, modes, indent_string
var whitespace, wordchar, punct, parser_pos, line_starters, in_case
var prefix, token_type, do_block_just_closed, var_line, var_line_tainted
function trim_output() {
while (output.length && (output[output.length - 1] === ' ' || output[output.length - 1] === indent_string)) {
output.pop()
}
}
function print_newline(ignore_repeated) {
ignore_repeated = typeof ignore_repeated === 'undefined' ? true : ignore_repeated
trim_output()
if (!output.length) {
return // no newline on start of file
}
if (output[output.length - 1] !== '\n' || !ignore_repeated) {
output.push('\n')
}
for (var i = 0; i < indent_level; i++) {
output.push(indent_string)
}
}
function print_space() {
var last_output = output.length ? output[output.length - 1] : ' '
if (last_output !== ' ' && last_output !== '\n' && last_output !== indent_string) {
// prevent occassional duplicate space
output.push(' ')
}
}
function print_token() {
output.push(token_text)
}
function indent() {
indent_level++
}
function unindent() {
if (indent_level) {
indent_level--
}
}
function remove_indent() {
if (output.length && output[output.length - 1] === indent_string) {
output.pop()
}
}
function set_mode(mode) {
modes.push(current_mode)
current_mode = mode
}
function restore_mode() {
do_block_just_closed = current_mode === 'DO_BLOCK'
current_mode = modes.pop()
}
function in_array(what, arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === what) {
return true
}
}
return false
}
function get_next_token() {
var n_newlines = 0
var c = ''
do {
if (parser_pos >= input.length) {
return ['', 'TK_EOF']
}
c = input.charAt(parser_pos)
parser_pos += 1
if (c === '\n') {
n_newlines += 1
}
} while (in_array(c, whitespace))
if (n_newlines > 1) {
for (var i = 0; i < 2; i++) {
print_newline(i === 0)
}
}
var wanted_newline = n_newlines === 1
if (in_array(c, wordchar)) {
if (parser_pos < input.length) {
while (in_array(input.charAt(parser_pos), wordchar)) {
c += input.charAt(parser_pos)
parser_pos += 1
if (parser_pos === input.length) {
break
}
}
}
// small and surprisingly unugly hack for 1E-10 representation
if (parser_pos !== input.length && c.match(/^[0-9]+[Ee]$/) && input.charAt(parser_pos) === '-') {
parser_pos += 1
var t = get_next_token(parser_pos)
c += '-' + t[0]
return [c, 'TK_WORD']
}
if (c === 'in') {
// hack for 'in' operator
return [c, 'TK_OPERATOR']
}
return [c, 'TK_WORD']
}
if (c === '(' || c === '[') {
return [c, 'TK_START_EXPR']
}
if (c === ')' || c === ']') {
return [c, 'TK_END_EXPR']
}
if (c === '{') {
return [c, 'TK_START_BLOCK']
}
if (c === '}') {
return [c, 'TK_END_BLOCK']
}
if (c === ';') {
return [c, 'TK_END_COMMAND']
}
if (c === '/') {
var comment = ''
// peek for comment /* ... */
if (input.charAt(parser_pos) === '*') {
parser_pos += 1
if (parser_pos < input.length) {
while (
!(input.charAt(parser_pos) === '*' && input.charAt(parser_pos + 1) && input.charAt(parser_pos + 1) === '/') &&
parser_pos < input.length
) {
comment += input.charAt(parser_pos)
parser_pos += 1
if (parser_pos >= input.length) {
break
}
}
}
parser_pos += 2
return ['/*' + comment + '*/', 'TK_BLOCK_COMMENT']
}
// peek for comment // ...
if (input.charAt(parser_pos) === '/') {
comment = c
while (input.charAt(parser_pos) !== '\x0d' && input.charAt(parser_pos) !== '\x0a') {
comment += input.charAt(parser_pos)
parser_pos += 1
if (parser_pos >= input.length) {
break
}
}
parser_pos += 1
if (wanted_newline) {
print_newline()
}
return [comment, 'TK_COMMENT']
}
}
if (
c === "'" || // string
c === '"' || // string
(c === '/' &&
((last_type === 'TK_WORD' && last_text === 'return') ||
last_type === 'TK_START_EXPR' ||
last_type === 'TK_END_BLOCK' ||
last_type === 'TK_OPERATOR' ||
last_type === 'TK_EOF' ||
last_type === 'TK_END_COMMAND'))
) {
// regexp
var sep = c
var esc = false
c = ''
if (parser_pos < input.length) {
while (esc || input.charAt(parser_pos) !== sep) {
c += input.charAt(parser_pos)
if (!esc) {
esc = input.charAt(parser_pos) === '\\'
} else {
esc = false
}
parser_pos += 1
if (parser_pos >= input.length) {
break
}
}
}
parser_pos += 1
if (last_type === 'TK_END_COMMAND') {
print_newline()
}
return [sep + c + sep, 'TK_STRING']
}
if (in_array(c, punct)) {
while (parser_pos < input.length && in_array(c + input.charAt(parser_pos), punct)) {
c += input.charAt(parser_pos)
parser_pos += 1
if (parser_pos >= input.length) {
break
}
}
return [c, 'TK_OPERATOR']
}
return [c, 'TK_UNKNOWN']
}
//----------------------------------
indent_character = indent_character || ' '
indent_size = indent_size || 4
indent_string = ''
while (indent_size--) {
indent_string += indent_character
}
input = js_source_text
last_word = '' // last 'TK_WORD' passed
last_type = 'TK_START_EXPR' // last token type
last_text = '' // last token text
output = []
do_block_just_closed = false
var_line = false
var_line_tainted = false
whitespace = '\n\r\t '.split('')
wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split('')
punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |='.split(' ')
// words which should always start on new line.
line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(',')
// states showing if we are currently in expression (i.e. "if" case) - 'EXPRESSION', or in usual block (like, procedure), 'BLOCK'.
// some formatting depends on that.
current_mode = 'BLOCK'
modes = [current_mode]
indent_level = indent_level || 0
parser_pos = 0 // parser position
in_case = false // flag for parser that case/default has been processed, and next colon needs special attention
while (true) {
var t = get_next_token(parser_pos)
token_text = t[0]
token_type = t[1]
if (token_type === 'TK_EOF') {
break
}
switch (token_type) {
case 'TK_START_EXPR':
var_line = false
set_mode('EXPRESSION')
if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR') {
// do nothing on (( and )( and ][ and ]( ..
} else if (last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR') {
print_space()
} else if (in_array(last_word, line_starters) && last_word !== 'function') {
print_space()
}
print_token()
break
case 'TK_END_EXPR':
print_token()
restore_mode()
break
case 'TK_START_BLOCK':
if (last_word === 'do') {
set_mode('DO_BLOCK')
} else {
set_mode('BLOCK')
}
if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') {
if (last_type === 'TK_START_BLOCK') {
print_newline()
} else {
print_space()
}
}
print_token()
indent()
break
case 'TK_END_BLOCK':
if (last_type === 'TK_START_BLOCK') {
// nothing
trim_output()
unindent()
} else {
unindent()
print_newline()
}
print_token()
restore_mode()
break
case 'TK_WORD':
if (do_block_just_closed) {
print_space()
print_token()
print_space()
break
}
if (token_text === 'case' || token_text === 'default') {
if (last_text === ':') {
// switch cases following one another
remove_indent()
} else {
// case statement starts in the same line where switch
unindent()
print_newline()
indent()
}
print_token()
in_case = true
break
}
prefix = 'NONE'
if (last_type === 'TK_END_BLOCK') {
if (!in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) {
prefix = 'NEWLINE'
} else {
prefix = 'SPACE'
print_space()
}
} else if (last_type === 'TK_END_COMMAND' && (current_mode === 'BLOCK' || current_mode === 'DO_BLOCK')) {
prefix = 'NEWLINE'
} else if (last_type === 'TK_END_COMMAND' && current_mode === 'EXPRESSION') {
prefix = 'SPACE'
} else if (last_type === 'TK_WORD') {
prefix = 'SPACE'
} else if (last_type === 'TK_START_BLOCK') {
prefix = 'NEWLINE'
} else if (last_type === 'TK_END_EXPR') {
print_space()
prefix = 'NEWLINE'
}
if (last_type !== 'TK_END_BLOCK' && in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) {
print_newline()
} else if (in_array(token_text, line_starters) || prefix === 'NEWLINE') {
if (last_text === 'else') {
// no need to force newline on else break
print_space()
} else if ((last_type === 'TK_START_EXPR' || last_text === '=') && token_text === 'function') {
// no need to force newline on 'function': (function
// DONOTHING
} else if (last_type === 'TK_WORD' && (last_text === 'return' || last_text === 'throw')) {
// no newline between 'return nnn'
print_space()
} else if (last_type !== 'TK_END_EXPR') {
if ((last_type !== 'TK_START_EXPR' || token_text !== 'var') && last_text !== ':') {
// no need to force newline on 'var': for (var x = 0...)
if (token_text === 'if' && last_type === 'TK_WORD' && last_word === 'else') {
// no newline for } else if {
print_space()
} else {
print_newline()
}
}
} else {
if (in_array(token_text, line_starters) && last_text !== ')') {
print_newline()
}
}
} else if (prefix === 'SPACE') {
print_space()
}
print_token()
last_word = token_text
if (token_text === 'var') {
var_line = true
var_line_tainted = false
}
break
case 'TK_END_COMMAND':
print_token()
var_line = false
break
case 'TK_STRING':
if (last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK') {
print_newline()
} else if (last_type === 'TK_WORD') {
print_space()
}
print_token()
break
case 'TK_OPERATOR':
var start_delim = true
var end_delim = true
if (var_line && token_text !== ',') {
var_line_tainted = true
if (token_text === ':') {
var_line = false
}
}
if (token_text === ':' && in_case) {
print_token() // colon really asks for separate treatment
print_newline()
break
}
in_case = false
if (token_text === ',') {
if (var_line) {
if (var_line_tainted) {
print_token()
print_newline()
var_line_tainted = false
} else {
print_token()
print_space()
}
} else if (last_type === 'TK_END_BLOCK') {
print_token()
print_newline()
} else {
if (current_mode === 'BLOCK') {
print_token()
print_newline()
} else {
// EXPR od DO_BLOCK
print_token()
print_space()
}
}
break
} else if (token_text === '--' || token_text === '++') {
// unary operators special case
if (last_text === ';') {
// space for (;; ++i)
start_delim = true
end_delim = false
} else {
start_delim = false
end_delim = false
}
} else if (token_text === '!' && last_type === 'TK_START_EXPR') {
// special case handling: if (!a)
start_delim = false
end_delim = false
} else if (last_type === 'TK_OPERATOR') {
start_delim = false
end_delim = false
} else if (last_type === 'TK_END_EXPR') {
start_delim = true
end_delim = true
} else if (token_text === '.') {
// decimal digits or object.property
start_delim = false
end_delim = false
} else if (token_text === ':') {
// zz: xx
// can't differentiate ternary op, so for now it's a ? b: c; without space before colon
if (last_text.match(/^\d+$/)) {
// a little help for ternary a ? 1 : 0;
start_delim = true
} else {
start_delim = false
}
}
if (start_delim) {
print_space()
}
print_token()
if (end_delim) {
print_space()
}
break
case 'TK_BLOCK_COMMENT':
print_newline()
print_token()
print_newline()
break
case 'TK_COMMENT':
// print_newline();
print_space()
print_token()
print_newline()
break
case 'TK_UNKNOWN':
print_token()
break
default:
break
}
last_type = token_type
last_text = token_text
}
return output.join('')
}