This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0

修复框架在循环中动态增加VM导致作用域混乱的bug;优化layer组件的tips和loading;完成meditor的移植

old
宇天 2018-05-20 05:32:51 +08:00
parent 99b95e67e1
commit 869dc40ab3
47 changed files with 319 additions and 239 deletions

View File

@ -22,8 +22,9 @@ const jsOpt = {
plugins: [
'transform-es2015-modules-amd',
'transform-decorators-legacy',
'transform-class-properties',
'transform-object-rest-spread'
'transform-object-rest-spread',
['transform-es2015-classes', { loose: true }],
['transform-es2015-for-of', { loose: true }]
]
}
const cssOpt = {
@ -78,7 +79,6 @@ const compileHtm = (entry, output) => {
/*===== ===*/
/*=======================================================*/
const fontFiles = fs.ls('./src/font/', true)
const jsFiles = fs.ls('./src/js/', true)
const cssFiles = fs.ls('./src/css/', true)

View File

@ -65,7 +65,6 @@ const compileHtm = (entry, output) => {
/*===== ===*/
/*=======================================================*/
const fontFiles = fs.ls('./src/font/', true)
const jsFiles = fs.ls('./src/js/', true)
const cssFiles = fs.ls('./src/css/', true)
@ -74,11 +73,6 @@ if (fs.isdir(buildDir)) {
log(chalk.cyan('清除旧目录 dist/'))
}
// 字体文件直接复制
fontFiles.forEach(file => {
fs.cp('./src/font/' + file, './dist/font/' + file)
})
// css目录
cssFiles.forEach(file => {
if (/\.scss$/.test(file)) {

View File

@ -22,8 +22,9 @@ const jsOpt = {
plugins: [
'transform-es2015-modules-amd',
'transform-decorators-legacy',
'transform-class-properties',
'transform-object-rest-spread'
'transform-object-rest-spread',
['transform-es2015-classes', { loose: true }],
['transform-es2015-for-of', { loose: true }]
]
}
const cssOpt = {
@ -37,10 +38,12 @@ const compileJs = (entry, output) => {
}
let t1 = Date.now()
let tmpOpt = jsOpt
if (/anot/.test(entry)) {
tmpOpt = Object.assign({}, jsOpt, { plugins: [] })
let code = ''
if (!/anot/.test(entry)) {
code = babel.transformFileSync(entry, jsOpt).code
} else {
code = fs.cat(entry).toString()
}
let { code } = babel.transformFileSync(entry, tmpOpt)
code = uglify.minify(code).code.replace(/\.scss/g, '.css')
log(
'编译JS: %s, 耗时 %s ms',
@ -79,7 +82,6 @@ const compileHtm = (entry, output) => {
/*===== ===*/
/*=======================================================*/
const fontFiles = fs.ls('./src/font/', true)
const jsFiles = fs.ls('./src/js/', true)
const cssFiles = fs.ls('./src/css/', true)
@ -88,11 +90,6 @@ if (fs.isdir(buildDir)) {
log(chalk.cyan('清除旧目录 dist/'))
}
// 字体文件直接复制
fontFiles.forEach(file => {
fs.cp('./src/font/' + file, './dist/font/' + file)
})
// css目录
cssFiles.forEach(file => {
if (/\.scss$/.test(file)) {

View File

@ -12,21 +12,25 @@
"type": "git",
"url": "git+https://github.com/yutent/doui.git"
},
"keywords": ["doui", "Anot"],
"keywords": [
"doui",
"Anot"
],
"author": "yutent",
"license": "MIT",
"devDependencies": {
"autoprefixer": "^7.2.6",
"babel-core": "^6.26.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-core": "^6.26.3",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-es2015-classes": "^6.24.1",
"babel-plugin-transform-es2015-for-of": "^6.23.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"chalk": "^2.3.2",
"chalk": "^2.4.1",
"chokidar": "^1.7.0",
"iofs": "^1.0.3",
"node-sass": "^4.8.2",
"postcss": "^6.0.19",
"node-sass": "^4.9.0",
"postcss": "^6.0.22",
"uglify-es": "^3.3.9"
},
"dependencies": {}

View File

@ -234,6 +234,7 @@
vm.$id = $id
VMODELS[$id] = vm
Anot.nextTick(function() {
var $elem = document.querySelector('[anot=' + vm.$id + ']')
if ($elem) {
if ($elem === DOC.body) {
@ -245,9 +246,14 @@
break
}
}
scanTag($elem.parentNode, $parent ? [VMODELS[$parent.anotctrl]] : [])
scanTag(
$elem.parentNode,
$parent ? [VMODELS[$parent.anotctrl]] : []
)
}
}
})
return vm
} else {
this[0] = this.element = source
@ -2172,6 +2178,7 @@
injectDependency(array, binding)
}
})
binding.getter = parseExpr(binding.expr, binding.vmodels, binding)
binding.observers.forEach(function(a) {
a.v.$watch(a.p, binding)
@ -3038,8 +3045,8 @@
}
function addAssign(vars, vmodel, name, binding) {
var ret = [],
prefix = ' = ' + name + '.'
var ret = []
var prefix = ' = ' + name + '.'
for (var i = vars.length, prop; (prop = vars[--i]); ) {
var arr = prop.split('.')
var first = arr[0]
@ -3137,7 +3144,7 @@
/* jshint ignore:start */
var fn2 = scpCompile(
names.concat(
"'use strict';" + 'return function(vvv){' + expr + ' = vvv\n}\n'
'"use strict";\n return function(vvv){' + expr + ' = vvv\n}\n'
)
)
/* jshint ignore:end */
@ -3178,11 +3185,23 @@
})
expr = '\nreturn ' + expr + ';' //IE全家 Function("return ")出错需要Function("return ;")
}
// log('')
// log(
// names
// .concat(
// "'use strict';\ntry{\nvar " +
// assigns.join(',\n') +
// expr +
// '\n}catch(e){console.log(e)}'
// )
// .join('')
// )
// log('')
/* jshint ignore:start */
getter = scpCompile(
names.concat(
"'use strict';\ntry{\nvar " +
assigns.join(',\n') +
"'use strict';\ntry{\n var " +
assigns.join(',\n ') +
expr +
'\n}catch(e){console.log(e)}'
)
@ -3290,7 +3309,7 @@
Anot.injectBinding(binding)
if (binding.getter && binding.element.nodeType === 1) {
//移除数据绑定,防止被二次解析
//chrome使用removeAttributeNode移除不存在的特性节点时会报错 https://github.com/RubyLouvre/Anot/issues/99
//chrome使用removeAttributeNode移除不存在的特性节点时会报错
binding.element.removeAttribute(binding.name)
}
}
@ -3505,8 +3524,8 @@
}
function scanTag(elem, vmodels, node) {
//扫描顺序 skip(0) --> anot(1) --> :if(10) --> :repeat(100)
//--> :if-loop(110) --> :attr(970) ...--> :each(1400)-->:with(1500)--〉:duplex(2000)垫后
//扫描顺序 skip(0) --> anot(1) --> :if(10) --> :repeat(90)
//--> :if-loop(110) --> :attr(970) ...--> :duplex(2000)垫后
var skip = elem.getAttribute('skip')
node = elem.getAttributeNode('anot')
var vm = vmodels.concat()
@ -3557,15 +3576,16 @@
newVmodel.props[k] = props[k]
delete props[k]
} else {
Anot.error(
console.error(
new TypeError(
'props.' +
k +
' needs [' +
newVmodel.props[k].checkType +
'], but [' +
newVmodel.props[k].result +
'] given.',
TypeError
'] given.'
)
)
}
}
@ -5463,11 +5483,6 @@
var kill = elem.previousSibling
var start = binding.start
/*log(kill === start, kill)
while(kill !== start && kill.nodeName !== '#comment'){
parent.removeChild(kill)
kill = elem.previousSibling
}*/
if (clear) {
while (kill !== start) {
parent.removeChild(kill)
@ -5509,9 +5524,6 @@
)
decorateProxy(proxy, binding, xtype)
} else {
// if (xtype === "array") {
// proxy[param] = value[i]
// }
fragments.push({})
retain[keyOrId] = true
}
@ -5528,7 +5540,6 @@
if (xtype === 'array') {
proxy.$first = i === 0
proxy.$last = i === length - 1
// proxy[param] = value[i]
} else {
proxy.$val = toJson(value[keyOrId]) //这里是处理vm.object = newObject的情况
}

View File

@ -33,6 +33,7 @@ let defconf = {
offset: [], // 弹窗出来后的坐标, 为数组,可有4个值,依次是 上右下左
btns: ['确定', '取消'] // 弹窗的2个按钮的文字
}
const $doc = Anot(document)
const uuid = function() {
return 'layer-' + lid++
}
@ -214,6 +215,9 @@ class __layer__ {
outerBox.classList.add('do-layer')
if (state.mask) {
outerBox.classList.add('mask')
if (state.container && state.container !== document.body) {
outerBox.classList.add('inner')
}
}
if (state.maskColor) {
outerBox.style.background = state.maskColor
@ -383,7 +387,6 @@ class __layer__ {
style.color = state.color
style.opacity = 1
let $container = Anot(container)
let $doc = Anot(document)
let $arrow = $container[0].querySelector('.arrow')
let cw = $container.innerWidth()
let ch = $container.innerHeight()
@ -564,23 +567,26 @@ const _layer = {
return _layer.open(opt)
},
loading: function(style, time, cb) {
loading: function(style, container, cb) {
style = style >>> 0
style = style < 1 ? 1 : style > 5 ? 5 : style
if (typeof time === 'function') {
cb = time
time = 0
if (typeof container === 'function') {
cb = container
container = null
} else {
time = time >>> 0
if (!(container instanceof HTMLElement)) {
container = null
}
if (typeof cb !== 'function') {
cb = Anot.noop
}
}
return _layer.open({
container,
type: 6,
load: style,
yes: cb,
timeout: time,
menubar: false,
background: 'none',
shift: 'ct',
@ -660,7 +666,7 @@ const _layer = {
}
Anot.directive('layer', {
priority: 1400,
priority: 8090,
init: function(binding) {
// 去掉:layer属性,避免二次扫描
binding.element.removeAttribute(binding.name)
@ -671,13 +677,15 @@ Anot.directive('layer', {
},
update: function(val) {
if (!val) {
console.error(this)
return console.error(
`SyntaxError: Unexpected [${this.name}=${this.expr}]`
)
}
if (!this.param) {
let state = Object.assign({ type: 7, wrap: true }, this.element.dataset)
if (!this.param) {
let init = { $id: 'layerwrap-' + val, state, props: {} }
if (state.hasOwnProperty('area')) {
@ -709,7 +717,72 @@ Anot.directive('layer', {
}
layerDom[tmp.init.$id] = tmp.create()
} else if (this.param === 'tips') {
_layer.tips(val, this.element)
let tips = document.createElement('div')
let cont = document.createElement('span')
let arrow = document.createElement('i')
tips.className = 'do-layer__tips'
cont.className = 'layer-content'
arrow.className = 'arrow'
cont.textContent = val
tips.appendChild(cont)
tips.appendChild(arrow)
this.element.appendChild(tips)
if (state.color) {
style.color = state.color
}
if (state.color) {
style.background = state.background
}
let style = {}
let css = getComputedStyle(tips)
let $container = Anot(this.element)
let cw = $container.innerWidth()
let ch = $container.innerHeight()
let ol = $container.offset().left - $doc.scrollLeft()
let ot = $container.offset().top - $doc.scrollTop()
let layw = parseInt(css.width)
let layh = parseInt(css.height)
let arrowOffset = ['top']
Anot(tips).css(style)
$container.bind('mouseenter', ev => {
let tmpStyle = { visibility: 'visible' }
ol = $container.offset().left - $doc.scrollLeft()
ot = $container.offset().top - $doc.scrollTop()
if (ot + 18 < layh) {
arrowOffset[0] = 'bottom'
arrow.style.borderBottomColor = state.background
tmpStyle.top = ot + ch + 8
} else {
arrow.style.borderTopColor = state.background
tmpStyle.top = ot - layh - 8
}
if (ol + cw * 0.7 + layw > window.innerWidth) {
tmpStyle.left = ol + cw * 0.3 - layw
arrowOffset[1] = 'left'
} else {
tmpStyle.left = ol + cw * 0.7
}
arrow.classList.add('offset-' + arrowOffset.join('-'))
Anot(tips).css(tmpStyle)
})
$container.bind('mouseleave', () => {
setTimeout(() => {
arrow.classList.remove('offset-' + arrowOffset.join('-'))
arrowOffset = ['top']
arrow.style.borderBottomColor = ''
arrow.style.borderTopColor = ''
tips.style.visibility = 'hidden'
}, 100)
})
// _layer.tips(val, this.element)
}
}
})

View File

@ -75,9 +75,8 @@
/* tips类弹层(type 5) */
&.type-5 {visibility:hidden;position:fixed;z-index:65534;min-width:75px;max-width:600px;line-height:1.5;color:#fff;background:rgba(0,0,0,.5);opacity:0;box-shadow:none;-webkit-transition:opacity .3s ease-in-out;-moz-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;
&.type-5 {visibility:hidden;position:fixed;z-index:65534;min-width:75px;max-width:600px;padding:10px;line-height:1.5;color:#fff;background:rgba(0,0,0,.5);box-shadow:none;
// &.active {visibility:visible;opacity:1;}
i.arrow {position:absolute;width:0;height:0;border:6px solid transparent;content: ""}
i.offset-top {left:5px;bottom:-14px;border-top:8px solid rgba(0,0,0,.5);}
i.offset-bottom {left:5px;top:-14px;border-bottom:8px solid rgba(0,0,0,.5);}
@ -189,12 +188,23 @@
&.mask {position:fixed;z-index:65534;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,.3);
&.shift {transition: all .5s ease-out;}
&.inner {position:absolute;}
}
&:active {z-index:65536;}
}
/* 指令式的tips */
.do-layer__tips {visibility:hidden;position:fixed;z-index:65534;min-width:75px;max-width:600px;padding:10px;line-height:1.5;border-radius:3px;font-size:14px;color:#fff;background:rgba(0,0,0,.5);
i.arrow {position:absolute;width:0;height:0;border:6px solid transparent;content: ""}
i.offset-top {left:5px;bottom:-14px;border-top:8px solid rgba(0,0,0,.5);}
i.offset-bottom {left:5px;top:-14px;border-bottom:8px solid rgba(0,0,0,.5);}
i.offset-top-left {right:5px;bottom:-14px;border-top:8px solid rgba(0,0,0,.5);}
i.offset-bottom-left {right:5px;top:-14px;border-bottom:8px solid rgba(0,0,0,.5);}
.layer-content {min-height:20px;margin:0;padding:0}
}

View File

@ -11,6 +11,10 @@ import 'layer/index'
import './attach.scss'
const $doc = Anot(document)
const LANG = {
image: ['远程图片', '图片管理', '图片描述', '图片地址'],
file: ['远程附件', '附件管理', '附件描述', '附件地址']
}
class Uploader {
constructor(url) {
@ -64,84 +68,6 @@ class Uploader {
}
}
var $init = function(vm) {
vm.$editor.addEventListener('paste', function(ev) {
var txt = ev.clipboardData.getData('text/plain').trim(),
html = ev.clipboardData.getData('text/html').trim()
//文本类型直接默认处理
if (txt || html) {
return
}
if (ev.clipboardData.items) {
var items = ev.clipboardData.items,
len = items.length,
blob = null
for (var i = 0, it; (it = items[i++]); ) {
if (it.type.indexOf('image') > -1) {
blob = it.getAsFile()
}
}
if (blob !== null) {
layer.msg('截图处理中...')
// 压缩截图,避免文件过大
var reader = new FileReader()
reader.onload = function() {
var img = document.createElement('img'),
canvas = document.createElement('canvas')
img.onload = function() {
canvas.width = img.width
canvas.height = img.height
var ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(this, 0, 0, canvas.width, canvas.height)
if (canvas.toBlob) {
canvas.toBlob(
function(obj) {
uploadScreenshot(vm, obj)
},
'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
for (var i = 0; i < buf.length; i++) {
intArr[i] = buf.charCodeAt(i)
}
obj = new Blob([intArr], { type: 'image/jpeg' })
uploadScreenshot(vm, obj)
}
}
img.src = this.result
}
reader.readAsDataURL(blob)
}
}
ev.preventDefault()
})
}
let cache = {
//缓存附件列表
image: [],
file: []
}
const LANG = {
image: ['远程图片', '图片管理', '图片描述', '图片地址'],
file: ['远程附件', '附件管理', '附件描述', '附件地址']
}
const fixCont = function(vm, tool) {
let limit = false
if (vm.props.uploadSizeLimit) {
@ -177,7 +103,7 @@ const fixCont = function(vm, tool) {
<a
href="javascript:;"
class="do-meditor__button submit"
:click="$confirm">确定</a>
:click="confirm">确定</a>
</section>
</div>
<div class="local" :visible="tab === 2">
@ -208,12 +134,20 @@ const fixCont = function(vm, tool) {
</li>
</ul>
</div>
<ul class="manager" :visible="tab === 3">
<li class="item" :repeat="attachList" :click="insert(el)">
<div class="manager" :visible="tab === 3">
<ul class="list-box">
<li
class="item"
:repeat="attachList"
:layer-tips="el.name"
:click="insert(el)">
<span class="thumb" :html="el.thumb"></span>
<p class="name" :attr-title="el.name" :text="el.name"></p>
<p class="name" :text="el.name"></p>
</li>
</ul>
</div>
</dd>
</dl>`
}
@ -296,7 +230,10 @@ function uploadScreenshot(vm, blob) {
if (vm.props.beforeUpload) {
vm.props
.beforeUpload(attach, upload)
.then(upload => {
.then(next => {
if (!next) {
return Promise.reject('something wrong with beforeUpload')
}
return upload.then(res => {
return res.data
})
@ -315,37 +252,6 @@ function uploadScreenshot(vm, blob) {
}
}
function getAttach(vm, cb) {
var xhr = new XMLHttpRequest(),
url = vm.manageUrl || ME.manageUrl
if (/\?/.test(url)) {
url += '&type=' + openType
} else {
url += '?type=' + openType
}
url += '&t=' + Math.random()
xhr.open('GET', url, true)
xhr.onreadystatechange = function() {
if (
this.readyState === 4 &&
this.status === 200 &&
this.responseText !== ''
) {
var res = this.responseText
try {
res = JSON.parse(res)
} catch (err) {}
cb(res)
} else {
if (this.status !== 200 && this.responseText)
console.error(this.responseText)
}
}
xhr.send()
}
function showDialog(elem, vm, tool) {
let offset = Anot(elem).offset()
@ -353,7 +259,10 @@ function showDialog(elem, vm, tool) {
type: 7,
menubar: false,
fixed: true,
offset: [offset.top + 37 - $doc.scrollTop()],
offset: [offset.top + 40 - $doc.scrollTop()],
shift: {
top: offset.top - $doc.scrollTop()
},
tab: 2,
attach: '',
attachAlt: '',
@ -415,17 +324,90 @@ function showDialog(elem, vm, tool) {
vm.insert(val)
this.close()
},
content: fixCont(vm, tool)
content: fixCont(vm, tool),
success() {
this.switchTab(3)
}
})
}
const addon = {
const plugin = {
__init__(ME) {
Object.assign(ME.vm.addon, {
attach(elem) {
showDialog(elem, this, 'file')
},
image(elem) {
showDialog(elem, this, 'image')
}
})
ME.vm.$refs.editor.addEventListener('paste', function(ev) {
ev.preventDefault()
let txt = ev.clipboardData.getData('text/plain')
//文本类型直接默认处理
if (txt) {
return
}
if (ev.clipboardData.items) {
let items = ev.clipboardData.items
let len = items.length
let blob = null
for (let it of items) {
if (it.type.indexOf('image') > -1) {
blob = it.getAsFile()
}
}
if (blob !== null) {
layer.toast('截图处理中...')
// 压缩截图,避免文件过大
let reader = new FileReader()
reader.onload = function() {
let img = document.createElement('img')
let canvas = document.createElement('canvas')
img.onload = function() {
canvas.width = img.width
canvas.height = img.height
let ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(this, 0, 0, canvas.width, canvas.height)
// 目前 IE和Safari的toBlob方法还不支持图片质量的设定
if (canvas.toBlob && (window.chrome || window.sidebar)) {
canvas.toBlob(
function(obj) {
uploadScreenshot(ME.vm, obj)
},
'image/jpeg',
0.8
)
} else {
let base64 = canvas.toDataURL('image/jpeg', 0.8)
let buf = atob(base64.split(',')[1])
let intArr = new Uint8Array(buf.length)
let obj = null
for (let i = 0; i < buf.length; i++) {
intArr[i] = buf.charCodeAt(i)
}
obj = new Blob([intArr], { type: 'image/jpeg' })
uploadScreenshot(ME.vm, obj)
}
}
img.src = this.result
}
reader.readAsDataURL(blob)
}
}
})
}
}
export default addon
export default plugin

View File

@ -8,7 +8,14 @@
@import 'var.scss';
.do-meditor-attach {width:630px;height:300px;cursor:default;color:nth($cgr, 1);
dt.close {position:absolute;z-index:65539;top:-8px;right:-8px;width:40px;height:40px;line-height:40px;font-size:20px;text-align:center;cursor:pointer;
::-webkit-scrollbar {width:5px;height:5px;background:nth($cp, 2);}
::-webkit-scrollbar:hover {background:nth($cp, 1);}
::-webkit-scrollbar-button {display:none;}
::-webkit-scrollbar-thumb {background:nth($cgr, 2);}
::-webkit-scrollbar-thumb:hover {background:nth($cgr, 1);}
dt.close {position:absolute;z-index:65539;top:-15px;right:-10px;width:30px;height:30px;line-height:30px;font-size:20px;text-align:center;cursor:pointer;
&:hover {color:nth($ct, 1);font-size:28px;}
}
@ -65,15 +72,19 @@
.red {color:#f30;}
}
.manager {overflow:hidden;overflow-y:auto;width:100%;height:255px;padding:10px;
.manager {overflow:hidden;overflow-y:auto;width:100%;height:300px;
.item {float:left;width:22%;height:130px;margin:10px 1.5%;padding:5px;
&:hover {background:#f7f7f7;}
.list-box {width:100%;column-count:4;column-gap: 5;}
.item {margin:0 0 10px;padding:5px;text-align:center;background:nth($cp, 2); break-inside: avoid;@include ts(background);
&:hover {background:nth($cp, 3)}
.thumb {display:block;width:100%;}
.name {overflow:hidden;height:30px;line-height:30px; text-align:center;}
img {width:100%;height:auto;}
em {line-height:1;font-size:50px;}
}
.thumb {display:block;width:100%;height:100px;}
.name {overflow:hidden;height:20px;line-height:30px; text-align:center;}
img {width:100%;height:100%;}
em {line-height:100px;font-size:50px;}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1 +0,0 @@
export default 1234

View File

@ -108,12 +108,13 @@ const ELEMS = {
strong: function(str, attr, inner) {
return (inner && '**' + inner + '**') || ''
},
code: function(str, attr, inner) {
return (inner && '`' + inner + '`') || ''
},
pre: function(str, attr, inner) {
return '\n\n```\n' + inner + '\n```\n'
},
code: function(str, attr, inner) {
return (inner && '`' + inner + '`') || ''
},
blockquote: function(str, attr, inner) {
return '> ' + inner.trim()
},
@ -154,16 +155,13 @@ function html2md(str) {
str = decodeURIComponent(str)
} catch (err) {}
str = str.replace(/\t/g, ' ').replace(/<meta [^>]*>/, '')
str = str
.replace(/\t/g, ' ')
.replace(/<meta [^>]*>/, '')
.replace(attrExp('class', 'g'), '')
.replace(attrExp('style', 'g'), '')
str = str
.replace(
/<(div|span|header|footer|nav|dl|dd|dt|table|tr|td|thead|tbody|i|em|b|strong|h[1-6]|ul|ol|li|p|pre) [^>]*>/g,
'<$1>'
)
.replace(/<svg [^>]*>.*?<\/svg>/g, '{invalid image}')
.replace(/<(?!a |img )(\w+) [^>]*>/g, '<$1>')
.replace(/<svg[^>]*>.*?<\/svg>/g, '{invalid image}')
// log(str)
for (let i in ELEMS) {
@ -176,6 +174,9 @@ function html2md(str) {
}
} else {
str = str.replace(exp, cb)
if (i === 'pre') {
str = str.replace(/<[/]?code>/g, '')
}
}
// 对另外3种同类标签做一次处理
@ -262,9 +263,6 @@ class MEObject {
hide() {
this.vm.editorVisible = false
}
extends(addon) {
Object.assign(this.vm.addon, addon)
}
}
Anot.component('meditor', {
@ -290,8 +288,7 @@ Anot.component('meditor', {
class="editor-body"
spellcheck="false"
:attr="{disabled: disabled}"
:duplex="plainTxt"
:on-paste="onPaste($event)"></textarea>
:duplex="plainTxt"></textarea>
<content
ref="preview"
class="md-preview do-marked-theme"
@ -326,6 +323,21 @@ Anot.component('meditor', {
}
})
$editor.bind('paste', ev => {
ev.preventDefault()
let txt = ev.clipboardData.getData('text/plain').trim()
let html = ev.clipboardData.getData('text/html').trim()
html = html2md(html)
if (html) {
this.insert(html)
} else if (txt) {
this.insert(txt)
}
this.plainTxt = this.$refs.editor.value
})
$editor.bind('scroll', ev => {
let syncTop =
ev.target.scrollTop / ev.target.scrollHeight * preview.scrollHeight
@ -441,20 +453,7 @@ Anot.component('meditor', {
console.log('%c没有对应的插件%c[%s]', 'color:#f00;', '', name)
}
},
onPaste: function(ev) {
ev.preventDefault()
let txt = ev.clipboardData.getData('text/plain').trim()
let html = ev.clipboardData.getData('text/html').trim()
html = html2md(html)
if (html) {
this.insert(html)
} else if (txt) {
this.insert(txt)
}
this.plainTxt = this.$refs.editor.value
},
compile: function() {
let txt = this.plainTxt.trim()