修复layer组件的回调及对shift属性的优化;移植meditor到新的框架
parent
8be3b9c70a
commit
d256f145cf
|
@ -4,7 +4,7 @@ $cpp: #651fff #7c4dff #6200ea;
|
|||
$cb: #2196f3 #64b5f6 #1976d2;
|
||||
$cr: #ff5722 #ff7043 #e64a19;
|
||||
$co: #ff9800 #ffa726 #f57c00;
|
||||
$cp: #e7e8eb #ecf0f1 #bdc3c7;
|
||||
$cp: #e7e8eb #ecf0f1 #d3d5db;
|
||||
$cgr: #546e7a #607d8b #37474f;
|
||||
|
||||
@mixin ts($c: all, $t: .2s, $m: ease-in-out){
|
||||
|
|
|
@ -182,8 +182,8 @@ class __layer__ {
|
|||
}
|
||||
},
|
||||
mounted: function() {
|
||||
if (typeof this.success === 'function') {
|
||||
this.success(_id)
|
||||
if (typeof this.props.success === 'function') {
|
||||
this.props.success.call(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +216,9 @@ class __layer__ {
|
|||
layBox.classList.add('__' + state.shift)
|
||||
} else {
|
||||
for (let k in state.shift) {
|
||||
layBox.style.cssText += `${k}: ${state.shift[k]};`
|
||||
let val = state.shift[k]
|
||||
val += isFinite(val) ? 'px' : ''
|
||||
layBox.style.cssText += `${k}: ${val};`
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,14 +5,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
define([
|
||||
'lib/layer/base',
|
||||
'css!./attach'
|
||||
], function(){
|
||||
'use strict'
|
||||
|
||||
define(['lib/layer/base', 'css!./attach'], function() {
|
||||
var Uploader = function(url) {
|
||||
this.url = url || ''
|
||||
this.init()
|
||||
|
@ -41,14 +36,16 @@ define([
|
|||
|
||||
var startTime = Date.now()
|
||||
|
||||
this.xhr.upload.addEventListener('progress', function(evt){
|
||||
|
||||
this.xhr.upload.addEventListener(
|
||||
'progress',
|
||||
function(evt) {
|
||||
if (evt.lengthComputable && _this.progress) {
|
||||
var res = Math.round(evt.loaded * 100 / evt.total)
|
||||
_this.progress(res)
|
||||
}
|
||||
|
||||
}, false)
|
||||
},
|
||||
false
|
||||
)
|
||||
|
||||
this.xhr.onreadystatechange = function() {
|
||||
if (_this.xhr.readyState === 4) {
|
||||
|
@ -65,7 +62,6 @@ define([
|
|||
}
|
||||
|
||||
this.xhr.send(this.form)
|
||||
|
||||
},
|
||||
onProgress: function(fn) {
|
||||
this.progress = fn
|
||||
|
@ -77,12 +73,12 @@ define([
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function uploadScreenshot(vm, blob) {
|
||||
var upload = new Uploader(vm.uploadUrl || ME.uploadUrl)
|
||||
if (ME.beforeUpload) {
|
||||
ME.beforeUpload(Date.now().toString(16) + '.jpg', function(qn) {
|
||||
upload.field('file', blob)
|
||||
upload
|
||||
.field('file', blob)
|
||||
.field('token', qn.token)
|
||||
.field('key', qn.key)
|
||||
.onEnd(function(json) {
|
||||
|
@ -91,7 +87,8 @@ define([
|
|||
.start()
|
||||
})
|
||||
} else {
|
||||
upload.field('file', blob)
|
||||
upload
|
||||
.field('file', blob)
|
||||
.onEnd(function(json) {
|
||||
ME.insert(vm.$editor, '![截图](' + json.data.url + ')')
|
||||
})
|
||||
|
@ -99,13 +96,16 @@ define([
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
var $init = function(vm) {
|
||||
if (!vm.uploadUrl && !ME.uploadUrl) {
|
||||
console.error('使用附件上传,必须先设置uploadUrl;\n可以给vm增加uploadUrl属性,也可以通过ME.uploadUrl设置')
|
||||
console.error(
|
||||
'使用附件上传,必须先设置uploadUrl;\n可以给vm增加uploadUrl属性,也可以通过ME.uploadUrl设置'
|
||||
)
|
||||
}
|
||||
if (!vm.manageUrl && !ME.manageUrl) {
|
||||
console.error('使用附件管理功能,必须先设置manageUrl;\n可以给vm增加manageUrl属性,也可以通过ME.manageUrl设置')
|
||||
console.error(
|
||||
'使用附件管理功能,必须先设置manageUrl;\n可以给vm增加manageUrl属性,也可以通过ME.manageUrl设置'
|
||||
)
|
||||
}
|
||||
if (!ME.maxSize) {
|
||||
ME.maxSize = 4194304
|
||||
|
@ -113,7 +113,7 @@ define([
|
|||
|
||||
vm.$editor.addEventListener('paste', function(ev) {
|
||||
var txt = ev.clipboardData.getData('text/plain').trim(),
|
||||
html = ev.clipboardData.getData('text/html').trim();
|
||||
html = ev.clipboardData.getData('text/html').trim()
|
||||
|
||||
//文本类型直接默认处理
|
||||
if (txt || html) {
|
||||
|
@ -123,8 +123,8 @@ define([
|
|||
if (ev.clipboardData.items) {
|
||||
var items = ev.clipboardData.items,
|
||||
len = items.length,
|
||||
blob = null;
|
||||
for(var i = 0,it; it = items[i++];){
|
||||
blob = null
|
||||
for (var i = 0, it; (it = items[i++]); ) {
|
||||
if (it.type.indexOf('image') > -1) {
|
||||
blob = it.getAsFile()
|
||||
}
|
||||
|
@ -146,17 +146,20 @@ define([
|
|||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||
ctx.drawImage(this, 0, 0, canvas.width, canvas.height)
|
||||
|
||||
|
||||
if (canvas.toBlob) {
|
||||
canvas.toBlob(function(obj){
|
||||
canvas.toBlob(
|
||||
function(obj) {
|
||||
uploadScreenshot(vm, obj)
|
||||
}, 'image/jpeg', 0.8)
|
||||
},
|
||||
'image/jpeg',
|
||||
0.8
|
||||
)
|
||||
} else {
|
||||
var base64 = canvas.toDataURL('image/jpeg', 0.8),
|
||||
buf = atob(base64.split(',')[1]),
|
||||
arrBuf = new ArrayBuffer(buf.length),
|
||||
intArr = new Uint8Array(arrBuf),
|
||||
obj = null;
|
||||
obj = null
|
||||
|
||||
for (var i = 0; i < buf.length; i++) {
|
||||
intArr[i] = buf.charCodeAt(i)
|
||||
|
@ -164,8 +167,6 @@ define([
|
|||
obj = new Blob([intArr], { type: 'image/jpeg' })
|
||||
uploadScreenshot(vm, obj)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
img.src = this.result
|
||||
}
|
||||
|
@ -181,52 +182,63 @@ define([
|
|||
},
|
||||
opened = false, //记录是否已经打开
|
||||
openType = 'image', //打开类型, 图片/附件
|
||||
cache = { //缓存附件列表
|
||||
cache = {
|
||||
//缓存附件列表
|
||||
image: [],
|
||||
file: []
|
||||
},
|
||||
fixCont = function() {
|
||||
return '<dl class="do-meditor-attach do-meditor-font">'
|
||||
+ '<dt class="tab-box" :drag="do-layer" data-limit="window">'
|
||||
+ '<span class="item" :class="active:tab === 1" :click="$switch(1)">' + lang[openType][0] +'</span>'
|
||||
+ '<span class="item" :class="active:tab === 2" :click="$switch(2)">本地上传</span>'
|
||||
+ '<span class="item" :class="active:tab === 3" :click="$switch(3)">' + lang[openType][1] + '</span>'
|
||||
+ '<a href="javascript:;" :click="no" class="action-close do-ui-font"></a>'
|
||||
+ '</dt>'
|
||||
+ '<dt class="cont-box">'
|
||||
+ '<div class="remote" :visible="tab === 1">'
|
||||
+ '<section class="section do-fn-cl input"><span class="label">'+ lang[openType][2] + '</span>'
|
||||
+ '<input class="txt" :duplex="attachAlt" />'
|
||||
+ '</section>'
|
||||
+ '<section class="section do-fn-cl input"><span class="label">'+ lang[openType][3] + '</span>'
|
||||
+ '<input class="txt" :duplex="attach" />'
|
||||
+ '</section>'
|
||||
+ '<section class="section do-fn-cl">'
|
||||
+ '<a href="javascript:;" class="submit" :click="$confirm">确定</a>'
|
||||
+ '</section>'
|
||||
+ '</div>'
|
||||
+ '<div class="local" :visible="tab === 2">'
|
||||
+ '<div class="select-file"><input id="meditor-attch" multiple :change="$change" type="file" class="hide" /><span class="file" :click="$select">选择文件</span><span class="tips">(上传大小限制:单文件最大 '
|
||||
+ ((ME.maxSize/1048576).toFixed(2) - 0)
|
||||
+ 'MB)</span></div>'
|
||||
+ '<ul class="upload-box">'
|
||||
+ '<li class="tr thead"><span class="td name">文件名</span><span class="td progress">上传进度</span><span class="td option">操作</span></li>'
|
||||
+ '<li class="tr" :repeat="uploadFile">'
|
||||
+ '<span class="td name" :text="el.name"></span>'
|
||||
+ '<span class="td progress" :html="el.progress"></span>'
|
||||
+ '<span class="td option"><a href="javascript:;" :click="$insert(el)">插入</a></span>'
|
||||
+ '</li>'
|
||||
+ '</ul>'
|
||||
+ '</div>'
|
||||
+ '<ul class="manager" :visible="tab === 3">'
|
||||
+ '<li class="item" :repeat="attachList" :click="$insert(el)">'
|
||||
+ '<span class="thumb" :html="el.thumb"></span>'
|
||||
+ '<p class="name" :attr-title="el.name" :text="el.name"></p>'
|
||||
+ '</li>'
|
||||
+ '</ul>'
|
||||
+ '</dt>'
|
||||
+ '</dl>'
|
||||
};
|
||||
return (
|
||||
'<dl class="do-meditor-attach do-meditor-font">' +
|
||||
'<dt class="tab-box" :drag="do-layer" data-limit="window">' +
|
||||
'<span class="item" :class="active:tab === 1" :click="$switch(1)">' +
|
||||
lang[openType][0] +
|
||||
'</span>' +
|
||||
'<span class="item" :class="active:tab === 2" :click="$switch(2)">本地上传</span>' +
|
||||
'<span class="item" :class="active:tab === 3" :click="$switch(3)">' +
|
||||
lang[openType][1] +
|
||||
'</span>' +
|
||||
'<a href="javascript:;" :click="no" class="action-close do-ui-font"></a>' +
|
||||
'</dt>' +
|
||||
'<dt class="cont-box">' +
|
||||
'<div class="remote" :visible="tab === 1">' +
|
||||
'<section class="section do-fn-cl input"><span class="label">' +
|
||||
lang[openType][2] +
|
||||
'</span>' +
|
||||
'<input class="txt" :duplex="attachAlt" />' +
|
||||
'</section>' +
|
||||
'<section class="section do-fn-cl input"><span class="label">' +
|
||||
lang[openType][3] +
|
||||
'</span>' +
|
||||
'<input class="txt" :duplex="attach" />' +
|
||||
'</section>' +
|
||||
'<section class="section do-fn-cl">' +
|
||||
'<a href="javascript:;" class="submit" :click="$confirm">确定</a>' +
|
||||
'</section>' +
|
||||
'</div>' +
|
||||
'<div class="local" :visible="tab === 2">' +
|
||||
'<div class="select-file"><input id="meditor-attch" multiple :change="$change" type="file" class="hide" /><span class="file" :click="$select">选择文件</span><span class="tips">(上传大小限制:单文件最大 ' +
|
||||
((ME.maxSize / 1048576).toFixed(2) - 0) +
|
||||
'MB)</span></div>' +
|
||||
'<ul class="upload-box">' +
|
||||
'<li class="tr thead"><span class="td name">文件名</span><span class="td progress">上传进度</span><span class="td option">操作</span></li>' +
|
||||
'<li class="tr" :repeat="uploadFile">' +
|
||||
'<span class="td name" :text="el.name"></span>' +
|
||||
'<span class="td progress" :html="el.progress"></span>' +
|
||||
'<span class="td option"><a href="javascript:;" :click="$insert(el)">插入</a></span>' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'</div>' +
|
||||
'<ul class="manager" :visible="tab === 3">' +
|
||||
'<li class="item" :repeat="attachList" :click="$insert(el)">' +
|
||||
'<span class="thumb" :html="el.thumb"></span>' +
|
||||
'<p class="name" :attr-title="el.name" :text="el.name"></p>' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'</dt>' +
|
||||
'</dl>'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* [uploadFile 文件上传]
|
||||
|
@ -235,17 +247,28 @@ define([
|
|||
* @param {[type]} type [image/file]
|
||||
*/
|
||||
function uploadFile(files, vm) {
|
||||
for(var i = 0, it; it = files[i++];){
|
||||
|
||||
if(openType === 'image' && !/\.(jpg|jpeg|png|gif|bmp|webp|ico)$/.test(it.name)){
|
||||
vm.uploadFile.push({name: it.name, progress: '<span class="red">0%(失败,不允许的文件类型)</span>', url: ''})
|
||||
for (var i = 0, it; (it = files[i++]); ) {
|
||||
if (
|
||||
openType === 'image' &&
|
||||
!/\.(jpg|jpeg|png|gif|bmp|webp|ico)$/.test(it.name)
|
||||
) {
|
||||
vm.uploadFile.push({
|
||||
name: it.name,
|
||||
progress: '<span class="red">0%(失败,不允许的文件类型)</span>',
|
||||
url: ''
|
||||
})
|
||||
continue
|
||||
}
|
||||
if (ME.maxSize > 0 && it.size > ME.maxSize) {
|
||||
vm.uploadFile.push({name: it.name, progress: '<span class="red">0%(文件体积过大)</span>', url: ''})
|
||||
vm.uploadFile.push({
|
||||
name: it.name,
|
||||
progress: '<span class="red">0%(文件体积过大)</span>',
|
||||
url: ''
|
||||
})
|
||||
continue
|
||||
}
|
||||
var fixName = Date.now().toString(16) + it.name.slice(it.name.lastIndexOf('.'))
|
||||
var fixName =
|
||||
Date.now().toString(16) + it.name.slice(it.name.lastIndexOf('.'))
|
||||
|
||||
var idx = vm.uploadFile.length,
|
||||
upload = new Uploader(vm.uploadUrl || ME.uploadUrl)
|
||||
|
@ -256,28 +279,33 @@ define([
|
|||
|
||||
if (ME.beforeUpload) {
|
||||
ME.beforeUpload(fixName, function(qn) {
|
||||
|
||||
upload.field('token', qn.token)
|
||||
upload
|
||||
.field('token', qn.token)
|
||||
.field('key', qn.key)
|
||||
.onProgress(function(val) {
|
||||
vm.uploadFile[idx].progress = val + '%'
|
||||
}).onEnd(function(json){
|
||||
})
|
||||
.onEnd(function(json) {
|
||||
vm.uploadFile[idx].url = qn.url
|
||||
}).start()
|
||||
})
|
||||
.start()
|
||||
})
|
||||
} else {
|
||||
upload.onProgress(function(val){
|
||||
upload
|
||||
.onProgress(function(val) {
|
||||
vm.uploadFile[idx].progress = val + '%'
|
||||
}).onEnd(function(json){
|
||||
})
|
||||
.onEnd(function(json) {
|
||||
vm.uploadFile[idx].url = json.data.url
|
||||
}).start()
|
||||
})
|
||||
.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getAttach(vm, cb) {
|
||||
var xhr = new XMLHttpRequest(),
|
||||
url = vm.manageUrl || ME.manageUrl;
|
||||
url = vm.manageUrl || ME.manageUrl
|
||||
|
||||
if (/\?/.test(url)) {
|
||||
url += '&type=' + openType
|
||||
|
@ -288,9 +316,11 @@ define([
|
|||
|
||||
xhr.open('GET', url, true)
|
||||
xhr.onreadystatechange = function() {
|
||||
if(this.readyState === 4 &&
|
||||
if (
|
||||
this.readyState === 4 &&
|
||||
this.status === 200 &&
|
||||
this.responseText !== ''){
|
||||
this.responseText !== ''
|
||||
) {
|
||||
var res = this.responseText
|
||||
try {
|
||||
res = JSON.parse(res)
|
||||
|
@ -330,7 +360,10 @@ define([
|
|||
getAttach(vm, function(json) {
|
||||
if (json) {
|
||||
cache[openType] = json.data.list.map(function(it) {
|
||||
it.thumb = openType === 'image' ? '<img src="' + it.url + '"/>' : '<em class="attach-icon"></em>'
|
||||
it.thumb =
|
||||
openType === 'image'
|
||||
? '<img src="' + it.url + '"/>'
|
||||
: '<em class="attach-icon"></em>'
|
||||
return it
|
||||
})
|
||||
lvm.attachList = json.data.list
|
||||
|
@ -338,8 +371,6 @@ define([
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
$select: yua.noop,
|
||||
$change: yua.noop,
|
||||
|
@ -347,8 +378,13 @@ define([
|
|||
if (!it.url) {
|
||||
return
|
||||
}
|
||||
var val = (openType === 'image' ? '!' : '')
|
||||
+ '[' + it.name + '](' + it.url + ')'
|
||||
var val =
|
||||
(openType === 'image' ? '!' : '') +
|
||||
'[' +
|
||||
it.name +
|
||||
'](' +
|
||||
it.url +
|
||||
')'
|
||||
ME.insert(vm.$editor, val)
|
||||
},
|
||||
$confirm: function() {
|
||||
|
@ -372,7 +408,7 @@ define([
|
|||
_this.$select = function() {
|
||||
var ev = document.createEvent('MouseEvent')
|
||||
ev.initEvent('click', false, false)
|
||||
$file.dispatchEvent(ev);
|
||||
$file.dispatchEvent(ev)
|
||||
}
|
||||
_this.$change = function() {
|
||||
uploadFile(this.files, _this)
|
||||
|
@ -382,7 +418,6 @@ define([
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
ME.addon.image = function(elem, vm) {
|
||||
if (opened) {
|
||||
return
|
||||
|
@ -391,7 +426,6 @@ define([
|
|||
showDialog(elem, vm)
|
||||
}
|
||||
|
||||
|
||||
ME.addon.file = function(elem, vm) {
|
||||
if (opened) {
|
||||
return
|
||||
|
@ -400,15 +434,5 @@ define([
|
|||
showDialog(elem, vm)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return $init
|
||||
|
||||
|
||||
})
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
|
||||
'use strict'
|
||||
import 'layer/base'
|
||||
import 'layer/index'
|
||||
|
||||
function objArr(num) {
|
||||
var arr = []
|
||||
let arr = []
|
||||
while (num > 0) {
|
||||
arr.push({ v: 0 })
|
||||
num--
|
||||
|
@ -19,292 +19,373 @@ function objArr(num) {
|
|||
function trim(str, sign) {
|
||||
return str.replace(new RegExp('^' + sign + '|' + sign + '$', 'g'), '')
|
||||
}
|
||||
function getOrderArr(len) {
|
||||
var arr = [],
|
||||
i = 0
|
||||
while (i < len) {
|
||||
arr.push(i++)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
const addon = {
|
||||
h1: function(elem, vm) {
|
||||
var offset = Anot(elem).offset(),
|
||||
wrap = ME.selection(vm.$editor, true) || '在此输入文本',
|
||||
h1ID = layer.open({
|
||||
let that = this
|
||||
let editor = vm.$refs.editor
|
||||
let offset = Anot(elem).offset()
|
||||
let wrap = this.selection(editor, true) || '在此输入文本'
|
||||
layer.open({
|
||||
type: 7,
|
||||
menubar: false,
|
||||
shadeClose: true,
|
||||
maskClose: true,
|
||||
fixed: true,
|
||||
$insert: function(level) {
|
||||
insert: function(level) {
|
||||
wrap = wrap.replace(/^#{1,6} /, '')
|
||||
wrap = ME.repeat('#', level) + ' ' + wrap
|
||||
ME.insert(vm.$editor, wrap, true)
|
||||
layer.close(h1ID)
|
||||
wrap = that.repeat('#', level) + ' ' + wrap
|
||||
that.insert(editor, wrap, true)
|
||||
this.close()
|
||||
},
|
||||
offset: [
|
||||
offset.top + 37 - ME.doc.scrollTop(),
|
||||
offset.top + 40 - that.doc.scrollTop(),
|
||||
'auto',
|
||||
'auto',
|
||||
offset.left - ME.doc.scrollLeft()
|
||||
offset.left - that.doc.scrollLeft()
|
||||
],
|
||||
content:
|
||||
'<ul class="do-meditor-h1 do-fn-noselect do-meditor-font">' +
|
||||
'<li :click="$insert(1)" class="h1">一级标题</li>' +
|
||||
'<li :click="$insert(2)" class="h2">二级标题</li>' +
|
||||
'<li :click="$insert(3)" class="h3">三级标题</li>' +
|
||||
'<li :click="$insert(4)" class="h4">四级标题</li>' +
|
||||
'<li :click="$insert(5)" class="h5">五级标题</li>' +
|
||||
'<li :click="$insert(6)" class="h6">六级标题</li>' +
|
||||
'</ul>'
|
||||
shift: {
|
||||
top: offset.top - that.doc.scrollTop(),
|
||||
left: offset.left - that.doc.scrollLeft()
|
||||
},
|
||||
content: `
|
||||
<ul class="do-meditor-h1 do-fn-noselect do-meditor__font">
|
||||
<li :click="insert(1)" class="h1"><i class="do-meditor__icon icon-h1"></i>一级标题</li>
|
||||
<li :click="insert(2)" class="h2"><i class="do-meditor__icon icon-h2"></i>二级标题</li>
|
||||
<li :click="insert(3)" class="h3"><i class="do-meditor__icon icon-h3"></i>三级标题</li>
|
||||
<li :click="insert(4)" class="h4"><i class="do-meditor__icon icon-h4"></i>四级标题</li>
|
||||
<li :click="insert(5)" class="h5"><i class="do-meditor__icon icon-h5"></i>五级标题</li>
|
||||
<li :click="insert(6)" class="h6"><i class="do-meditor__icon icon-h6"></i>六级标题</li>
|
||||
</ul>`
|
||||
})
|
||||
},
|
||||
quote: function(elem, vm) {
|
||||
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||
let wrap = this.selection(vm.$refs.editor) || '在此输入文本'
|
||||
wrap = '> ' + wrap
|
||||
|
||||
ME.insert(vm.$editor, wrap, true)
|
||||
this.insert(vm.$refs.editor, wrap, true)
|
||||
},
|
||||
bold: function(elem, vm) {
|
||||
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||
wraped = trim(wrap, '\\*\\*')
|
||||
let wrap = this.selection(vm.$refs.editor) || '在此输入文本'
|
||||
let wraped = trim(wrap, '\\*\\*')
|
||||
|
||||
wrap = wrap === wraped ? '**' + wrap + '**' : wraped
|
||||
|
||||
ME.insert(vm.$editor, wrap, true)
|
||||
this.insert(vm.$refs.editor, wrap, true)
|
||||
},
|
||||
italic: function(elem, vm) {
|
||||
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||
wraped = trim(wrap, '_')
|
||||
let wrap = this.selection(vm.$refs.editor) || '在此输入文本'
|
||||
let wraped = trim(wrap, '_')
|
||||
|
||||
wrap = wrap === wraped ? '_' + wrap + '_' : wraped
|
||||
|
||||
ME.insert(vm.$editor, wrap, true)
|
||||
this.insert(vm.$refs.editor, wrap, true)
|
||||
},
|
||||
through: function(elem, vm) {
|
||||
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||
wraped = trim(wrap, '~~')
|
||||
let wrap = this.selection(vm.$refs.editor) || '在此输入文本'
|
||||
let wraped = trim(wrap, '~~')
|
||||
|
||||
wrap = wrap === wraped ? '~~' + wrap + '~~' : wraped
|
||||
|
||||
ME.insert(vm.$editor, wrap, true)
|
||||
this.insert(vm.$refs.editor, wrap, true)
|
||||
},
|
||||
unordered: function(elem, vm) {
|
||||
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||
let wrap = this.selection(vm.$refs.editor) || '在此输入文本'
|
||||
wrap = '* ' + wrap
|
||||
|
||||
ME.insert(vm.$editor, wrap, false)
|
||||
this.insert(vm.$refs.editor, wrap, false)
|
||||
},
|
||||
ordered: function(elem, vm) {
|
||||
var wrap = ME.selection(vm.$editor) || '在此输入文本'
|
||||
let wrap = this.selection(vm.$refs.editor) || '在此输入文本'
|
||||
wrap = '1. ' + wrap
|
||||
|
||||
ME.insert(vm.$editor, wrap, false)
|
||||
this.insert(vm.$refs.editor, wrap, false)
|
||||
},
|
||||
hr: function(elem, vm) {
|
||||
ME.insert(vm.$editor, '\n\n---\n\n', false)
|
||||
this.insert(vm.$refs.editor, '\n\n---\n\n', false)
|
||||
},
|
||||
link: function(elem, vm) {
|
||||
var offset = Anot(elem).offset(),
|
||||
wrap = ME.selection(vm.$editor) || '',
|
||||
layid = layer.open({
|
||||
let that = this
|
||||
let offset = Anot(elem).offset()
|
||||
let wrap = this.selection(vm.$refs.editor) || ''
|
||||
|
||||
layer.open({
|
||||
type: 7,
|
||||
menubar: false,
|
||||
shadeClose: true,
|
||||
maskClose: true,
|
||||
fixed: true,
|
||||
link: '',
|
||||
linkName: wrap,
|
||||
linkTarget: 1,
|
||||
$confirm: function() {
|
||||
var lvm = Anot.vmodels[layid]
|
||||
if (!lvm.link || !lvm.linkName) {
|
||||
return layer.alert('链接文字和地址不能为空')
|
||||
insert: function() {
|
||||
if (!this.link || !this.linkName) {
|
||||
return layer.toast('链接文字和地址不能为空', 'error')
|
||||
}
|
||||
var val =
|
||||
'[' +
|
||||
lvm.linkName +
|
||||
'](' +
|
||||
lvm.link +
|
||||
(lvm.linkTarget === 1 ? ' "target=_blank"' : '') +
|
||||
')'
|
||||
ME.insert(vm.$editor, val, false)
|
||||
layer.close(layid)
|
||||
let val = `[${this.linkName}](${this.link} ${
|
||||
this.linkTarget === 1 ? ' "target=_blank"' : ''
|
||||
})`
|
||||
|
||||
that.insert(vm.$refs.editor, val, false)
|
||||
this.close()
|
||||
},
|
||||
offset: [
|
||||
offset.top + 37 - ME.doc.scrollTop(),
|
||||
offset.top + 40 - that.doc.scrollTop(),
|
||||
'auto',
|
||||
'auto',
|
||||
offset.left - ME.doc.scrollLeft()
|
||||
offset.left - that.doc.scrollLeft()
|
||||
],
|
||||
content:
|
||||
'<div class="do-meditor-common do-meditor-font">' +
|
||||
'<section class="input"><span class="label">链接文字</span>' +
|
||||
'<input class="txt" :duplex="linkName" />' +
|
||||
'</section>' +
|
||||
'<section class="input"><span class="label">链接地址</span>' +
|
||||
'<input class="txt" :duplex="link"/>' +
|
||||
'</section>' +
|
||||
'<section>' +
|
||||
'<label><input name="link" type="radio" class="radio" :duplex-number="linkTarget" value="1"/> 新窗口打开</label>' +
|
||||
'<label><input name="link" type="radio" class="radio" :duplex-number="linkTarget" value="2"/> 本窗口打开</label>' +
|
||||
'</section>' +
|
||||
'<section>' +
|
||||
'<a href="javascript:;" class="submit" :click="$confirm">确定</a>' +
|
||||
'</section>' +
|
||||
'</div>'
|
||||
shift: {
|
||||
top: offset.top - that.doc.scrollTop(),
|
||||
left: offset.left - that.doc.scrollLeft()
|
||||
},
|
||||
content: `
|
||||
<div class="do-meditor-common do-meditor__font">
|
||||
<section class="input">
|
||||
<input class="txt" :duplex="linkName" placeholder="链接文字"/>
|
||||
</section>
|
||||
<section class="input">
|
||||
<input class="txt" :duplex="link" placeholder="链接地址"/>
|
||||
</section>
|
||||
<section>
|
||||
<label>
|
||||
<input
|
||||
name="link"
|
||||
type="radio"
|
||||
class="radio"
|
||||
:duplex-number="linkTarget"
|
||||
value="1"/>
|
||||
新窗口打开
|
||||
</label>
|
||||
<label>
|
||||
<input
|
||||
name="link"
|
||||
type="radio"
|
||||
class="radio"
|
||||
:duplex-number="linkTarget"
|
||||
value="2"/>
|
||||
本窗口打开
|
||||
</label>
|
||||
</section>
|
||||
<section>
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="do-meditor__button submit"
|
||||
:click="insert">确定</a>
|
||||
</section>
|
||||
</div>`
|
||||
})
|
||||
},
|
||||
time: function(elem, vm) {
|
||||
ME.insert(vm.$editor, new Date().format(), false)
|
||||
this.insert(vm.$refs.editor, new Date().format(), false)
|
||||
},
|
||||
face: function(elem, vm) {
|
||||
var offset = Anot(elem).offset(),
|
||||
faceid = 0,
|
||||
layid = layer.open({
|
||||
let that = this
|
||||
let offset = Anot(elem).offset()
|
||||
|
||||
layer.open({
|
||||
type: 7,
|
||||
title: '插入表情',
|
||||
fixed: true,
|
||||
shadeClose: true,
|
||||
arr: getOrderArr(36),
|
||||
offset: [
|
||||
offset.top + 37 - ME.doc.scrollTop(),
|
||||
'auto',
|
||||
'auto',
|
||||
offset.left - ME.doc.scrollLeft()
|
||||
maskClose: true,
|
||||
arr: [
|
||||
'😀',
|
||||
'😅',
|
||||
'😂',
|
||||
'🤣',
|
||||
'😇',
|
||||
'😉',
|
||||
'😍',
|
||||
'😗',
|
||||
'😋',
|
||||
'😛',
|
||||
'😜',
|
||||
'🤨',
|
||||
'🧐',
|
||||
'🤓',
|
||||
'😎',
|
||||
'😞',
|
||||
'😔',
|
||||
'😭',
|
||||
'😤',
|
||||
'😡',
|
||||
'😱',
|
||||
'😰',
|
||||
'😓',
|
||||
'😬',
|
||||
'🙄',
|
||||
'😴',
|
||||
'😪',
|
||||
'🤮',
|
||||
'😷',
|
||||
'💩',
|
||||
'👻',
|
||||
'💀',
|
||||
'🤝',
|
||||
'👎',
|
||||
'👍',
|
||||
'🙏'
|
||||
],
|
||||
content:
|
||||
'<ul class="do-meditor-face">' +
|
||||
'<li class="item" :repeat="arr" ><img :attr-src="ME.path + \'/addon/face/\' + el + \'.gif\'" :click="$insert(this.src)" /></li>' +
|
||||
'</ul>',
|
||||
$insert: function(src) {
|
||||
ME.insert(vm.$editor, '![](' + src + ')', false)
|
||||
layer.close(layid)
|
||||
offset: [
|
||||
offset.top + 40 - that.doc.scrollTop(),
|
||||
'auto',
|
||||
'auto',
|
||||
offset.left - that.doc.scrollLeft()
|
||||
],
|
||||
shift: {
|
||||
top: offset.top - that.doc.scrollTop(),
|
||||
left: offset.left - that.doc.scrollLeft()
|
||||
},
|
||||
content: `
|
||||
<ul class="do-meditor-face">
|
||||
<li class="item" :repeat="arr">
|
||||
<span :html="el" :click="insert(el)"></span>
|
||||
</li>
|
||||
</ul>`,
|
||||
insert: function(val) {
|
||||
that.insert(vm.$refs.editor, val, false)
|
||||
this.close()
|
||||
}
|
||||
})
|
||||
},
|
||||
table: function(elem, vm) {
|
||||
var offset = Anot(elem).offset()
|
||||
let that = this
|
||||
let offset = Anot(elem).offset()
|
||||
|
||||
layer.open({
|
||||
type: 7,
|
||||
title: '0行 x 0列',
|
||||
fixed: true,
|
||||
shadeClose: true,
|
||||
maskClose: true,
|
||||
offset: [
|
||||
offset.top + 37 - ME.doc.scrollTop(),
|
||||
offset.top + 40 - that.doc.scrollTop(),
|
||||
'auto',
|
||||
'auto',
|
||||
offset.left - ME.doc.scrollLeft()
|
||||
offset.left - that.doc.scrollLeft()
|
||||
],
|
||||
shift: {
|
||||
top: offset.top - that.doc.scrollTop(),
|
||||
left: offset.left - that.doc.scrollLeft()
|
||||
},
|
||||
matrix: objArr(10).map(function() {
|
||||
return objArr(10)
|
||||
}),
|
||||
content:
|
||||
'<ul class="do-meditor-table">' +
|
||||
'<li :repeat="matrix"><span :repeat-o="el" :class="{active: o.v}" :data="{x: $index, y: $outer.$index}"></span></li>' +
|
||||
'</ul>',
|
||||
success: function(id) {
|
||||
var tb = document.querySelector('.do-meditor-table'),
|
||||
_this = Anot.vmodels[id],
|
||||
lastx,
|
||||
lasty
|
||||
Anot(tb).bind('mousemove', function(ev) {
|
||||
content: `
|
||||
<ul class="do-meditor-table" ref="table">
|
||||
<li :repeat="matrix">
|
||||
<span
|
||||
:repeat-o="el"
|
||||
:class="{active: o.v}"
|
||||
:data="{x: $index, y: $outer.$index}"></span>
|
||||
</li>
|
||||
</ul>`,
|
||||
success: function() {
|
||||
let tb = this.$refs.table
|
||||
let lastx, lasty
|
||||
|
||||
Anot(tb).bind('mousemove', ev => {
|
||||
if (ev.target.nodeName === 'SPAN') {
|
||||
var x = ev.target.dataset.x - 0,
|
||||
y = ev.target.dataset.y - 0
|
||||
let x = ev.target.dataset.x - 0
|
||||
let y = ev.target.dataset.y - 0
|
||||
if (x === lastx && y === lasty) {
|
||||
return
|
||||
}
|
||||
lastx = x
|
||||
lasty = y
|
||||
_this.title = y + 1 + '行 x ' + (x + 1) + '列'
|
||||
for (var i = 0; i <= 9; i++) {
|
||||
for (var j = 0; j <= 9; j++) {
|
||||
_this.matrix[i][j].v = i <= y && j <= x ? 1 : 0
|
||||
this.title = y + 1 + '行 x ' + (x + 1) + '列'
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
for (let j = 0; j <= 9; j++) {
|
||||
this.matrix[i][j].v = i <= y && j <= x ? 1 : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Anot(tb).bind('mouseleave', function(ev) {
|
||||
Anot(tb).bind('mouseleave', ev => {
|
||||
lastx = -1
|
||||
lasty = -1
|
||||
_this.title = '0行 x 0列'
|
||||
for (var i = 0; i <= 9; i++) {
|
||||
for (var j = 0; j <= 9; j++) {
|
||||
_this.matrix[i][j].v = 0
|
||||
this.title = '0行 x 0列'
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
for (let j = 0; j <= 9; j++) {
|
||||
this.matrix[i][j].v = 0
|
||||
}
|
||||
}
|
||||
})
|
||||
Anot(tb).bind('click', function(ev) {
|
||||
Anot(tb).bind('click', ev => {
|
||||
if (ev.target.nodeName === 'SPAN') {
|
||||
var x = ev.target.dataset.x - 0 + 1,
|
||||
y = ev.target.dataset.y - 0 + 1
|
||||
let x = ev.target.dataset.x - 0 + 1
|
||||
let y = ev.target.dataset.y - 0 + 1
|
||||
|
||||
var val =
|
||||
'\n\n' +
|
||||
ME.repeat('| 表头 ', x) +
|
||||
'|\n' +
|
||||
ME.repeat('| -- ', x) +
|
||||
'|\n' +
|
||||
ME.repeat(ME.repeat('| ', x) + '|\n', y)
|
||||
ME.insert(vm.$editor, val, false)
|
||||
layer.close(id)
|
||||
let thead = `\n\n${that.repeat('| 表头 ', x)}|\n`
|
||||
let pipe = `${that.repeat('| -- ', x)}|\n`
|
||||
let tbody = that.repeat(that.repeat('| ', x) + '|\n', y)
|
||||
|
||||
that.insert(vm.$refs.editor, thead + pipe + tbody, false)
|
||||
this.close()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
image: function(elem, vm) {
|
||||
var offset = Anot(elem).offset(),
|
||||
wrap = ME.selection(vm.$editor) || '',
|
||||
layid = layer.open({
|
||||
let that = this
|
||||
let offset = Anot(elem).offset()
|
||||
let wrap = this.selection(vm.$refs.editor) || ''
|
||||
|
||||
layer.open({
|
||||
type: 7,
|
||||
menubar: false,
|
||||
shadeClose: true,
|
||||
maskClose: true,
|
||||
fixed: true,
|
||||
img: '',
|
||||
imgAlt: wrap,
|
||||
$confirm: function() {
|
||||
var lvm = Anot.vmodels[layid]
|
||||
if (!lvm.img || !lvm.imgAlt) {
|
||||
return layer.alert('图片描述和图片地址不能为空')
|
||||
insert: function() {
|
||||
if (!this.img || !this.imgAlt) {
|
||||
return layer.toast('链接文字和地址不能为空', 'error')
|
||||
}
|
||||
var val = '![' + lvm.imgAlt + '](' + lvm.img + ')'
|
||||
let val = `![${this.imgAlt}](${this.img})`
|
||||
|
||||
ME.insert(vm.$editor, val, false)
|
||||
layer.close(layid)
|
||||
that.insert(vm.$refs.editor, val, false)
|
||||
this.close()
|
||||
},
|
||||
offset: [
|
||||
offset.top + 37 - ME.doc.scrollTop(),
|
||||
offset.top + 40 - that.doc.scrollTop(),
|
||||
'auto',
|
||||
'auto',
|
||||
offset.left - ME.doc.scrollLeft()
|
||||
offset.left - that.doc.scrollLeft()
|
||||
],
|
||||
content:
|
||||
'<div class="do-meditor-common do-meditor-font">' +
|
||||
'<section class="input"><span class="label">图片描述</span>' +
|
||||
'<input class="txt" :duplex="imgAlt" />' +
|
||||
'</section>' +
|
||||
'<section class="input"><span class="label">图片地址</span>' +
|
||||
'<input class="txt" :duplex="img"/>' +
|
||||
'</section>' +
|
||||
'<section>' +
|
||||
'<a href="javascript:;" class="submit" :click="$confirm">确定</a>' +
|
||||
'</section>' +
|
||||
'</div>'
|
||||
shift: {
|
||||
top: offset.top - that.doc.scrollTop(),
|
||||
left: offset.left - that.doc.scrollLeft()
|
||||
},
|
||||
content: `
|
||||
<div class="do-meditor-common do-meditor__font">
|
||||
<section class="input">
|
||||
<input class="txt" :duplex="imgAlt" placeholder="图片描述"/>
|
||||
</section>
|
||||
<section class="input">
|
||||
<input class="txt" :duplex="img" placeholder="图片地址"/>
|
||||
</section>
|
||||
<section>
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="do-meditor__button submit"
|
||||
:click="insert">确定</a>
|
||||
</section>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
},
|
||||
file: function(elem, vm) {
|
||||
this.link(elem, vm, false)
|
||||
attach: function(elem, vm) {
|
||||
this.addon.link.call(this, elem, vm, false)
|
||||
},
|
||||
inlinecode: function(elem, vm) {
|
||||
var wrap = ME.selection(vm.$editor) || '在此输入文本',
|
||||
wraped = trim(wrap, '`')
|
||||
let wrap = this.selection(vm.$refs.editor) || '在此输入文本'
|
||||
let wraped = trim(wrap, '`')
|
||||
|
||||
wrap = wrap === wraped ? '`' + wrap + '`' : wraped
|
||||
ME.insert(vm.$editor, wrap, true)
|
||||
this.insert(vm.$refs.editor, wrap, true)
|
||||
},
|
||||
blockcode: function(elem, vm) {
|
||||
var layid = layer.open({
|
||||
let that = this
|
||||
layer.open({
|
||||
type: 7,
|
||||
title: '添加代码块',
|
||||
$lang: [
|
||||
|
@ -350,11 +431,11 @@ const addon = {
|
|||
var val =
|
||||
'\n```' + lvm.lang + '\n' + (lvm.code || '//在此输入代码') + '\n```\n'
|
||||
|
||||
ME.insert(vm.$editor, val, false)
|
||||
that.insert(vm.$refs.editor, val, false)
|
||||
layer.close(layid)
|
||||
},
|
||||
content:
|
||||
'<div class="do-meditor-codeblock do-meditor-font">' +
|
||||
'<div class="do-meditor-codeblock do-meditor__font">' +
|
||||
'<section class="do-fn-cl"><span class="label">语言类型</span>' +
|
||||
'<select :duplex="lang">' +
|
||||
'<option :repeat="$lang" :attr-value="el.id">{{el.name || el.id}}</option>' +
|
||||
|
@ -384,9 +465,11 @@ const addon = {
|
|||
layer.open({
|
||||
type: 7,
|
||||
title: '关于编辑器',
|
||||
offset: [offset.top + 37 - ME.doc.scrollTop()],
|
||||
maskClose: true,
|
||||
offset: [offset.top + 37 - this.doc.scrollTop()],
|
||||
shift: { top: offset.top - this.doc.scrollTop() },
|
||||
content:
|
||||
'<div class="do-meditor-about do-meditor-font">' +
|
||||
'<div class="do-meditor-about do-meditor__font">' +
|
||||
'<pre>' +
|
||||
' __ __ _____ _ _ _\n' +
|
||||
'| \\/ | ____|__| (_) |_ ___ _ __\n' +
|
||||
|
@ -394,7 +477,7 @@ const addon = {
|
|||
'| | | | |__| (_| | | || (_) | |\n' +
|
||||
'|_| |_|_____\\__,_|_|\\__\\___/|_| ' +
|
||||
'v' +
|
||||
ME.version +
|
||||
this.version +
|
||||
'</pre>' +
|
||||
'<p>开源在线Markdown编辑器</p>' +
|
||||
'<p><a target="_blank" href="https://doui.cc/product/meditor">https://doui.cc/product/meditor</a></p>' +
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export default 1234
|
|
@ -17,13 +17,14 @@ marked.setOptions({
|
|||
return Prism.highlight(code, Prism.languages[lang])
|
||||
}
|
||||
})
|
||||
var editorVM = []
|
||||
let editorVM = []
|
||||
Anot.ui.meditor = '1.0.0'
|
||||
const log = console.log
|
||||
//存放编辑器公共静态资源
|
||||
window.ME = {
|
||||
version: Anot.ui.meditor,
|
||||
toolbar: {
|
||||
// 工具栏title
|
||||
toolbar: {
|
||||
pipe: '',
|
||||
h1: '标题',
|
||||
quote: '引用文本',
|
||||
|
@ -50,14 +51,14 @@ window.ME = {
|
|||
insert: function(dom, val, isSelect) {
|
||||
if (document.selection) {
|
||||
dom.focus()
|
||||
var range = document.selection.createRange()
|
||||
let range = document.selection.createRange()
|
||||
range.text = val
|
||||
dom.focus()
|
||||
range.moveStart('character', -1)
|
||||
} else if (dom.selectionStart || dom.selectionStart === 0) {
|
||||
var startPos = dom.selectionStart,
|
||||
endPos = dom.selectionEnd,
|
||||
scrollTop = dom.scrollTop
|
||||
let startPos = dom.selectionStart
|
||||
let endPos = dom.selectionEnd
|
||||
let scrollTop = dom.scrollTop
|
||||
|
||||
dom.value =
|
||||
dom.value.slice(0, startPos) +
|
||||
|
@ -82,15 +83,15 @@ window.ME = {
|
|||
if (document.selection) {
|
||||
return document.selection.createRange().text
|
||||
} else {
|
||||
var startPos = dom.selectionStart,
|
||||
endPos = dom.selectionEnd
|
||||
let startPos = dom.selectionStart
|
||||
let endPos = dom.selectionEnd
|
||||
|
||||
if (endPos) {
|
||||
//强制选择整行
|
||||
if (line) {
|
||||
startPos = dom.value.slice(0, startPos).lastIndexOf('\n')
|
||||
|
||||
var tmpEnd = dom.value.slice(endPos).indexOf('\n')
|
||||
let tmpEnd = dom.value.slice(endPos).indexOf('\n')
|
||||
tmpEnd = tmpEnd < 0 ? 0 : tmpEnd
|
||||
|
||||
startPos += 1 //把\n加上
|
||||
|
@ -169,27 +170,24 @@ var elems = {
|
|||
},
|
||||
hr: '\n\n___\n\n',
|
||||
a: function(str, attr, inner) {
|
||||
var href = attr.match(attrExp('href')),
|
||||
title = attr.match(attrExp('title')),
|
||||
tar = attr.match(attrExp('target'))
|
||||
let href = attr.match(attrExp('href'))
|
||||
let title = attr.match(attrExp('title'))
|
||||
let tar = attr.match(attrExp('target'))
|
||||
let attrs = ''
|
||||
|
||||
href = (href && href[1]) || ''
|
||||
title = (title && title[1]) || ''
|
||||
href = (href && href[1]) || null
|
||||
title = (title && title[1]) || null
|
||||
tar = (tar && tar[1]) || '_self'
|
||||
|
||||
href = href === 'javascript:void(0);' ? 'javascript:;' : href
|
||||
if (!href) {
|
||||
return inner || href
|
||||
}
|
||||
|
||||
return (
|
||||
'[' +
|
||||
(inner || href) +
|
||||
'](' +
|
||||
href +
|
||||
' "title=' +
|
||||
title +
|
||||
';target=' +
|
||||
tar +
|
||||
'")'
|
||||
)
|
||||
href = href.replace('viod(0)', '')
|
||||
attrs = `target=${tar}`
|
||||
attrs += title ? `;title=${title}` : ''
|
||||
|
||||
return `[${inner || href}](${href} "${attrs}")`
|
||||
},
|
||||
em: function(str, attr, inner) {
|
||||
return (inner && '_' + inner + '_') || ''
|
||||
|
@ -233,7 +231,12 @@ function html2md(str) {
|
|||
try {
|
||||
str = decodeURIComponent(str)
|
||||
} catch (err) {}
|
||||
|
||||
str = str.replace(/\t/g, ' ').replace(/<meta [^>]*>/, '')
|
||||
str = str.replace(
|
||||
/<(div|span|dl|dd|dt|table|tr|td|thead|tbody|i|em|strong|h[1-6]|ul|ol|li) [^>]*>/g,
|
||||
'<$1>'
|
||||
)
|
||||
|
||||
for (var i in elems) {
|
||||
var cb = elems[i],
|
||||
|
@ -313,7 +316,7 @@ var defaultToolbar = [
|
|||
'|',
|
||||
'table',
|
||||
'image',
|
||||
'file',
|
||||
'attach',
|
||||
'inlinecode',
|
||||
'blockcode',
|
||||
'|',
|
||||
|
@ -330,7 +333,7 @@ function tool(name) {
|
|||
return (
|
||||
'<span title="' +
|
||||
ME.toolbar[name] +
|
||||
'" class="icon-' +
|
||||
'" class="do-meditor__icon icon-' +
|
||||
name +
|
||||
'" ' +
|
||||
(name !== 'pipe' ? ':click="onToolClick(\'' + name + '\', $event)"' : '') +
|
||||
|
@ -340,35 +343,43 @@ function tool(name) {
|
|||
|
||||
Anot.component('meditor', {
|
||||
render: function() {
|
||||
var toolbar = (this.toolbar || defaultToolbar)
|
||||
.map(function(it) {
|
||||
return tool(it)
|
||||
})
|
||||
.join('')
|
||||
let toolbar = (this.toolbar || defaultToolbar).map(it => tool(it)).join('')
|
||||
|
||||
delete this.toolbar
|
||||
return (
|
||||
'<div class="do-meditor do-meditor-font" :visible="editorVisible"' +
|
||||
' :class="{fullscreen: fullscreen, preview: preview}">' +
|
||||
'<div class="tool-bar do-ui-font do-fn-noselect">{toolbar}</div>' +
|
||||
'<textarea ref="textarea" class="editor-body" spellcheck="false" :duplex="plainTxt" :attr="{disabled: disabled}" :on-paste="$paste($event)"></textarea>' +
|
||||
'<content class="md-preview do-marked-theme" :visible="preview" :html="htmlTxt"></content>' +
|
||||
'</div>'
|
||||
).replace(/\{toolbar\}/g, toolbar)
|
||||
|
||||
return `
|
||||
<div
|
||||
class="do-meditor do-meditor__font"
|
||||
:visible="editorVisible"
|
||||
:class="{fullscreen: fullscreen, preview: preview}">
|
||||
<div class="tool-bar do-fn-noselect">${toolbar}</div>
|
||||
<textarea
|
||||
ref="editor"
|
||||
class="editor-body"
|
||||
spellcheck="false"
|
||||
:attr="{disabled: disabled}"
|
||||
:duplex="plainTxt"
|
||||
:on-paste="onPaste($event)"></textarea>
|
||||
<content
|
||||
class="md-preview do-marked-theme"
|
||||
:visible="preview"
|
||||
:html="htmlTxt"></content>
|
||||
</div>
|
||||
`
|
||||
},
|
||||
|
||||
construct: function(base, opt, attr) {
|
||||
Anot.mix(base, opt, attr)
|
||||
if (base.$addons && Array.isArray(base.$addons)) {
|
||||
extraAddons = base.$addons.map(function(name) {
|
||||
return ME.path + '/addon/' + name
|
||||
})
|
||||
delete base.$addons
|
||||
construct: function(props, state) {
|
||||
// Anot.mix(base, opt, attr)
|
||||
// if (base.$addons && Array.isArray(base.$addons)) {
|
||||
// extraAddons = base.$addons.map(function(name) {
|
||||
// return ME.path + '/addon/' + name
|
||||
// })
|
||||
// delete base.$addons
|
||||
// }
|
||||
if (props.hasOwnProperty('$show')) {
|
||||
state.editorVisible = props.$show
|
||||
delete props.$show
|
||||
}
|
||||
if (base.hasOwnProperty('$show')) {
|
||||
base.editorVisible = base.$show
|
||||
delete base.$show
|
||||
}
|
||||
return base
|
||||
},
|
||||
componentWillMount: function(vm) {},
|
||||
componentDidMount: function(vm, elem) {
|
||||
|
@ -411,25 +422,32 @@ Anot.component('meditor', {
|
|||
},
|
||||
watch: {
|
||||
plainTxt: function(val) {
|
||||
this.$compile()
|
||||
this.compile()
|
||||
//只有开启实时预览,才会赋值给htmlTxt
|
||||
if (this.preview) {
|
||||
this.htmlTxt = this.$htmlTxt
|
||||
}
|
||||
this.$onUpdate(this.plainTxt, vm.$htmlTxt)
|
||||
if (typeof this.props.onUpdate === 'function') {
|
||||
this.props.onUpdate(this.plainTxt, this.$htmlTxt)
|
||||
}
|
||||
}
|
||||
},
|
||||
state: {
|
||||
disabled: false, //禁用编辑器
|
||||
fullscreen: false, //是否全屏
|
||||
preview: false, //是否显示预览
|
||||
$editor: null, //编辑器元素
|
||||
// $editor: null, //编辑器元素
|
||||
editorVisible: true,
|
||||
$htmlTxt: '', //临时储存html文本
|
||||
htmlTxt: '', //用于预览渲染
|
||||
plainTxt: '', //纯md文本
|
||||
$safelyCompile: true
|
||||
},
|
||||
props: {
|
||||
onSuccess: Anot.PropsTypes.isFunction(),
|
||||
onUpdate: Anot.PropsTypes.isFunction(),
|
||||
onFullscreen: Anot.PropsTypes.isFunction()
|
||||
},
|
||||
methods: {
|
||||
onToolClick: function(name, ev) {
|
||||
if (ME.addon[name]) {
|
||||
|
@ -438,24 +456,23 @@ Anot.component('meditor', {
|
|||
console.log('%c没有对应的插件%c[%s]', 'color:#f00;', '', name)
|
||||
}
|
||||
},
|
||||
$onSuccess: Anot.noop,
|
||||
$onUpdate: Anot.noop,
|
||||
$onFullscreen: Anot.noop,
|
||||
$paste: function(ev) {
|
||||
onPaste: function(ev) {
|
||||
ev.preventDefault()
|
||||
var txt = ev.clipboardData.getData('text/plain').trim(),
|
||||
html = ev.clipboardData.getData('text/html').trim()
|
||||
let txt = ev.clipboardData.getData('text/plain').trim()
|
||||
let html = ev.clipboardData.getData('text/html').trim()
|
||||
|
||||
html = html2md(html)
|
||||
|
||||
if (html) {
|
||||
ME.insert(this, html)
|
||||
ME.insert(ev.target, html)
|
||||
} else if (txt) {
|
||||
ME.insert(this, txt)
|
||||
ME.insert(ev.target, txt)
|
||||
}
|
||||
this.plainTxt = this.value
|
||||
log(ev.target.value)
|
||||
this.plainTxt = this.$refs.editor.value
|
||||
},
|
||||
compile: function() {
|
||||
log(this)
|
||||
var txt = this.plainTxt.trim()
|
||||
|
||||
if (this.$safelyCompile) {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,15 +7,13 @@
|
|||
|
||||
import './highlight.scss'
|
||||
|
||||
var _self = window
|
||||
|
||||
var Prism = (function() {
|
||||
// Private helper vars
|
||||
var lang = /\blang(?:uage)?-(\w+)\b/i
|
||||
var uniqueId = 0
|
||||
|
||||
var _ = (_self.Prism = {
|
||||
manual: _self.Prism && _self.Prism.manual,
|
||||
var _ = (window.Prism = {
|
||||
manual: window.Prism && window.Prism.manual,
|
||||
util: {
|
||||
encode: function(tokens) {
|
||||
if (tokens instanceof Token) {
|
||||
|
@ -221,7 +219,7 @@ var Prism = (function() {
|
|||
|
||||
_.hooks.run('before-highlight', env)
|
||||
|
||||
if (async && _self.Worker) {
|
||||
if (async && window.Worker) {
|
||||
var worker = new Worker(_.filename)
|
||||
|
||||
worker.onmessage = function(evt) {
|
||||
|
@ -487,13 +485,13 @@ var Prism = (function() {
|
|||
)
|
||||
}
|
||||
|
||||
if (!_self.document) {
|
||||
if (!_self.addEventListener) {
|
||||
if (!window.document) {
|
||||
if (!window.addEventListener) {
|
||||
// in Node.js
|
||||
return _self.Prism
|
||||
return window.Prism
|
||||
}
|
||||
// In worker
|
||||
_self.addEventListener(
|
||||
window.addEventListener(
|
||||
'message',
|
||||
function(evt) {
|
||||
var message = JSON.parse(evt.data),
|
||||
|
@ -501,15 +499,15 @@ var Prism = (function() {
|
|||
code = message.code,
|
||||
immediateClose = message.immediateClose
|
||||
|
||||
_self.postMessage(_.highlight(code, _.languages[lang], lang))
|
||||
window.postMessage(_.highlight(code, _.languages[lang], lang))
|
||||
if (immediateClose) {
|
||||
_self.close()
|
||||
window.close()
|
||||
}
|
||||
},
|
||||
false
|
||||
)
|
||||
|
||||
return _self.Prism
|
||||
return window.Prism
|
||||
}
|
||||
|
||||
//Get current script and highlight
|
||||
|
@ -537,7 +535,7 @@ var Prism = (function() {
|
|||
}
|
||||
}
|
||||
|
||||
return _self.Prism
|
||||
return window.Prism
|
||||
})()
|
||||
|
||||
Prism.languages.markup = {
|
||||
|
|
|
@ -232,7 +232,6 @@ Prism.languages.insertBefore('cpp', 'keyword', {
|
|||
})
|
||||
|
||||
/*-----------------------coffeescript-----------------------*/
|
||||
|
||||
;(function(Prism) {
|
||||
// Ignore comments starting with { to privilege string interpolation highlighting
|
||||
var comment = /#(?!\{).+/,
|
||||
|
@ -322,7 +321,6 @@ Prism.languages.insertBefore('cpp', 'keyword', {
|
|||
})(Prism)
|
||||
|
||||
/*---------------------------ruby---------------------------*/
|
||||
|
||||
;(function(Prism) {
|
||||
Prism.languages.ruby = Prism.languages.extend('clike', {
|
||||
comment: [
|
||||
|
@ -650,7 +648,6 @@ Prism.languages.haskell = {
|
|||
}
|
||||
|
||||
/*---------------------------jade---------------------------*/
|
||||
|
||||
;(function(Prism) {
|
||||
Prism.languages.jade = {
|
||||
comment: {
|
||||
|
@ -862,7 +859,6 @@ Prism.languages.json = {
|
|||
Prism.languages.jsonp = Prism.languages.json
|
||||
|
||||
/*--------------------------kotlin----------------------------*/
|
||||
|
||||
;(function(Prism) {
|
||||
Prism.languages.kotlin = Prism.languages.extend('clike', {
|
||||
keyword: {
|
||||
|
@ -1525,7 +1521,6 @@ Prism.languages.rust = {
|
|||
}
|
||||
|
||||
/*------------------------------------------------------------*/
|
||||
|
||||
;(function(Prism) {
|
||||
Prism.languages.sass = Prism.languages.extend('css', {
|
||||
// Sass comments don't need to be closed, only indented
|
||||
|
@ -1676,7 +1671,6 @@ Prism.languages.scss['atrule'].inside.rest = Prism.util.clone(
|
|||
)
|
||||
|
||||
/*-----------------------------smarty-------------------------*/
|
||||
|
||||
;(function(Prism) {
|
||||
var smarty_pattern = /\{\*[\s\S]+?\*\}|\{[\s\S]+?\}/g
|
||||
var smarty_litteral_start = '{literal}'
|
||||
|
|
Reference in New Issue