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

feat:添加附件解析器

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