增加meditor
parent
902aadd424
commit
98d66014ad
|
@ -0,0 +1,141 @@
|
||||||
|
/**
|
||||||
|
* 基础拓展
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2020/10/14 17:52:44
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { offset } from 'wkit'
|
||||||
|
|
||||||
|
var placeholder = '在此输入文本'
|
||||||
|
|
||||||
|
function trim(str, sign) {
|
||||||
|
return str.replace(new RegExp('^' + sign + '|' + sign + '$', 'g'), '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function docScroll(k = 'X') {
|
||||||
|
return window[`page${k.toUpperCase()}Offset`]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通用的弹层触发
|
||||||
|
function showDialog(dialog, elem) {
|
||||||
|
var { left, top } = offset(elem)
|
||||||
|
left -= docScroll('X')
|
||||||
|
top += 29 - docScroll('Y')
|
||||||
|
left += 'px'
|
||||||
|
top += 'px'
|
||||||
|
dialog.moveTo({ top, left })
|
||||||
|
dialog.show()
|
||||||
|
return Promise.resolve(dialog)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
header(elem) {
|
||||||
|
showDialog(this.__HEADER_ADDON__, elem)
|
||||||
|
},
|
||||||
|
|
||||||
|
h(level) {
|
||||||
|
var wrap = this.selection(true) || placeholder
|
||||||
|
wrap = wrap.replace(/^(#+ )?/, '#'.repeat(level) + ' ')
|
||||||
|
this.insert(wrap, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
quote(elem) {
|
||||||
|
var wrap = this.selection(true) || placeholder
|
||||||
|
wrap = wrap.replace(/^(>+ )?/, '> ')
|
||||||
|
|
||||||
|
this.insert(wrap, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
bold(elem) {
|
||||||
|
var wrap = this.selection() || placeholder
|
||||||
|
var unwrap = trim(wrap, '\\*\\*')
|
||||||
|
wrap = wrap === unwrap ? `**${wrap}**` : unwrap
|
||||||
|
this.insert(wrap, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
italic(elem) {
|
||||||
|
var wrap = this.selection() || placeholder
|
||||||
|
var unwrap = trim(wrap, '_')
|
||||||
|
wrap = wrap === unwrap ? `_${wrap}_` : unwrap
|
||||||
|
this.insert(wrap, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
through(elem) {
|
||||||
|
var wrap = this.selection() || placeholder
|
||||||
|
var unwrap = trim(wrap, '~~')
|
||||||
|
wrap = wrap === unwrap ? `~~${wrap}~~` : unwrap
|
||||||
|
this.insert(wrap, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
list(elem) {
|
||||||
|
var wrap = this.selection(true) || placeholder
|
||||||
|
|
||||||
|
wrap = wrap.replace(/^([+\-*] )?/, '+ ')
|
||||||
|
this.insert(wrap, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
order(elem) {
|
||||||
|
var wrap = this.selection(true) || placeholder
|
||||||
|
|
||||||
|
wrap = wrap.replace(/^(\d+\. )?/, '1. ')
|
||||||
|
this.insert(wrap, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
line(elem) {
|
||||||
|
this.insert('\n\n---\n\n', false)
|
||||||
|
},
|
||||||
|
|
||||||
|
code(elem) {
|
||||||
|
var wrap = this.selection() || placeholder
|
||||||
|
var unwrap = trim(wrap, '`')
|
||||||
|
wrap = wrap === unwrap ? `\`${wrap}\`` : unwrap
|
||||||
|
this.insert(wrap, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
codeblock(elem) {
|
||||||
|
this.insert('\n```language\n\n```\n')
|
||||||
|
},
|
||||||
|
|
||||||
|
table(elem) {
|
||||||
|
showDialog(this.__TABLE_ADDON__, elem)
|
||||||
|
},
|
||||||
|
|
||||||
|
link(elem) {
|
||||||
|
showDialog(this.__LINK_ADDON__, elem).then(dialog => {
|
||||||
|
var wrap = this.selection() || placeholder
|
||||||
|
dialog.__txt__.value = wrap
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
image(elem) {
|
||||||
|
var $file = this.__ATTACH_ADDON__.querySelector('input')
|
||||||
|
|
||||||
|
this._attach = 'image'
|
||||||
|
$file.setAttribute('accept', 'image/*')
|
||||||
|
|
||||||
|
showDialog(this.__ATTACH_ADDON__, elem)
|
||||||
|
},
|
||||||
|
|
||||||
|
attach(elem) {
|
||||||
|
var $file = this.__ATTACH_ADDON__.querySelector('input')
|
||||||
|
this._attach = 'file'
|
||||||
|
$file.removeAttribute('accept')
|
||||||
|
showDialog(this.__ATTACH_ADDON__, elem)
|
||||||
|
},
|
||||||
|
|
||||||
|
fullscreen(elem) {
|
||||||
|
//
|
||||||
|
this.props.fullscreen = !this.props.fullscreen
|
||||||
|
if (this.props.fullscreen) {
|
||||||
|
this.setAttribute('fullscreen', '')
|
||||||
|
} else {
|
||||||
|
this.removeAttribute('fullscreen')
|
||||||
|
}
|
||||||
|
elem.classList.toggle('active', this.props.fullscreen)
|
||||||
|
},
|
||||||
|
preview(elem) {
|
||||||
|
this.state.preview = !this.state.preview
|
||||||
|
this.__VIEW__.classList.toggle('active', this.state.preview)
|
||||||
|
elem.classList.toggle('active', this.state.preview)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,222 @@
|
||||||
|
/**
|
||||||
|
* 一些公共的东西
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2020/10/12 18:23:23
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ICONS from './svg'
|
||||||
|
|
||||||
|
const ELEMS = {
|
||||||
|
a: function (str, attr, inner) {
|
||||||
|
let href = attr.match(attrExp('href'))
|
||||||
|
let title = attr.match(attrExp('title'))
|
||||||
|
let tar = attr.match(attrExp('target'))
|
||||||
|
let attrs = ''
|
||||||
|
|
||||||
|
href = (href && href[1]) || null
|
||||||
|
title = (title && title[1]) || null
|
||||||
|
tar = (tar && tar[1]) || '_self'
|
||||||
|
|
||||||
|
if (!href) {
|
||||||
|
return inner || href
|
||||||
|
}
|
||||||
|
|
||||||
|
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 + '_') || ''
|
||||||
|
},
|
||||||
|
strong: function (str, attr, inner) {
|
||||||
|
return (inner && '**' + inner + '**') || ''
|
||||||
|
},
|
||||||
|
pre: function (str, attr, inner) {
|
||||||
|
inner = inner.replace(/<[/]?code>/g, '')
|
||||||
|
return '\n\n```\n' + inner + '\n```\n'
|
||||||
|
},
|
||||||
|
code: function (str, attr, inner) {
|
||||||
|
return (inner && '`' + inner + '`') || ''
|
||||||
|
},
|
||||||
|
blockquote: function (str, attr, inner) {
|
||||||
|
return '> ' + inner.trim()
|
||||||
|
},
|
||||||
|
img: function (str, attr, inner) {
|
||||||
|
var src = attr.match(attrExp('src')),
|
||||||
|
alt = attr.match(attrExp('alt'))
|
||||||
|
|
||||||
|
src = (src && src[1]) || ''
|
||||||
|
alt = (alt && alt[1]) || ''
|
||||||
|
|
||||||
|
return '![' + alt + '](' + src + ')'
|
||||||
|
},
|
||||||
|
p: function (str, attr, inner) {
|
||||||
|
return inner ? '\n' + inner : ''
|
||||||
|
},
|
||||||
|
br: '\n',
|
||||||
|
'h([1-6])': function (str, level, attr, inner) {
|
||||||
|
let h = '#'.repeat(level)
|
||||||
|
return '\n' + h + ' ' + inner + '\n'
|
||||||
|
},
|
||||||
|
hr: '\n\n---\n\n'
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_TOOLS = [
|
||||||
|
'header',
|
||||||
|
'quote',
|
||||||
|
'bold',
|
||||||
|
'italic',
|
||||||
|
'through',
|
||||||
|
'list',
|
||||||
|
'order',
|
||||||
|
'line',
|
||||||
|
'code',
|
||||||
|
'codeblock',
|
||||||
|
'table',
|
||||||
|
'link',
|
||||||
|
'image',
|
||||||
|
'attach',
|
||||||
|
'fullscreen',
|
||||||
|
'preview'
|
||||||
|
]
|
||||||
|
|
||||||
|
export const TOOL_TITLE = {
|
||||||
|
header: '插入标题',
|
||||||
|
h1: '一级标题',
|
||||||
|
h2: '二级标题',
|
||||||
|
h3: '三级标题',
|
||||||
|
h4: '四级标题',
|
||||||
|
h5: '五级标题',
|
||||||
|
h6: '六级标题',
|
||||||
|
quote: '引用文本',
|
||||||
|
bold: '粗体',
|
||||||
|
italic: '斜体',
|
||||||
|
through: '横线',
|
||||||
|
list: '无序列表',
|
||||||
|
order: '有序列表',
|
||||||
|
line: '分割线',
|
||||||
|
code: '行内代码',
|
||||||
|
codeblock: '插入代码块',
|
||||||
|
table: '插入表格',
|
||||||
|
link: '插入连接',
|
||||||
|
image: '上传图片',
|
||||||
|
attach: '上传附件',
|
||||||
|
fullscreen: '全屏编辑',
|
||||||
|
preview: '预览'
|
||||||
|
}
|
||||||
|
|
||||||
|
const LI_EXP = /<(ul|ol)>(?:(?!<ul|<ol)[\s\S])*?<\/\1>/gi
|
||||||
|
|
||||||
|
// html标签的属性正则
|
||||||
|
function attrExp(field, flag = 'i') {
|
||||||
|
return new RegExp(field + '\\s?=\\s?["\']?([^"\']*)["\']?', flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成html标签的正则
|
||||||
|
function tagExp(tag, open) {
|
||||||
|
var exp = ''
|
||||||
|
if (['br', 'hr', 'img'].indexOf(tag) > -1) {
|
||||||
|
exp = '<' + tag + '([^>]*?)\\/?>'
|
||||||
|
} else {
|
||||||
|
exp = '<' + tag + '([^>]*?)>([\\s\\S]*?)<\\/' + tag + '>'
|
||||||
|
}
|
||||||
|
return new RegExp(exp, 'gi')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染工具栏图标
|
||||||
|
*/
|
||||||
|
export function renderToolbar(list, tag = 'span', dict = {}, showText = false) {
|
||||||
|
return (list || DEFAULT_TOOLS)
|
||||||
|
.map(it => {
|
||||||
|
var title = showText ? '' : `title="${dict[it] || ''}"`
|
||||||
|
var text = showText ? dict[it] || '' : ''
|
||||||
|
|
||||||
|
return `<${tag} data-act="${it}" ${title}><svg class="icon" viewBox="0 0 1024 1024"><path d="${ICONS[it]}"/></svg>${text}</${tag}>`
|
||||||
|
})
|
||||||
|
.join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* html转成md
|
||||||
|
*/
|
||||||
|
export function html2md(str) {
|
||||||
|
try {
|
||||||
|
str = decodeURIComponent(str)
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
str = str
|
||||||
|
.replace(/\t/g, ' ')
|
||||||
|
.replace(/<meta [^>]*>/, '')
|
||||||
|
.replace(attrExp('class', 'g'), '')
|
||||||
|
.replace(attrExp('style', 'g'), '')
|
||||||
|
.replace(/<(?!a |img )(\w+) [^>]*>/g, '<$1>')
|
||||||
|
.replace(/<svg[^>]*>.*?<\/svg>/g, '{invalid image}')
|
||||||
|
|
||||||
|
// log(str)
|
||||||
|
for (let i in ELEMS) {
|
||||||
|
let cb = ELEMS[i]
|
||||||
|
let exp = tagExp(i)
|
||||||
|
|
||||||
|
if (i === 'blockquote') {
|
||||||
|
while (str.match(exp)) {
|
||||||
|
str = str.replace(exp, cb)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
str = str.replace(exp, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对另外3种同类标签做一次处理
|
||||||
|
if (i === 'p') {
|
||||||
|
exp = tagExp('div')
|
||||||
|
str = str.replace(exp, cb)
|
||||||
|
}
|
||||||
|
if (i === 'em') {
|
||||||
|
exp = tagExp('i')
|
||||||
|
str = str.replace(exp, cb)
|
||||||
|
}
|
||||||
|
if (i === 'strong') {
|
||||||
|
exp = tagExp('b')
|
||||||
|
str = str.replace(exp, cb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (str.match(LI_EXP)) {
|
||||||
|
str = str.replace(LI_EXP, function (match) {
|
||||||
|
match = match.replace(
|
||||||
|
/<(ul|ol)>([\s\S]*?)<\/\1>/gi,
|
||||||
|
function (m, t, inner) {
|
||||||
|
let li = inner.split('</li>')
|
||||||
|
li.pop()
|
||||||
|
|
||||||
|
for (let i = 0, len = li.length; i < len; i++) {
|
||||||
|
let pre = t === 'ol' ? i + 1 + '. ' : '* '
|
||||||
|
li[i] =
|
||||||
|
pre +
|
||||||
|
li[i]
|
||||||
|
.replace(/\s*<li>([\s\S]*)/i, function (m, n) {
|
||||||
|
n = n.trim().replace(/\n/g, '\n ')
|
||||||
|
return n
|
||||||
|
})
|
||||||
|
.replace(/<[\/]?[\w]*[^>]*>/g, '')
|
||||||
|
}
|
||||||
|
return li.join('\n')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return '\n' + match.trim()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
str = str
|
||||||
|
|
||||||
|
.replace(/<[\/]?[\w]*[^>]*>/g, '')
|
||||||
|
.replace(/```([\w\W]*)```/g, function (str, inner) {
|
||||||
|
inner = inner
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
return '```' + inner + '```'
|
||||||
|
})
|
||||||
|
return str
|
||||||
|
}
|
|
@ -0,0 +1,755 @@
|
||||||
|
/**
|
||||||
|
* {}
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2023/09/14 16:49:15
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
raw,
|
||||||
|
html,
|
||||||
|
Component,
|
||||||
|
bind,
|
||||||
|
unbind,
|
||||||
|
nextTick,
|
||||||
|
styleMap,
|
||||||
|
classMap,
|
||||||
|
outsideClick,
|
||||||
|
clearOutsideClick
|
||||||
|
} from 'wkit'
|
||||||
|
import ICONS from './svg.js'
|
||||||
|
import '../form/input.js'
|
||||||
|
import '../form/button.js'
|
||||||
|
|
||||||
|
const ACTTION = {
|
||||||
|
bold: 'bold',
|
||||||
|
italic: 'italic',
|
||||||
|
under: 'underline',
|
||||||
|
delete: 'strikeThrough',
|
||||||
|
left: 'justifyLeft',
|
||||||
|
center: 'justifyCenter',
|
||||||
|
right: 'justifyRight',
|
||||||
|
image: 'insertImage',
|
||||||
|
font: 'fontSize',
|
||||||
|
color: 'foreColor',
|
||||||
|
link: 'createLink',
|
||||||
|
ordered: 'insertOrderedList',
|
||||||
|
unordered: 'insertUnorderedList'
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_TOOLS = [
|
||||||
|
'font',
|
||||||
|
'color',
|
||||||
|
'bold',
|
||||||
|
'italic',
|
||||||
|
'under',
|
||||||
|
'delete',
|
||||||
|
'ordered',
|
||||||
|
'unordered',
|
||||||
|
'table',
|
||||||
|
'left',
|
||||||
|
'center',
|
||||||
|
'right',
|
||||||
|
'link',
|
||||||
|
'image',
|
||||||
|
'fullscreen'
|
||||||
|
]
|
||||||
|
|
||||||
|
const COLORS = [
|
||||||
|
'#f3f5fb',
|
||||||
|
'#dae1e9',
|
||||||
|
'#62778d',
|
||||||
|
'#58d68d',
|
||||||
|
'#3fc2a7',
|
||||||
|
'#52a3de',
|
||||||
|
'#ac61ce',
|
||||||
|
'#ffb618',
|
||||||
|
'#e67e22',
|
||||||
|
'#ff5061',
|
||||||
|
'#ff0000',
|
||||||
|
'#000000'
|
||||||
|
]
|
||||||
|
|
||||||
|
// 获取一维数组转二维的行
|
||||||
|
function getY(i) {
|
||||||
|
return (i / 9) >> 0
|
||||||
|
}
|
||||||
|
//获取一维数组转二维的列
|
||||||
|
function getX(i) {
|
||||||
|
return i % 9
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIndex(x, y) {
|
||||||
|
return x + y * 9
|
||||||
|
}
|
||||||
|
|
||||||
|
class MEditor extends Component {
|
||||||
|
static props = {
|
||||||
|
toolbar: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
attribute: false,
|
||||||
|
observer(v) {
|
||||||
|
if (v === null) {
|
||||||
|
this.#toolbar = [...DEFAULT_TOOLS]
|
||||||
|
} else if (v) {
|
||||||
|
this.#toolbar = v.split(',').map(it => it.trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
value: 'str!',
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
observer(v) {
|
||||||
|
this.#updateStat()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
observer(v) {
|
||||||
|
this.#updateStat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = [
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
min-width: 200px;
|
||||||
|
max-height: 720px;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: box-shadow 0.15s linear;
|
||||||
|
background: var(--wc-meditor-background, #fff);
|
||||||
|
}
|
||||||
|
.noselect {
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
|
||||||
|
css`
|
||||||
|
.meditor {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid var(--wc-editor-border-color, var(--color-grey-2));
|
||||||
|
border-radius: inherit;
|
||||||
|
font-size: 14px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 34px;
|
||||||
|
padding: 5px;
|
||||||
|
line-height: 24px;
|
||||||
|
border-bottom: 1px solid var(--color-grey-1);
|
||||||
|
|
||||||
|
span {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin: 0 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: var(--color-grey-3);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
overflow: hidden;
|
||||||
|
width: 70%;
|
||||||
|
height: 70%;
|
||||||
|
fill: currentColor;
|
||||||
|
color: #62778d;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.active {
|
||||||
|
background: var(--color-plain-1);
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
color: var(--color-teal-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
css`
|
||||||
|
.editor-outbox {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
.editor,
|
||||||
|
.preview {
|
||||||
|
flex: 1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor {
|
||||||
|
height: 100%;
|
||||||
|
padding: 5px 8px;
|
||||||
|
line-height: 1.5;
|
||||||
|
border: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
|
||||||
|
color: var(--color-dark-1);
|
||||||
|
background: none;
|
||||||
|
outline: none;
|
||||||
|
resize: none;
|
||||||
|
cursor: inherit;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: var(--color-grey-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview {
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
display: none;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-left: 1px solid var(--color-plain-2);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
css`
|
||||||
|
:host([readonly]) {
|
||||||
|
.editor {
|
||||||
|
cursor: default;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:host([disabled]) {
|
||||||
|
.editor {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:host([readonly]),
|
||||||
|
:host([disabled]) {
|
||||||
|
.toolbar {
|
||||||
|
span:hover {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(:focus-within) {
|
||||||
|
box-shadow: 0 0 0 2px var(--color-plain-a);
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(.fullscreen) {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 9;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
max-height: 100vh;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
|
||||||
|
css`
|
||||||
|
.addon-table {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 222px;
|
||||||
|
height: 222px;
|
||||||
|
padding: 2px;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background: var(--color-plain-1);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: rgba(77, 182, 172, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.addon-header {
|
||||||
|
width: 108px;
|
||||||
|
height: 190px;
|
||||||
|
padding: 5px 0;
|
||||||
|
line-height: 30px;
|
||||||
|
user-select: none;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
padding: 0 12px;
|
||||||
|
transition: background 0.1s ease-in-out;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--color-plain-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.addon-link {
|
||||||
|
width: 320px;
|
||||||
|
padding: 8px 5px;
|
||||||
|
background: #fff;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 12px;
|
||||||
|
margin-top: 6px;
|
||||||
|
|
||||||
|
label {
|
||||||
|
width: 60px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
wc-input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wc-button {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.addon-attach {
|
||||||
|
width: 320px;
|
||||||
|
padding: 8px 5px;
|
||||||
|
background: #fff;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid var(--color-plain-2);
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
span {
|
||||||
|
height: 28px;
|
||||||
|
padding: 0 8px;
|
||||||
|
line-height: 28px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: var(--color-teal-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.remote,
|
||||||
|
.locale {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.locale {
|
||||||
|
height: 120px;
|
||||||
|
padding: 24px 32px;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 12px 16px;
|
||||||
|
line-height: 46px;
|
||||||
|
border: 1px dashed var(--color-plain-3);
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.1s ease-in-out;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '点击选择文件,或拖拽文件到此处';
|
||||||
|
}
|
||||||
|
&:hover,
|
||||||
|
&.active {
|
||||||
|
background: rgba(255, 228, 196, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 12px;
|
||||||
|
margin-top: 6px;
|
||||||
|
|
||||||
|
label {
|
||||||
|
width: 60px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
wc-input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wc-button {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
]
|
||||||
|
|
||||||
|
#toolbar = []
|
||||||
|
#value = ''
|
||||||
|
#cache = { bar: 0, y: 0 }
|
||||||
|
#gridx = 0
|
||||||
|
#gridy = 0
|
||||||
|
|
||||||
|
#select = null
|
||||||
|
|
||||||
|
__init__() {
|
||||||
|
//
|
||||||
|
let { outer, inner, thumb } = this.$refs
|
||||||
|
let height = outer.offsetHeight
|
||||||
|
let scrollHeight = inner.scrollHeight + 10
|
||||||
|
|
||||||
|
let bar = 50 // 滚动条的高度
|
||||||
|
bar = (height * (height / scrollHeight)) >> 0
|
||||||
|
|
||||||
|
if (bar < 50) {
|
||||||
|
bar = 50
|
||||||
|
}
|
||||||
|
|
||||||
|
// 100%或主体高度比滚动条还短时不显示
|
||||||
|
if (bar >= height) {
|
||||||
|
bar = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#cache.bar = bar
|
||||||
|
thumb.style.height = bar + 'px'
|
||||||
|
}
|
||||||
|
|
||||||
|
#updateStat() {
|
||||||
|
if (this.$refs.editor) {
|
||||||
|
if (this.readOnly || this.disabled) {
|
||||||
|
this.$refs.editor.removeAttribute('contenteditable')
|
||||||
|
} else {
|
||||||
|
this.$refs.editor.setAttribute('contenteditable', '')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nextTick(_ => this.#updateStat())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#fetchScroll(moveY) {
|
||||||
|
let { bar } = this.#cache
|
||||||
|
let { outer, thumb, inner } = this.$refs
|
||||||
|
let height = outer.offsetHeight
|
||||||
|
let scrollHeight = inner.scrollHeight + 10
|
||||||
|
|
||||||
|
if (moveY < 0) {
|
||||||
|
moveY = 0
|
||||||
|
} else if (moveY > height - bar) {
|
||||||
|
moveY = height - bar
|
||||||
|
}
|
||||||
|
|
||||||
|
inner.scrollTop = (scrollHeight - height) * (moveY / (height - bar))
|
||||||
|
thumb.style.transform = `translateY(${moveY}px)`
|
||||||
|
return moveY
|
||||||
|
}
|
||||||
|
|
||||||
|
#hideLayers() {
|
||||||
|
this.$refs.font.classList.remove('fadein')
|
||||||
|
this.$refs.color.classList.remove('fadein')
|
||||||
|
this.$refs.link.classList.remove('fadein')
|
||||||
|
this.$refs.table.classList.remove('fadein')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理图片
|
||||||
|
#handleImage(ev, file) {
|
||||||
|
if (ev && ev.type === 'change') {
|
||||||
|
file = ev.target.files[0]
|
||||||
|
ev.target.value = ''
|
||||||
|
}
|
||||||
|
this.$emit('upload', {
|
||||||
|
detail: {
|
||||||
|
file,
|
||||||
|
send: link => {
|
||||||
|
this.$refs.editor.focus()
|
||||||
|
this.restoreSelection()
|
||||||
|
this.exec(ACTTION.image, link)
|
||||||
|
this.saveSelection()
|
||||||
|
|
||||||
|
// 修正插入的图片,宽度不得超出容器
|
||||||
|
this.$refs.editor.querySelectorAll('img').forEach(_ => {
|
||||||
|
_.style.maxWidth = '100%'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#handlePaste(ev) {
|
||||||
|
let html = ev.clipboardData.getData('text/html')
|
||||||
|
let txt = ev.clipboardData.getData('text/plain')
|
||||||
|
let items = ev.clipboardData.items
|
||||||
|
|
||||||
|
// 先文件判断, 避免右键单击复制图片时, 当成html处理
|
||||||
|
if (items && items.length) {
|
||||||
|
let blob = null
|
||||||
|
for (let it of items) {
|
||||||
|
if (it.type.indexOf('image') > -1) {
|
||||||
|
blob = it.getAsFile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blob) {
|
||||||
|
return this.#handleImage(null, blob)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (html) {
|
||||||
|
html = html
|
||||||
|
.replace(/\t/g, ' ')
|
||||||
|
.replace(/<\/?(meta|link|script)[^>]*?>/g, '')
|
||||||
|
.replace(/<!--[\w\W]*?-->/g, '')
|
||||||
|
.replace(
|
||||||
|
/<a[^>]*? href\s?=\s?["']?([^"']*)["']?[^>]*?>/g,
|
||||||
|
'<a href="$1">'
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
/<img[^>]*? src\s?=\s?["']?([^"']*)["']?[^>]*?>/g,
|
||||||
|
'<img src="$1">'
|
||||||
|
)
|
||||||
|
.replace(/<(?!a|img)([\w\-]+)[^>]*>/g, '<$1>')
|
||||||
|
.replace(/<xml[^>]*?>[\w\W]*?<\/xml>/g, '')
|
||||||
|
.replace(/<style>[\w\W]*?<\/style>/g, '')
|
||||||
|
|
||||||
|
return this.exec('insertHtml', html)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txt) {
|
||||||
|
return this.exec('insertText', txt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbarClick(ev) {
|
||||||
|
var target = ev.target
|
||||||
|
var act
|
||||||
|
|
||||||
|
this.restoreSelection()
|
||||||
|
|
||||||
|
if (ev.target === ev.currentTarget) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.readOnly || this.disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
while (target.tagName !== 'SPAN') {
|
||||||
|
target = target.parentNode
|
||||||
|
}
|
||||||
|
|
||||||
|
act = target.dataset.act
|
||||||
|
|
||||||
|
this.#hideLayers()
|
||||||
|
|
||||||
|
switch (act) {
|
||||||
|
case 'font':
|
||||||
|
case 'color':
|
||||||
|
case 'link':
|
||||||
|
case 'table':
|
||||||
|
this.$refs[act].classList.add('fadein')
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'image':
|
||||||
|
// 这里不作任何处理
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'copy':
|
||||||
|
navigator.clipboard.writeText(this.value)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'fullscreen':
|
||||||
|
this.classList.toggle('fullscreen')
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
this.$refs.editor.focus()
|
||||||
|
this.restoreSelection()
|
||||||
|
this.exec(ACTTION[act])
|
||||||
|
this.saveSelection()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#chnageFontSize(ev) {
|
||||||
|
if (ev.target === ev.currentTarget) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$refs.font.classList.remove('fadein')
|
||||||
|
this.$refs.editor.focus()
|
||||||
|
this.restoreSelection()
|
||||||
|
this.exec(ACTTION.font, ev.target.dataset.size)
|
||||||
|
this.saveSelection()
|
||||||
|
}
|
||||||
|
|
||||||
|
#chnageColor(ev) {
|
||||||
|
if (ev.target === ev.currentTarget) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$refs.color.classList.remove('fadein')
|
||||||
|
this.$refs.editor.focus()
|
||||||
|
this.restoreSelection()
|
||||||
|
this.exec(ACTTION.color, ev.target.dataset.value)
|
||||||
|
this.saveSelection()
|
||||||
|
}
|
||||||
|
|
||||||
|
#insertLink(ev) {
|
||||||
|
let value = this.$refs.linkinput.value.trim()
|
||||||
|
if (value) {
|
||||||
|
this.$refs.link.classList.remove('fadein')
|
||||||
|
this.$refs.editor.focus()
|
||||||
|
this.restoreSelection()
|
||||||
|
this.exec(ACTTION.link, value)
|
||||||
|
this.saveSelection()
|
||||||
|
this.$refs.linkinput.value = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#insertTable(ev) {
|
||||||
|
let th = `<th> </th>`.repeat(this.#gridx + 1)
|
||||||
|
let td = `<td> </td>`.repeat(this.#gridx + 1)
|
||||||
|
this.exec(
|
||||||
|
'insertHtml',
|
||||||
|
`<br>
|
||||||
|
<table>
|
||||||
|
<thead><tr>${th}</tr></thead>
|
||||||
|
<tbody>${`<tr>${td}</tr>`.repeat(this.#gridy + 1)}</tbody>
|
||||||
|
</table><br>`
|
||||||
|
)
|
||||||
|
this.$refs.table.classList.remove('fadein')
|
||||||
|
}
|
||||||
|
|
||||||
|
#tableSelect(ev) {
|
||||||
|
let grids = Array.from(this.$refs.table.children)
|
||||||
|
if (ev.type === 'mousemove') {
|
||||||
|
if (ev.target === ev.currentTarget) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let idx = +ev.target.dataset.idx
|
||||||
|
let x = getX(idx)
|
||||||
|
let y = getY(idx)
|
||||||
|
// 避免每次遍历完所有的节点
|
||||||
|
let max = Math.max(getIndex(this.#gridx, this.#gridy), idx) + 1
|
||||||
|
|
||||||
|
if (x === this.#gridx && y === this.#gridy) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.#gridx = x
|
||||||
|
this.#gridy = y
|
||||||
|
|
||||||
|
for (let i = 0; i < max; i++) {
|
||||||
|
let _x = getX(i)
|
||||||
|
let _y = getY(i)
|
||||||
|
grids[i].classList.toggle('active', _x <= x && _y <= y)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
grids.forEach(it => it.classList.remove('active'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存选中
|
||||||
|
saveSelection() {
|
||||||
|
var gs = this.root.getSelection()
|
||||||
|
if (gs.getRangeAt && gs.rangeCount) {
|
||||||
|
this.#select = gs.getRangeAt(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除选中并重置选中
|
||||||
|
restoreSelection() {
|
||||||
|
var gs = this.root.getSelection()
|
||||||
|
if (this.#select) {
|
||||||
|
try {
|
||||||
|
gs.removeAllRanges()
|
||||||
|
} catch (err) {}
|
||||||
|
gs.addRange(this.#select)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 执行命令
|
||||||
|
exec(cmd, val = '') {
|
||||||
|
document.execCommand(cmd, false, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
mounted() {}
|
||||||
|
|
||||||
|
unmounted() {}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
// toolbar = [
|
||||||
|
// ...(this.#toolbar.length ? this.#toolbar : DEFAULT_TOOLS),
|
||||||
|
// 'copy'
|
||||||
|
// ]
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="meditor">
|
||||||
|
<section class="toolbar"></section>
|
||||||
|
<div class="editor-outbox">
|
||||||
|
<textarea
|
||||||
|
class="editor"
|
||||||
|
spellcheck="false"
|
||||||
|
:value=${this.value}
|
||||||
|
></textarea>
|
||||||
|
<wc-markd class="preview"></wc-markd>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEditor.reg('meditor')
|
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
* icon字典
|
||||||
|
* @author yutent<yutent.io@gmail.com>
|
||||||
|
* @date 2019/07/08 17:39:11
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
header:
|
||||||
|
'M128 457.15h329.14v109.71H347.43v329.13H237.71V566.86H128V457.15z m767.98-219.43H680.21v658.27h-117V237.72H347.44V128.01H896l-0.02 109.71z',
|
||||||
|
h1: 'M567.23 896h-62.15V523.45H222.22V896h-62.93V128h62.93v326.11h282.86V128h62.15v768z m297.48-1.48h-230.2v-59.5h86.99V535.26h-69.38v-47.71l6.3-1.26c32.06-6.4 57.01-15.6 78.51-28.96l1.9-1.18h47.43v378.86h78.45v59.51z',
|
||||||
|
h2: 'M864.54 896H639.87v-41.55l2.05-2.24C745.85 738.4 792.2 657.17 792.2 588.8c0-67.27-37.32-74.53-53.37-74.53-26.94 0-48.8 24.36-62.39 44.79l-5.89 8.85-34.57-42.49 3.6-4.88C663.09 488.62 693.86 456 743.82 456c63.42 0 104.4 51.46 104.4 131.1 0 40.81-12.01 83.37-36.73 130.12-19.26 36.44-45.83 75.01-83 120.37 12.26-1.15 24.97-2.13 36.18-2.13h99.87V896z m-297.34-0.37h-62.12V523.26H222.36v372.37h-62.91V128h62.91v325.95h282.72V128h62.12v767.63z',
|
||||||
|
h3: 'M750.38 895.4c-25.28 0-48.37-6.06-68.62-18.01-16.41-9.68-30.85-22.96-44.14-40.59l-3.25-4.31 29.65-47.34 6.88 8.82c23.21 29.74 47.46 43.58 76.3 43.58 36.26 0 59.69-26.54 59.69-67.61 0-50.29-30.34-73.71-95.49-73.71h-7.84v-54.51h7.84c30.05 0 52.33-6.8 66.22-20.2 11.9-11.49 17.94-28.18 17.94-49.63 0-34.99-18.06-56.51-48.32-57.62-27.59 1.28-49.4 21.14-62.85 37.61l-6.6 8.08-31.61-45.8 4.05-4.59c30.51-34.64 62.83-51.48 98.79-51.48 30.23 0 56.07 9.96 74.74 28.81 19.38 19.58 29.63 47.62 29.63 81.1 0 43.53-17.82 77.85-50.55 98.17 15.76 7.15 29.34 18.23 39.81 32.57 14.44 19.79 22.07 44.99 22.07 72.85 0 36.77-11.54 68.12-33.36 90.68-20.67 21.37-49.43 33.13-80.98 33.13z m-183.15 0.6h-62.15V523.45H222.22V896h-62.94V128h62.94v326.11h282.86V128h62.15v768z',
|
||||||
|
h4: 'M823.31 894.76h-52.82V778.48H634.31v-44.16l133.11-277.17h55.89v263.64h41.41v57.7h-41.41v116.27zM695.34 720.79h75.15V599.11c0-9.81 0.37-22.31 0.86-35.25-3.17 7.66-6.55 15.63-10.16 23.98l-0.17 0.37-65.68 132.58zM567.23 896h-62.15V523.45H222.22V896h-62.94V128h62.94v326.11h282.86V128h62.15v768z',
|
||||||
|
h5: 'M567.23 896h-62.15V523.45H222.22V896h-62.94V128h62.94v326.11h282.86V128h62.15v768z m181.59-0.16c-58.28 0-91.28-33.08-111.04-57.97l-3.36-4.24 28.84-48.43 7.06 8.89c30.07 37.86 54.74 42.97 74.91 42.97 16.75 0 32.15-8.23 43.37-23.16 12.45-16.58 19.03-39.78 19.03-67.1 0-27.27-5.93-49.76-17.16-65.04-10.5-14.28-25.51-21.83-43.44-21.83-19.59 0-31.69 7.27-49.89 22.55l-4.83 4.06-30.32-23.38 10.97-206.03h176v59.91H723.73l-6.59 97.77c12.81-6.63 25.67-9.67 40.24-9.67 31.08 0 57.49 11.98 76.37 34.65 20.55 24.67 30.97 60.1 30.97 105.32-0.01 98.95-58.31 150.73-115.9 150.73z',
|
||||||
|
h6: 'M567.22 895.92h-62.14V523.41H222.25v372.51h-62.93V128h62.93v326.08h282.83V128h62.14v767.92z m191.63 0.08c-36.45 0-67.06-18.74-88.53-54.2-22-36.32-33.62-90.02-33.62-155.31 0-75.99 13.35-134.66 39.68-174.4 23.41-35.32 56.12-54 94.61-54 33.88 0 62.8 15.03 85.97 44.68l3.66 4.69-33.35 45.27-6.25-8.98c-12.1-17.38-30.28-27.75-48.64-27.75-22.59 0-40.82 11.25-54.18 33.43-14.23 23.61-22.73 58.91-25.36 105.12 20.59-21.5 45.78-34.22 69.27-34.22 31.54 0 57.57 12.13 75.26 35.06 18.11 23.48 27.3 57.31 27.3 100.55 0 39.09-10.89 74.77-30.67 100.48-19.64 25.52-46.33 39.58-75.15 39.58z m-65.74-175.89c2.63 39.75 9.87 70.41 21.54 91.16 11.06 19.65 25.93 29.62 44.2 29.62 28.99 0 50.02-35.72 50.02-84.94 0-26.16-4.82-47.37-13.95-61.34-9.03-13.82-22.42-20.82-39.81-20.82-21.46-0.01-43.98 16.84-62 46.32z',
|
||||||
|
codeblock:
|
||||||
|
'M819.2 864H204.8c-42.35 0-76.8-35.89-76.8-80V240c0-44.11 34.45-80 76.8-80h614.4c42.35 0 76.8 35.89 76.8 80v544c0 44.11-34.45 80-76.8 80zM233.74 221.09c-23.02 0-41.74 19.58-41.74 43.64v494.55c0 24.06 18.72 43.64 41.74 43.64h556.52c23.02 0 41.74-19.57 41.74-43.64V264.73c0-24.06-18.72-43.64-41.74-43.64H233.74z m410.77 417.59l124.33-106.53c4.56-3.9 7.17-9.61 7.16-15.66 0-6.04-2.62-11.75-7.18-15.64L644.44 394.58l-0.08-0.07c-4.15-3.45-9.38-5.07-14.74-4.55-5.37 0.52-10.21 3.12-13.65 7.33-6.96 8.51-5.91 21.33 2.34 28.56l106.15 90.68-106.04 90.86c-5.59 4.64-8.33 12-7.14 19.23 1.2 7.3 6.21 13.39 13.08 15.91 2.23 0.82 4.55 1.21 6.85 1.21a20.11 20.11 0 0 0 13.3-5.06zM414.63 774.64c5.1-1.98 9.11-5.86 11.29-10.93L635.93 276.7c4.44-10.29-0.19-22.37-10.3-26.93-4.92-2.22-10.41-2.37-15.44-0.41-5.1 1.98-9.11 5.86-11.29 10.93L388.88 747.3c-4.44 10.28 0.18 22.36 10.3 26.93 2.63 1.19 5.42 1.78 8.21 1.78 2.45 0 4.89-0.46 7.24-1.37z m-20.52-129.77c8.5 0 16.14-5.45 19.02-13.56 2.84-8.03 0.43-17.11-6.01-22.61L299.6 516.99l107.47-91.67c5.54-4.65 8.23-12.01 7.03-19.19-1.21-7.22-6.17-13.28-12.95-15.81a20.027 20.027 0 0 0-20.06 3.61L255.2 501.31c-4.57 3.9-7.2 9.61-7.2 15.68 0 6.06 2.62 11.77 7.2 15.67l125.88 107.38a20 20 0 0 0 12.99 4.82c0.02 0.01 0.02 0.01 0.04 0.01z',
|
||||||
|
code: 'M686.87 681.71c-2.86 0-5.73-0.45-8.5-1.38-8.85-2.96-15.33-10.29-16.91-19.12-1.6-8.91 2-17.92 9.4-23.53L829.48 513.1 670.76 388.8c-5.33-4.28-8.57-10.3-9.12-16.94-0.55-6.57 1.61-12.96 6.08-17.97 9.08-10.2 24.78-11.64 35.74-3.29l0.08 0.06 183.01 143.31c6 4.7 9.44 11.66 9.44 19.08 0 7.43-3.43 14.39-9.43 19.09l-182.94 143.7c-4.72 3.84-10.7 5.87-16.75 5.87zM356.91 865.09c-3.4 0-6.86-0.65-10.16-2.01-6.53-2.7-11.49-7.7-13.96-14.08-2.37-6.12-2.13-12.77 0.67-18.72l308.99-656.84c5.75-12.23 20.9-17.85 33.78-12.53 6.53 2.7 11.49 7.7 13.96 14.09 2.37 6.12 2.13 12.77-0.67 18.72L380.54 850.56c-4.28 9.09-13.75 14.53-23.63 14.53zM339 682.25c-5.93 0-11.73-1.98-16.32-5.58L137.47 531.83c-6.02-4.71-9.47-11.67-9.47-19.11 0-7.44 3.45-14.41 9.47-19.11L322.7 348.77c6.94-5.51 16.59-7.13 25.13-4.21 8.73 2.99 15.15 10.27 16.74 19.01 1.61 8.84-1.93 17.84-9.24 23.47L194.59 512.72l160.78 125.72c8.53 6.67 11.7 17.8 7.87 27.69-3.73 9.64-13.46 16.12-24.21 16.12H339z',
|
||||||
|
quote:
|
||||||
|
'M328.25 527.53h120.17V896H128V617.21C128 312.66 234.77 149.55 448.42 128v138.19c-80.08 25.76-120.17 99.55-120.17 221.61v39.73z m447.62 0H896V896H575.58V617.21c0-304.55 106.74-467.66 320.32-489.21v138.19c-80.05 25.76-120.13 99.55-120.13 221.61v39.72h0.1z',
|
||||||
|
bold: 'M573.71 758.85h-192V594.28h192c45.53 0 82.29 36.76 82.29 82.29 0 45.53-36.76 82.28-82.29 82.28m-192-493.71h164.57c45.53 0 82.29 36.75 82.29 82.29s-36.75 82.29-82.29 82.29H381.71m307.21 70.76c53.21-37.3 90.51-98.19 90.51-153.05 0-123.98-96-219.43-219.43-219.43H217.14v768h386.19c115.2 0 203.52-93.26 203.52-207.91 0.01-83.38-47.17-154.7-117.93-187.61z',
|
||||||
|
image:
|
||||||
|
'M550.34 397.58h210.87L550.34 186.71v210.87M281.96 129.2h306.72l230.04 230.04v460.08c0 42.17-34.51 76.68-76.68 76.68H281.96c-42.56 0-76.68-34.51-76.68-76.68V205.88a76.406 76.406 0 0 1 22.38-54.3 76.406 76.406 0 0 1 54.3-22.38m0 690.12h460.08V512.6L588.68 665.96 512 589.28 281.96 819.32m76.68-421.74c-42.17 0-76.68 34.51-76.68 76.68s34.51 76.68 76.68 76.68 76.68-34.51 76.68-76.68-34.51-76.68-76.68-76.68z',
|
||||||
|
attach:
|
||||||
|
'M821.2 466.43L501.65 785.98c-63.92 63.92-168.48 63.92-232.4 0-63.91-63.91-63.91-168.48 0-232.4l334.07-334.07c40.67-40.67 104.58-40.67 145.25 0s40.67 104.58 0 145.25L414.5 698.83c-15.97 15.97-42.13 15.97-58.1 0-15.97-15.97-15.97-42.13 0-58.1l275.97-275.97-43.57-43.57-275.98 275.96c-40.66 40.67-40.67 104.58 0 145.25s104.58 40.67 145.25 0l334.07-334.07c63.91-63.91 63.92-168.48 0-232.4s-168.49-63.91-232.4 0L225.68 510c-88.6 88.6-88.6 230.95 0 319.55s230.95 88.6 319.55 0L864.78 510l-43.58-43.57z',
|
||||||
|
link: 'M338.96 895.99c-27.5 0-53.33-10.68-72.73-30.08L158.08 757.76c-19.4-19.4-30.08-45.24-30.08-72.74 0-27.5 10.68-53.33 30.08-72.71l135.97-135.97c12.84-12.84 33.74-12.84 46.58 0 6.22 6.22 9.65 14.5 9.65 23.3s-3.43 17.07-9.65 23.29L204.66 658.88c-14.41 14.41-14.41 37.87 0 52.29l108.15 108.15c14.41 14.42 37.87 14.42 52.31 0l216.29-216.3c6.94-6.94 10.75-16.22 10.75-26.14 0-9.92-3.82-19.21-10.75-26.15l-59.47-59.49c-6.22-6.22-9.65-14.49-9.65-23.29 0-8.8 3.43-17.07 9.65-23.29 12.84-12.84 33.74-12.84 46.58 0L628 504.14c19.38 19.36 30.06 45.19 30.06 72.73 0 27.54-10.67 53.37-30.06 72.73L411.71 865.9c-19.39 19.41-45.23 30.09-72.75 30.09zM478.8 588.96c-8.8 0-17.07-3.43-23.29-9.65l-59.49-59.48c-19.38-19.37-30.06-45.2-30.06-72.73s10.67-53.37 30.06-72.75l216.31-216.3c19.36-19.37 45.19-30.04 72.73-30.04 27.51 0 53.34 10.66 72.73 30.03L865.94 266.2c19.38 19.38 30.06 45.21 30.06 72.74 0 27.53-10.68 53.37-30.06 72.74L729.98 547.64c-6.22 6.22-14.49 9.65-23.29 9.65s-17.07-3.43-23.29-9.65c-6.22-6.22-9.65-14.49-9.65-23.29 0-8.8 3.43-17.07 9.65-23.29l135.96-135.97c6.93-6.95 10.76-16.23 10.76-26.15 0-9.92-3.82-19.21-10.76-26.15L711.2 204.64c-6.59-6.58-16.12-10.36-26.15-10.36h-0.02c-10.03 0-19.55 3.78-26.12 10.36L442.6 420.94c-6.94 6.94-10.76 16.23-10.76 26.15 0 9.92 3.82 19.2 10.76 26.14l59.49 59.49c12.84 12.85 12.84 33.74 0 46.58-6.22 6.23-14.49 9.66-23.29 9.66z',
|
||||||
|
order:
|
||||||
|
'M320 215v82h576v-82M320 553h576v-82H320m0 338h576v-82H320m-192 9h85.33v16h-42.67v32h42.67v16H128v32h128V704H128v32z m0-256h76.8L128 547.2V576h128v-32h-76.8l76.8-67.2V448H128m64-128h42V192h-84v32h42',
|
||||||
|
italic:
|
||||||
|
'M391.7 128c0.67 38.67 1.33 77.33 2 116h146c-58 169.14-115.99 338.28-173.99 507.42-67.14 0.17-134.28 0.33-201.42 0.5 0.06 47.64 0.11 95.28 0.17 142.92 176.19 0.39 352.39 0.77 528.58 1.16V751.42H510.29C571.1 581.95 631.9 412.47 692.7 243h167V128h-468z',
|
||||||
|
through:
|
||||||
|
'M896 514.38v69.72H742.75c34.91 74.61 33.16 278.89-217.48 278.89-290.79 1.74-279.62-226.6-279.62-226.6l138.59 1.74c1.05 117.48 110.31 117.48 131.96 116.09 22.34-1.74 105.77-1.39 112.41-82.97 2.79-38-35.61-66.93-77.5-87.15H128v-69.72h768M770.68 371.1l-138.94-1.04s5.93-96.57-114.5-96.92c-120.44-0.7-109.96 76.69-109.96 86.45 1.4 9.77 11.87 57.88 104.73 80.88H292.42S170.59 205.85 468.01 165.75c304.06-41.82 303.36 206.04 302.67 205.35z',
|
||||||
|
|
||||||
|
list: 'M320 215v82h576v-82M320 553h576v-82H320m0 338h576v-82H320m-64-215c0 35.35-28.65 64-64 64s-64-28.65-64-64 28.65-64 64-64 64 28.65 64 64z m0 256c0 35.35-28.65 64-64 64s-64-28.65-64-64 28.65-64 64-64 64 28.65 64 64z m0-512c0 35.35-28.65 64-64 64s-64-28.65-64-64 28.65-64 64-64 64 28.65 64 64z',
|
||||||
|
line: 'M868.29 539.71H155.71c-15.28 0-27.71-12.43-27.71-27.71s12.43-27.71 27.71-27.71h712.58c15.28 0 27.71 12.43 27.71 27.71s-12.43 27.71-27.71 27.71z',
|
||||||
|
preview:
|
||||||
|
'M512 253.14c-174.51 0-322.97 106.97-384 258.86 61.03 151.89 209.49 258.86 384 258.86S834.97 663.89 896 512c-61.03-151.89-209.49-258.86-384-258.86z m0 431.49c-96 0-174.51-77.66-174.51-172.63S416 339.37 512 339.37 686.51 417.03 686.51 512 608 684.63 512 684.63z m0-276.17c-57.6 0-104.74 46.63-104.74 103.54S454.4 615.54 512 615.54 616.74 568.91 616.74 512 569.6 408.46 512 408.46z',
|
||||||
|
table:
|
||||||
|
'M860 159H164c-19.88 0-36 16.93-36 37.82v630.36c0 20.89 16.12 37.82 36 37.82h696c19.88 0 36-16.93 36-37.82V196.82c0-20.89-16.12-37.82-36-37.82z m-422 26.74c20.98 0 38 17.01 38 38 0 20.98-17.02 38-38 38-20.99 0-38-17.01-38-38s17.02-38 38-38z m-108 0c20.98 0 38 17.01 38 38 0 20.98-17.02 38-38 38-20.99 0-38-17.01-38-38s17.01-38 38-38z m-108 0c20.98 0 38 17.01 38 38 0 20.98-17.01 38-38 38s-38-17.01-38-38 17.01-38 38-38zM664 808V664h176v144H664z m-64-144v144H424V664h176z m-416 0h176v144H184V664z m480-190h176v144H664V474zM424 618V474h176v144H424z m-64 0H184V474h176v144z m480-338v144H664V280h176z m-240 0v144H424V280h176z m-385.54 0H360v144H184V280h30.46z',
|
||||||
|
fullscreen:
|
||||||
|
'M597.33 449.42l40.02 41.25 94.25-93.75 36.4 35V320H654.14l37.44 36.3-94.25 93.12z m-170.66 124.6l-40.41-40.68-93.53 93.93L256 592.76l0.95 111.24 113.96-0.9-37.78-35.78 93.54-93.3z m211.91-40.69l-41.25 40.02 93.75 94.24-35 36.4H768V590.14l-36.3 37.44-93.12-94.25z m-252.86-42.66l40.95-40.23-93.84-93.87L367.56 320l-111.56 0.5 0.48 113.91 36.02-37.62 93.22 93.88zM848 832H176c-26.47 0-48-19.57-48-43.64V235.64c0-24.06 21.53-43.64 48-43.64h672c26.47 0 48 19.58 48 43.64v552.73c0 24.06-21.53 43.63-48 43.63zM206.55 256c-8.02 0-14.55 5.74-14.55 12.8v486.4c0 7.06 6.53 12.8 14.55 12.8h610.91c8.02 0 14.55-5.74 14.55-12.8V268.8c0-7.06-6.53-12.8-14.55-12.8H206.55z'
|
||||||
|
}
|
Loading…
Reference in New Issue