Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_43676597
Awesome-Markdown-Editor
提交
453e0bad
Awesome-Markdown-Editor
项目概览
weixin_43676597
/
Awesome-Markdown-Editor
与 Fork 源项目一致
Fork自
gitcode_dev / Awesome-Markdown-Editor
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Awesome-Markdown-Editor
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
453e0bad
编写于
6月 21, 2021
作者:
璃白.
🌻
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat:添加高度自适应和内容长度限制
上级
8df9a059
变更
10
展开全部
隐藏空白更改
内联
并排
Showing
10 changed file
with
241 addition
and
46 deletion
+241
-46
dist/index.html
dist/index.html
+18
-5
dist/markdown-editor.js
dist/markdown-editor.js
+1
-1
package.json
package.json
+1
-1
src/App.vue
src/App.vue
+58
-2
src/assets/js/utils.js
src/assets/js/utils.js
+31
-8
src/assets/style/variable.less
src/assets/style/variable.less
+1
-0
src/components/content/md-textarea.vue
src/components/content/md-textarea.vue
+90
-14
src/components/header/md-header.vue
src/components/header/md-header.vue
+12
-3
src/components/header/tool-button.vue
src/components/header/tool-button.vue
+6
-4
src/main.js
src/main.js
+23
-8
未找到文件。
dist/index.html
浏览文件 @
453e0bad
...
...
@@ -10,6 +10,9 @@
width
:
600px
!important
;
margin
:
40px
auto
;
}
body
{
/* background-color: #222226; */
}
</style>
</head>
<body>
...
...
@@ -20,7 +23,7 @@
el
:
"
#app
"
,
// required
value
:
"
34567567567
"
,
themeOptions
:
{
dark
:
true
,
//
dark: true,
borderColor
:
"
#dbdbdb
"
,
borderColorActive
:
"
#409eff
"
,
textColor
:
"
#303030
"
,
...
...
@@ -36,19 +39,29 @@
ol
:
true
,
task
:
true
,
table
:
true
,
file
:
true
,
fullScreen
:
true
},
zIndex
:
7000
,
maxLength
:
600
,
showWordLimit
:
true
,
rows
:
"
auto
"
,
rule
:
/http:
\/\/
www
\.
baidu
\.
com/
,
canPreview
:
true
,
canAttachFile
:
true
,
placeholder
:
"
请输入内容
"
,
onFocus
:
function
(
res
)
{
console
.
log
(
res
);
},
throttle
:
1000
,
// onFocus: function(res) {
// console.log(res);
// },
onBlur
:
function
(
res
)
{
console
.
log
(
res
);
},
onInput
:
function
(
res
)
{
console
.
log
(
"
input
"
);
},
onChange
:
function
(
res
)
{
console
.
log
(
res
);
console
.
log
(
"
change
"
);
},
onSubmit
:
function
(
res
)
{
console
.
log
(
res
);
...
...
dist/markdown-editor.js
浏览文件 @
453e0bad
此差异已折叠。
点击以展开。
package.json
浏览文件 @
453e0bad
{
"name"
:
"markdown-editor"
,
"description"
:
" A open source markdown editor of csdn codechina team contributed"
,
"version"
:
"0.
3
.1"
,
"version"
:
"0.
4
.1"
,
"publisher"
:
"guoweijia"
,
"scripts"
:
{
"start"
:
"webpack serve --mode=development"
,
...
...
src/App.vue
浏览文件 @
453e0bad
...
...
@@ -8,6 +8,16 @@
:canPreview=
"canPreview"
:toolsOptions=
"toolsOptions"
:fullScreen.sync=
"fullScreen"
@
upload=
"$refs.mdUploadFile.click()"
/>
<input
ref=
"mdUploadFile"
class=
"md_upload"
type=
"file"
hidden
name=
"md-upload-file"
id=
"md-upload-file"
@
change=
"upload"
/>
<markdownPreview
:text=
"text"
:html.sync=
"html"
v-show=
"showPreview"
/>
<markdown-editor
...
...
@@ -16,17 +26,25 @@
:fileList.sync=
"fileList"
:placeholder=
"placeholder"
:isFocus.sync=
"isFocus"
:throttleTime=
"throttle"
:fullScreen.sync=
"fullScreen"
:maxLength=
"maxLength"
:textLength.sync=
"textLength"
:rows=
"rows"
@
submit=
"submit"
v-show=
"!showPreview"
/>
<markdown-footer
<div
v-if=
"maxLength && showWordLimit"
class=
"word_limit"
>
<span>
{{
textLength
}}
</span
>
/
<span>
{{
maxLength
}}
</span>
</div>
<!--
<markdown-footer
:fileList.sync=
"fileList"
:canAttachFile=
"canAttachFile"
:isFocus.sync=
"isFocus"
:can-attach-file=
"canAttachFile"
v-if=
"!showPreview && canAttachFile"
/>
/>
-->
</div>
</
template
>
<
script
>
...
...
@@ -55,6 +73,10 @@ export default {
type
:
[
String
,
Number
],
default
:
""
},
throttle
:
{
type
:
Number
,
default
:
1000
},
canPreview
:
{
type
:
Boolean
,
default
:
true
...
...
@@ -62,6 +84,22 @@ export default {
toolsOptions
:
{
type
:
Object
,
default
:
()
=>
{}
},
rows
:
{
type
:
[
Number
,
String
],
default
:
""
},
maxLength
:
{
type
:
[
Number
,
String
],
default
:
""
},
showWordLimit
:
{
type
:
Boolean
,
default
:
false
},
rule
:
{
type
:
RegExp
,
default
:
/./
}
},
data
()
{
...
...
@@ -72,6 +110,7 @@ export default {
fileList
:
[],
text
:
""
,
html
:
""
,
textLength
:
""
,
selectionInfo
:
{
selectorId
:
""
,
selectionStart
:
""
,
...
...
@@ -79,14 +118,20 @@ export default {
}
};
},
watch
:
{
html
:
{
immediate
:
true
,
handler
:
function
(
val
)
{
this
.
textLength
=
this
.
text
.
length
;
this
.
$emit
(
"
change
"
,
{
text
:
this
.
text
,
html
:
this
.
html
});
this
.
$emit
(
"
input
"
,
{
text
:
this
.
text
,
html
:
this
.
html
});
}
},
isFocus
:
{
...
...
@@ -133,6 +178,9 @@ export default {
}
},
methods
:
{
upload
(
e
)
{
this
.
fileList
=
Array
.
from
(
e
.
target
.
files
);
},
submit
()
{
this
.
$emit
(
"
submit
"
,
{
text
:
this
.
text
,
...
...
@@ -152,8 +200,16 @@ export default {
padding: 10px 16px;
box-sizing: border-box;
transition: border 0.3s;
position: relative;
&.active {
border: 1px solid var(--md-editor-border-color-active);
}
.word_limit {
position: absolute;
right: 10px;
bottom: 8px;
font-size: 12px;
color: var(--md-editor-text-color);
}
}
</
style
>
src/assets/js/utils.js
浏览文件 @
453e0bad
...
...
@@ -12,8 +12,24 @@ export function getSelectionInfo(selectorId) {
};
}
// 节流
export
const
throttle
=
function
(
fn
,
wait
)
{
var
timer
=
null
;
return
function
()
{
var
context
=
this
;
var
args
=
arguments
;
if
(
!
timer
)
{
timer
=
setTimeout
(
function
()
{
fn
.
apply
(
context
,
args
);
timer
=
null
;
},
wait
);
}
};
};
export
const
getPosition
=
function
(
selectorId
)
{
const
element
=
document
.
getElementById
(
selectorId
);
if
(
!
element
)
return
0
;
let
cursorPos
=
0
;
if
(
document
.
selection
)
{
//IE
...
...
@@ -38,6 +54,13 @@ export function formatText(text, selectionInfo, startStr = "", endStr = "") {
return
newText
;
}
export
function
setzIndex
(
index
)
{
document
.
documentElement
.
style
.
setProperty
(
"
--md-editor-fullScrren-zIndex
"
,
index
);
}
// 初始化样式
export
function
initStyle
({
dark
,
...
...
@@ -51,13 +74,13 @@ export function initStyle({
})
{
// 夜晚模式
if
(
dark
)
{
borderColor
=
"
#
b2b2b2
"
;
borderColorActive
=
"
#
fff
"
;
textColor
=
"
#
fff
"
;
textColorActive
=
"
#
fff
"
;
frameBgColor
=
"
#
343434
"
;
codeBgColor
=
"
#
48484
8
"
;
contentBgColor
=
"
#
484848
"
;
borderColor
=
"
#
44444F
"
;
borderColorActive
=
"
#
2998F2
"
;
textColor
=
"
#
777888
"
;
textColorActive
=
"
#
CCCCD8
"
;
frameBgColor
=
"
#
222226
"
;
codeBgColor
=
"
#
77788
8
"
;
contentBgColor
=
"
#
222226
"
;
}
if
(
frameBgColor
)
{
document
.
documentElement
.
style
.
setProperty
(
...
...
@@ -69,7 +92,7 @@ export function initStyle({
document
.
documentElement
.
style
.
setProperty
(
"
--md-editor-content-bg-color
"
,
contentBgColor
);
);
}
if
(
codeBgColor
)
{
...
...
src/assets/style/variable.less
浏览文件 @
453e0bad
...
...
@@ -6,4 +6,5 @@
--md-editor-frame-bg-color: #fff;
--md-editor-content-bg-color: #fff;
--md-editor-code-bg-color: #f3f4f5;
--md-editor-fullScrren-zIndex: 2000;
}
src/components/content/md-textarea.vue
浏览文件 @
453e0bad
...
...
@@ -3,6 +3,7 @@
<textarea
:id=
"id"
@
change=
"$emit('update:text', textContent)"
@
input=
"input"
@
focus=
"setFocus(true)"
@
blur=
"setFocus(false)"
@
paste=
"pasteFile"
...
...
@@ -10,7 +11,9 @@
@
keydown.ctrl.enter.exact=
"submit"
v-model=
"textContent"
:placeholder=
"placeholder"
rows=
"10"
:maxlength=
"maxLength"
:rows=
"rows"
:style=
"
{ height: editorHeight, overflow: autoSize ? 'hidden' : 'auto' }"
>
</textarea>
<span
...
...
@@ -21,13 +24,21 @@
</div>
</
template
>
<
script
>
import
{
getSelectionInfo
,
getPosition
}
from
"
@/assets/js/utils
"
;
import
{
getSelectionInfo
,
getPosition
,
throttle
as
throttleFn
}
from
"
@/assets/js/utils
"
;
export
default
{
props
:
{
fullScreen
:
{
type
:
Boolean
,
default
:
false
},
throttleTime
:
{
type
:
Number
,
default
:
1000
},
isFocus
:
{
type
:
Boolean
,
default
:
false
...
...
@@ -44,15 +55,25 @@ export default {
type
:
[
String
,
Number
],
default
:
""
},
maxLength
:
{
type
:
[
String
,
Number
],
default
:
""
},
rows
:
{
type
:
[
String
,
Number
],
default
:
""
},
selectionInfo
:
{
type
:
Object
,
default
:
()
=>
{}
}
},
data
()
{
return
{
id
:
new
Date
().
getTime
(),
textContent
:
""
textContent
:
""
,
editorHeight
:
"
auto
"
};
},
created
()
{
...
...
@@ -64,13 +85,62 @@ export default {
handler
:
function
(
val
)
{
this
.
textContent
=
val
;
}
},
textContent
:
{
immediate
:
true
,
handler
:
function
()
{
setTimeout
(()
=>
{
if
(
!
this
.
autoSize
)
return
;
this
.
reSizeHeight
();
},
0
);
}
}
},
beforeDestroy
()
{
document
.
removeEventListener
(
"
mouseup
"
,
this
.
checkSelection
);
},
computed
:
{
emitText
()
{
return
throttleFn
(()
=>
{
this
.
$emit
(
"
update:text
"
,
this
.
textContent
);
},
this
.
throttleTime
);
},
autoSize
()
{
return
this
.
rows
===
"
auto
"
;
}
},
methods
:
{
input
()
{
this
.
$emit
(
"
update:textLength
"
,
this
.
textContent
.
length
);
this
.
emitText
();
},
reSizeHeight
()
{
const
textEl
=
document
.
getElementById
(
this
.
id
);
if
(
!
textEl
)
return
;
const
fontSize
=
getComputedStyle
(
textEl
).
getPropertyValue
(
"
font-size
"
);
const
lineHeight
=
getComputedStyle
(
textEl
).
getPropertyValue
(
"
line-height
"
);
const
fontFamily
=
getComputedStyle
(
textEl
).
getPropertyValue
(
"
font-family
"
);
const
hideElId
=
"
hdieEl
"
+
this
.
id
;
let
hideEl
=
document
.
getElementById
(
hideElId
);
if
(
!
hideEl
)
{
hideEl
=
document
.
createElement
(
"
div
"
);
textEl
.
parentNode
.
appendChild
(
hideEl
);
}
hideEl
.
id
=
hideElId
;
hideEl
.
style
.
fontSize
=
fontSize
;
hideEl
.
style
.
lineHeight
=
lineHeight
;
hideEl
.
style
.
fontFamily
=
fontFamily
;
hideEl
.
innerText
=
this
.
textContent
;
const
contentHeight
=
hideEl
.
offsetHeight
;
this
.
editorHeight
=
`
${
contentHeight
+
parseFloat
(
fontSize
)
*
1.2
}
px`
;
textEl
.
parentNode
.
removeChild
(
hideEl
);
},
submit
()
{
this
.
$emit
(
"
submit
"
);
},
...
...
@@ -108,17 +178,17 @@ export default {
<
style
lang=
"less"
scoped
>
.md_textarea {
position: relative;
padding: 1
0
px 0;
padding: 1
4
px 0;
background: var(--md-editor-content-bg-color);
border-left: 1px solid var(--md-editor-border-color);
border-right: 1px solid var(--md-editor-border-color);
//
border-left: 1px solid var(--md-editor-border-color);
//
border-right: 1px solid var(--md-editor-border-color);
transition: border 0.3s;
padding: 14px;
//
padding: 14px;
box-sizing: border-box;
&.isFocus {
border-left: 1px solid var(--md-editor-border-color-active);
border-right: 1px solid var(--md-editor-border-color-active);
}
//
&.isFocus {
//
border-left: 1px solid var(--md-editor-border-color-active);
//
border-right: 1px solid var(--md-editor-border-color-active);
//
}
&.fullScreen {
position: fixed;
width: 100vw;
...
...
@@ -126,23 +196,29 @@ export default {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index:
99
;
z-index:
var(--md-editor-fullScrren-zIndex)
;
padding: 40px 60px;
box-sizing: border-box;
textarea {
font-size: 20px;
}
}
textarea {
display: block;
width: 100%;
height: 100%;
box-sizing: border-box;
background: var(--md-editor-content-bg-color);
color: var(--md-editor-text-color);
color: var(--md-editor-text-color-active);
height: var(--md-editor-height);
resize: none;
font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas",
"Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
&::placeholder {
color: var(--md-editor-text-color);
}
}
.icon {
position: absolute;
...
...
src/components/header/md-header.vue
浏览文件 @
453e0bad
...
...
@@ -21,6 +21,7 @@
:fullScreen=
"fullScreen"
@
setFullScreen=
"$emit('update:fullScreen', true)"
@
updateText=
"updateText"
@
upload=
"$emit('upload')"
v-for=
"(item, index) in toolsShow"
:key=
"index"
:text=
"text"
...
...
@@ -55,6 +56,7 @@ export default {
type
:
Object
,
default
:
()
=>
{}
},
text
:
{
type
:
[
String
,
Number
],
default
:
""
...
...
@@ -101,9 +103,9 @@ export default {
{
name
:
"
code
"
,
icon
:
"
code
"
,
tip
:
"
插入代码
"
,
startStr
:
"
`
"
,
endStr
:
"
`
"
tip
:
"
插入代码
块
"
,
startStr
:
"
\n
```
\n
"
,
endStr
:
"
\n
``
`
"
},
{
name
:
"
link
"
,
...
...
@@ -126,6 +128,13 @@ export default {
startStr
:
""
,
endStr
:
""
},
{
name
:
"
file
"
,
icon
:
"
tupian
"
,
tip
:
"
上传文件
"
,
startStr
:
""
,
endStr
:
""
},
{
name
:
"
task
"
,
icon
:
"
renwu
"
,
...
...
src/components/header/tool-button.vue
浏览文件 @
453e0bad
...
...
@@ -26,10 +26,6 @@ export default {
selectionInfo
:
{
type
:
Object
,
default
:
()
=>
{}
},
uploadPath
:
{
type
:
String
,
default
:
""
}
},
data
()
{
...
...
@@ -55,6 +51,9 @@ export default {
this
.
updateText
(
`\n
${
ulNum
}
. `
,
""
);
this
.
ulNum
++
;
break
;
case
"
file
"
:
this
.
$emit
(
"
upload
"
);
break
;
case
"
fullScreen
"
:
this
.
$emit
(
"
setFullScreen
"
,
true
);
break
;
...
...
@@ -80,6 +79,9 @@ export default {
&:hover {
color: var(--md-editor-text-color-active);
}
&.icon-tupian {
font-size: 24px;
}
}
}
</
style
>
src/main.js
浏览文件 @
453e0bad
...
...
@@ -2,7 +2,7 @@ import Vue from "vue";
import
App
from
"
./App
"
;
import
Vtip
from
"
vtip
"
;
import
"
vtip/lib/index.min.css
"
;
import
{
initStyle
,
isNotEmpty
}
from
"
@/assets/js/utils
"
;
import
{
initStyle
,
setzIndex
,
isNotEmpty
}
from
"
@/assets/js/utils
"
;
import
"
@/assets/style/global.less
"
;
Vue
.
use
(
Vtip
.
directive
);
...
...
@@ -10,13 +10,20 @@ Vue.use(Vtip.directive);
function
initMdEditor
(
obj
)
{
const
{
el
,
onChange
,
onUpload
,
onFocus
,
onBlur
,
onSubmit
,
onChange
=
()
=>
{},
onUpload
=
()
=>
{},
onFocus
=
()
=>
{},
onBlur
=
()
=>
{},
onInput
=
()
=>
{},
onSubmit
=
()
=>
{},
placeholder
,
value
,
zIndex
=
2000
,
rule
,
rows
=
10
,
maxLength
,
showWordLimit
,
throttle
,
canPreview
,
canAttachFile
,
themeOptions
,
...
...
@@ -24,7 +31,7 @@ function initMdEditor(obj) {
}
=
obj
;
if
(
!
el
||
!
document
.
querySelector
(
el
))
throw
new
Error
(
"
请指定容器
"
);
if
(
isNotEmpty
(
themeOptions
))
initStyle
(
themeOptions
);
if
(
isNotEmpty
(
zIndex
))
setzIndex
(
zIndex
);
new
Vue
({
render
:
h
=>
h
(
App
,
{
...
...
@@ -32,6 +39,9 @@ function initMdEditor(obj) {
change
(
val
)
{
onChange
(
val
);
},
input
(
val
)
{
onInput
(
val
);
},
focus
(
val
)
{
onFocus
(
val
);
},
...
...
@@ -50,9 +60,14 @@ function initMdEditor(obj) {
props
:
{
canAttachFile
,
value
,
rule
,
rows
,
throttle
,
canPreview
,
toolsOptions
,
placeholder
placeholder
,
maxLength
,
showWordLimit
}
})
}).
$mount
(
el
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录