提交 a6571f9f 编写于 作者: 璃白.'s avatar 璃白. 🌻

feat:添加附件解析器

上级 369d74fd
...@@ -85,8 +85,8 @@ void main() ...@@ -85,8 +85,8 @@ void main()
value: value:
"## edswgdfgdfgdfg\n**dfgdfgdfg**\n_ergdfgdfg_\n> ergergdfg\n```\nwefgdfsfdgdf\n```\n- efwefsdfsdf\n\n\nsdgfdfgdfgdfg\n\n\nedrfgdfgdfg\n\n\n\nergergergergerg\nergergergerg\n\n\nedrfgdfgdfg\n\n\n\nergergergergerg\nergergergerg\n\n\nedrfgdfgdfg\n\n\n\nergergergergerg\nergergergerg", "## edswgdfgdfgdfg\n**dfgdfgdfg**\n_ergdfgdfg_\n> ergergdfg\n```\nwefgdfsfdgdf\n```\n- efwefsdfsdf\n\n\nsdgfdfgdfgdfg\n\n\nedrfgdfgdfg\n\n\n\nergergergergerg\nergergergerg\n\n\nedrfgdfgdfg\n\n\n\nergergergergerg\nergergergerg\n\n\nedrfgdfgdfg\n\n\n\nergergergergerg\nergergergerg",
value: value:
"![img](https://img2.baidu.com/it/u=4025475678,645544065&fm=26&fmt=auto&gp=0.jpg)", "![file](https://img2.baidu.com/it/u=4025475678,645544065&fm=26&fmt=auto&gp=0.jpg '附件')\n[file](https://img2.baidu.com/it/u=4025475678,645544065&fm=26&fmt=auto&gp=0.jpg)",
value: "", // value: "[](http://www.baidu.com)",
disabled: false, disabled: false,
themeOptions: { themeOptions: {
dark: false, dark: false,
......
此差异已折叠。
...@@ -200,6 +200,37 @@ export default { ...@@ -200,6 +200,37 @@ export default {
const height = this.height; const height = this.height;
if (!height) return 0; if (!height) return 0;
return height - 83; return height - 83;
},
uploadImgCallBack() {
const _this = this;
return function({ url, file: { name } }) {
const originalText = _this.text;
const selectionInfo = _this.selectionInfo;
const newText = formatText(
originalText,
selectionInfo,
"\n![img](",
`${url} '${name}')\n`
);
_this.text = newText;
_this.$refs.mdUploadFile.value = "";
};
},
uploadFileCallBack() {
const _this = this;
return function({ url, file: { name } }) {
// url = "http://www.baidu.com";
const originalText = _this.text;
const selectionInfo = _this.selectionInfo;
const newText = formatText(
originalText,
selectionInfo,
"\n![file](",
`${url} '${name}')\n`
);
_this.text = newText;
_this.$refs.mdUploadFile.value = "";
};
} }
}, },
data() { data() {
...@@ -207,6 +238,7 @@ export default { ...@@ -207,6 +238,7 @@ export default {
fullScreen: false, fullScreen: false,
isFocus: false, isFocus: false,
showPreview: false, showPreview: false,
uploadType: "img",
fileList: [], fileList: [],
filteredTags: [], filteredTags: [],
text: "", text: "",
...@@ -312,29 +344,22 @@ export default { ...@@ -312,29 +344,22 @@ export default {
immediate: false, immediate: false,
deep: true, deep: true,
handler: function(val) { handler: function(val) {
const _this = this; const uploadType = this.uploadType;
if (!val.length) return; if (!val.length) return;
this.$emit("upload", { this.$emit("upload", {
val: val[0], val: val[0],
callback: function(url) { callback:
const originalText = _this.text; uploadType === "img"
const selectionInfo = _this.selectionInfo; ? this.uploadImgCallBack
const newText = formatText( : this.uploadFileCallBack
originalText,
selectionInfo,
"\n![img](",
`${url})\n`
);
_this.text = newText;
_this.$refs.mdUploadFile.value = "";
}
}); });
this.fileList = []; this.fileList = [];
} }
} }
}, },
methods: { methods: {
handleUpload() { handleUpload(type) {
this.uploadType = type;
this.$refs.mdUploadFile.click(); this.$refs.mdUploadFile.click();
document.getElementById(this.textareaId).focus(); document.getElementById(this.textareaId).focus();
}, },
...@@ -394,16 +419,14 @@ export default { ...@@ -394,16 +419,14 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.md_container { .md_container {
// width: 100%;
background: var(--md-editor-frame-bg-color); background: var(--md-editor-frame-bg-color);
// margin: 200px auto;
border: 1px solid var(--md-editor-border-color); border: 1px solid var(--md-editor-border-color);
border-radius: 4px; border-radius: 4px;
padding: 10px 16px; padding: 10px 16px;
box-sizing: border-box; box-sizing: border-box;
transition: border 0.3s; transition: border 0.3s;
position: relative; position: relative;
overflow: hidden; // overflow: hidden; // 注释为了显示@用户的弹窗
&.fullScreen { &.fullScreen {
position: fixed; position: fixed;
top: 0; top: 0;
......
import marked from "marked";
// 获取选中文本信息 // 获取选中文本信息
export function getSelectionInfo(selectorId) { export function getSelectionInfo(selectorId) {
...@@ -314,20 +315,19 @@ export function addLanguageClass(html) { ...@@ -314,20 +315,19 @@ export function addLanguageClass(html) {
}); });
return virtualDom; return virtualDom;
} }
export function getLinkTags(id, html) { export function getLinkTags(id, html) {
const virtualDom = document.createElement("div"); const virtualDom = document.createElement("div");
virtualDom.innerHTML = html; virtualDom.innerHTML = html;
const links = Array.from(virtualDom.querySelectorAll("a")).map( const links = Array.from(
(item, index) => { virtualDom.querySelectorAll("a:not([download])")
item.id = id + "_" + index; ).map((item, index) => {
return { item.id = id + "_" + index;
id: item.id, return {
title: item.innerText, id: item.id,
url: item.href title: item.innerText,
}; url: item.href
} };
); });
return { vDom: virtualDom, links }; return { vDom: virtualDom, links };
} }
...@@ -335,3 +335,34 @@ export function getLinkTitle(linkEl) { ...@@ -335,3 +335,34 @@ export function getLinkTitle(linkEl) {
const title = linkEl.innerText; const title = linkEl.innerText;
return /^http/.test(title) ? "" : title; return /^http/.test(title) ? "" : title;
} }
export function rerender() {
const renderer = {
image(href, title, text) {
if (href === null) {
return text;
}
// ![file](...)渲染文件,只可以下载
if (text === "file") {
return `<a href="${href}" class="md_file_card md_flex_card" download target="_blank">
<span class="md_file_img icon iconfont icon-doc"></span>
<span class="flex-1">
<span class="md_file_title">${title}</span>
<span class="md_file_desc">16.6KB</span>
</span>
<span class="md_file_controls">
<span class="md_file_download icon iconfont icon-xiazai"></span>
</span>
</a>`;
}
// ![img](...)渲染图片
let out = '<img src="' + href + '" alt="' + text + '"';
if (title) {
out += ' title="' + title + '"';
}
out += "/>";
return out;
}
};
marked.use({ renderer });
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
box-sizing: border-box; box-sizing: border-box;
border-radius: 4px; border-radius: 4px;
border: 1px solid var(--md-editor-border-color); border: 1px solid var(--md-editor-border-color);
background: #f5f6f7; background: #f5f7fa;
transition: border 0.3s; transition: border 0.3s;
max-width: 800px; max-width: 800px;
&:hover { &:hover {
...@@ -46,3 +46,56 @@ ...@@ -46,3 +46,56 @@
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
} }
.md_file_card {
display: block;
padding: 10px 16px;
box-sizing: border-box;
border-radius: 4px;
border: 1px solid var(--md-editor-border-color);
background: #f5f7fa;
transition: border 0.3s;
max-width: 600px;
&:hover {
border: 1px solid var(--md-editor-border-color-active);
}
span {
color: var(--md-editor-text-color-active);
}
.md_file_img {
font-size: 36px;
margin-right: 16px;
color: var(--md-editor-text-color);
}
.md_file_download {
font-size: 16px;
padding: 8px;
box-sizing: border-box;
border: 1px solid var(--md-editor-border-color);
border-radius: 50%;
cursor: pointer;
transition: color 0.3s;
&:hover {
color: var(--md-editor-border-color-active);
}
}
.md_file_title {
font-size: 14px;
line-height: 26px;
font-weight: 500;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.md_file_desc {
font-size: 12px;
line-height: 20px;
color: var(--md-editor-text-color);
line-height: 20px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
}
@font-face { @font-face {
font-family: "iconfont"; /* Project id */ font-family: "iconfont"; /* Project id */
src: url('font/iconfont.ttf?t=1626660749010') format('truetype'); src: url("font/iconfont.ttf?t=1626660749010") format("truetype");
} }
.iconfont { .iconfont {
...@@ -107,3 +107,14 @@ ...@@ -107,3 +107,14 @@
content: "\e503"; content: "\e503";
} }
.icon-wenjian:before {
content: "\e607";
}
.icon-doc:before {
content: "\e642";
}
.icon-xiazai:before {
content: "\e6be";
}
...@@ -43,8 +43,8 @@ export default { ...@@ -43,8 +43,8 @@ export default {
position: { position: {
immediate: true, immediate: true,
handler: function({ left, top }) { handler: function({ left, top }) {
this.left = left + 14; this.left = left + 12;
this.top = top + 20; this.top = top + 40;
} }
} }
}, },
...@@ -63,9 +63,7 @@ export default { ...@@ -63,9 +63,7 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.md_select_container { .md_select_container {
position: relative; position: absolute;
position: fixed;
background: #fff; background: #fff;
box-shadow: 0 1px 6px rgb(0 0 0 / 10%); box-shadow: 0 1px 6px rgb(0 0 0 / 10%);
border: 1px solid var(--md-editor-border-color); border: 1px solid var(--md-editor-border-color);
......
...@@ -53,6 +53,7 @@ import { ...@@ -53,6 +53,7 @@ import {
getFilteredTags, getFilteredTags,
getLinkTags, getLinkTags,
formatText, formatText,
rerender,
addLanguageClass, addLanguageClass,
throttle as throttleFn throttle as throttleFn
} from "@/assets/js/utils"; } from "@/assets/js/utils";
...@@ -156,6 +157,8 @@ export default { ...@@ -156,6 +157,8 @@ export default {
handler: function(val) { handler: function(val) {
if (val) { if (val) {
this.resetPreviewMinHeight(); this.resetPreviewMinHeight();
} else {
this.showSelectUser = false;
} }
} }
}, },
...@@ -227,6 +230,7 @@ export default { ...@@ -227,6 +230,7 @@ export default {
}; };
}, },
transferMarkdown(val) { transferMarkdown(val) {
rerender();
marked.setOptions({ marked.setOptions({
breaks: true, breaks: true,
gfm: true, gfm: true,
...@@ -267,7 +271,6 @@ export default { ...@@ -267,7 +271,6 @@ export default {
selectUser(user) { selectUser(user) {
const originalText = this.textContent; const originalText = this.textContent;
const queryInfo = this.queryInfo; const queryInfo = this.queryInfo;
console.log(queryInfo);
const cursorPosition = getPosition(this.id); const cursorPosition = getPosition(this.id);
const username = user.name + " "; const username = user.name + " ";
const newText = const newText =
...@@ -296,6 +299,7 @@ export default { ...@@ -296,6 +299,7 @@ export default {
this.showSelectUser = false; this.showSelectUser = false;
return; return;
} }
this.queryInfo.keyWord = keyWord; this.queryInfo.keyWord = keyWord;
this.$emit("queryUserList", keyWord); this.$emit("queryUserList", keyWord);
}, },
...@@ -313,7 +317,7 @@ export default { ...@@ -313,7 +317,7 @@ export default {
const originalText = this.textContent; const originalText = this.textContent;
const cursorPoint = getPosition(this.id); const cursorPoint = getPosition(this.id);
const selectionInfo = { const selectionInfo = {
selectionStart: cursorPoint - 1, selectionStart: cursorPoint,
selectionEnd: cursorPoint selectionEnd: cursorPoint
}; };
const newText = formatText( const newText = formatText(
...@@ -337,8 +341,10 @@ export default { ...@@ -337,8 +341,10 @@ export default {
hideEl.scrollTop = scrollTop; hideEl.scrollTop = scrollTop;
const pEl = document.getElementById("call_position"); const pEl = document.getElementById("call_position");
this.selectUserPosition = { this.selectUserPosition = {
left: pEl.getBoundingClientRect().left, left: pEl.offsetLeft,
top: pEl.getBoundingClientRect().top top: pEl.offsetTop - textEl.scrollTop
// left: pEl.getBoundingClientRect().left,
// top: pEl.getBoundingClientRect().top
}; };
textEl.parentNode.removeChild(hideEl); textEl.parentNode.removeChild(hideEl);
this.showSelectUser = true; this.showSelectUser = true;
...@@ -472,7 +478,7 @@ export default { ...@@ -472,7 +478,7 @@ export default {
height: var(--md-editor-height); height: var(--md-editor-height);
resize: none; resize: none;
font-size: 14px; font-size: 14px;
line-height: 18px; line-height: 1.625;
word-break: break-all; word-break: break-all;
font-family: "Menlo", -apple-system, SF UI Text, Arial, PingFang SC, font-family: "Menlo", -apple-system, SF UI Text, Arial, PingFang SC,
Hiragino Sans GB, Microsoft YaHei, WenQuanYi Micro Hei, sans-serif, SimHei, Hiragino Sans GB, Microsoft YaHei, WenQuanYi Micro Hei, sans-serif, SimHei,
......
...@@ -158,8 +158,11 @@ export default { ...@@ -158,8 +158,11 @@ export default {
this.$emit("updateText", { startStr: `\n${ulNum++}. `, endStr: "" }); this.$emit("updateText", { startStr: `\n${ulNum++}. `, endStr: "" });
this.$emit("update:ulNum", ulNum); this.$emit("update:ulNum", ulNum);
break; break;
case "img":
this.$emit("upload", "img");
break;
case "file": case "file":
this.$emit("upload"); this.$emit("upload", "file");
break; break;
case "fullScreen": case "fullScreen":
this.$emit("setFullScreen", true); this.$emit("setFullScreen", true);
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
:fullScreen="fullScreen" :fullScreen="fullScreen"
@setFullScreen="$emit('update:fullScreen', $event)" @setFullScreen="$emit('update:fullScreen', $event)"
@updateText="handleUpdateText" @updateText="handleUpdateText"
@upload="$emit('upload')" @upload="$emit('upload', $event)"
@setFormatType="setFormatType" @setFormatType="setFormatType"
@updateShowHelp="$emit('updateShowHelp', $event)" @updateShowHelp="$emit('updateShowHelp', $event)"
:class="{ active: item.name === 'format' && formatType }" :class="{ active: item.name === 'format' && formatType }"
...@@ -224,12 +224,19 @@ export default { ...@@ -224,12 +224,19 @@ export default {
endStr: "" endStr: ""
}, },
{ {
name: "file", name: "img",
icon: "tupian", icon: "tupian",
tip: "上传图片", tip: "上传图片",
startStr: "", startStr: "",
endStr: "" endStr: ""
}, },
{
name: "file",
icon: "wenjian",
tip: "上传附件",
startStr: "",
endStr: ""
},
{ {
name: "task", name: "task",
icon: "renwu", icon: "renwu",
......
...@@ -106,8 +106,13 @@ function initMdEditor(obj) { ...@@ -106,8 +106,13 @@ function initMdEditor(obj) {
onSubmit(val); onSubmit(val);
}, },
upload({ val, callback }) { upload({ val, callback }) {
console.log(val);
onUpload(val, function(res) { onUpload(val, function(res) {
callback(res); callback({
url: res,
file: val
});
}); });
}, },
renderLinks({ links, callback }) { renderLinks({ links, callback }) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册