202 lines
5.4 KiB
JavaScript
202 lines
5.4 KiB
JavaScript
import {Marked} from 'marked';
|
||
import hljs from 'highlight.js';
|
||
import markedFootnote from 'marked-footnote'
|
||
import markedCodeFormat from 'marked-code-format'
|
||
import { markedEmoji } from 'marked-emoji';
|
||
|
||
postMessage({
|
||
type: 'init',
|
||
data: 'Hello World!'
|
||
})
|
||
|
||
|
||
// 默认编辑器配置
|
||
const defaoltMarkOption = {
|
||
async: true, // 同步编译
|
||
pedantic: false,
|
||
gfm: true,
|
||
silent: true, // 输出错误
|
||
breaks: false, // 将回车编程<br/>
|
||
}
|
||
|
||
// 自定义行号注入函数
|
||
const injectLineNumbers = (highlightedCode) => {
|
||
const lines = highlightedCode.split('\n')
|
||
|
||
// 移除最后一行空行(常见于代码块末尾的换行)
|
||
if (lines[lines.length - 1] === '') lines.pop()
|
||
|
||
// 为每行添加行号容器
|
||
return lines.map((line, index) => `<div class="code-line"><span class="line-number">${index + 1}</span><span class="line-content">${line}</span></div>`).join('')
|
||
}
|
||
|
||
// 编辑器render配置
|
||
const editorRenderOption = {
|
||
space: (...args) => {
|
||
console.log(args, 'space')
|
||
return `<div>space</div>`
|
||
},
|
||
code: (...args) => {
|
||
console.log(args, 'code')
|
||
return `<div>xscode</div>`
|
||
},
|
||
blockquote: (...args) => {
|
||
console.log(args, 'blockquote')
|
||
return `<div>blockquote</div>`
|
||
},
|
||
html: (...args) => {
|
||
console.log(args, 'html')
|
||
return `<div>html</div>`
|
||
},
|
||
heading: (...args) => {
|
||
console.log(args[0], 'heading')
|
||
return `<h${args[0].depth}>${args[0].raw}</h${args[0].depth}>`
|
||
},
|
||
hr: (...args) => {
|
||
console.log(args, 'hr')
|
||
return `<div>hr</div>`
|
||
},
|
||
list: (...args) => {
|
||
console.log(args, 'list')
|
||
return `<div>list</div>`
|
||
},
|
||
listitem: (...args) => {
|
||
console.log(args, 'listitem')
|
||
return `<div>listitem</div>`
|
||
},
|
||
checkbox: (...args) => {
|
||
console.log(args, 'checkbox')
|
||
return `<div>checkbox</div>`
|
||
},
|
||
paragraph: (...args) => {
|
||
console.log(args, 'paragraph')
|
||
return `<div>${args[0].raw}</div>`
|
||
},
|
||
table: (...args) => {
|
||
console.log(args, 'table')
|
||
return `<div>table</div>`
|
||
},
|
||
tablerow: (...args) => {
|
||
console.log(args, 'tablerow')
|
||
return `<div>tablerow</div>`
|
||
},
|
||
tablecell: (...args) => {
|
||
console.log(args, 'tablecell')
|
||
return `<div>tablecell</div>`
|
||
},
|
||
strong: (...args) => {
|
||
console.log(args, 'strong')
|
||
return `<div>strong</div>`
|
||
},
|
||
em: (...args) => {
|
||
console.log(args, 'em')
|
||
return `<div>em</div>`
|
||
},
|
||
codespan: (...args) => {
|
||
console.log(args, 'codespan')
|
||
return `<div>codespan</div>`
|
||
},
|
||
br: (...args) => {
|
||
console.log(args, 'br')
|
||
return `<div>br</div>`
|
||
},
|
||
del: (...args) => {
|
||
console.log(args, 'del')
|
||
return `<div>del</div>`
|
||
},
|
||
link: (...args) => {
|
||
console.log(args, 'link')
|
||
return `<div>link</div>`
|
||
},
|
||
image: (...args) => {
|
||
console.log(args, 'image')
|
||
return `<div>image</div>`
|
||
},
|
||
text: (...args) => {
|
||
console.log(args, 'text')
|
||
return `<div>text</div>`
|
||
},
|
||
}
|
||
// 显示器render配置
|
||
const viewerRenderOption = {
|
||
code: ({text, lang}) => {
|
||
// console.log(text);
|
||
const validLang = hljs.getLanguage(lang) ? lang : 'plaintext'
|
||
const highlighted = hljs.highlight(text, {language: lang}).value
|
||
// console.log(highlighted)
|
||
const withLineNumbers = injectLineNumbers(highlighted)
|
||
return `<pre class="hljs ${validLang}"><code>${withLineNumbers}</code></pre>`;
|
||
}
|
||
}
|
||
|
||
|
||
// 编辑器Marked编译器
|
||
const editorMarked = new Marked({
|
||
...defaoltMarkOption,
|
||
renderer: editorRenderOption
|
||
});
|
||
// 显示器Marked编译器
|
||
const viewerMarked = new Marked({
|
||
...defaoltMarkOption,
|
||
renderer: viewerRenderOption
|
||
});
|
||
|
||
|
||
// 编辑器插件
|
||
editorMarked.use(markedCodeFormat()).use()
|
||
|
||
// 显示器插件
|
||
// 自定义表情快速插入
|
||
const markedEmojiOptions = {
|
||
emojis: {
|
||
"heart": "❤️",
|
||
"tada": "🎉"
|
||
},
|
||
renderer: (token) => {
|
||
console.log(token)
|
||
return token.emoji
|
||
}
|
||
};
|
||
// 支持脚注[^1] 会影响原始文本
|
||
viewerMarked.use(markedFootnote()).use(markedCodeFormat()).use(markedEmoji(markedEmojiOptions))
|
||
|
||
addEventListener('message', async (e) => {
|
||
console.log(e.data)
|
||
switch (e.data.type) {
|
||
case 'render': {
|
||
// const editContent = await makeEditContent(e.data.content)
|
||
const viewContent = await makeViewContent(e.data.content)
|
||
postMessage({
|
||
type: 'render',
|
||
content: {
|
||
viewContent,
|
||
// editContent,
|
||
},
|
||
})
|
||
break;
|
||
}
|
||
}
|
||
})
|
||
|
||
|
||
|
||
// 函数
|
||
|
||
// 使用编译
|
||
async function makeEditContent(contents){
|
||
// 去除html innerText两端的空格,将 转化为空格
|
||
let content = contents.trim().replace(/ /g, ' ');
|
||
// 过滤不能识别,难识别的字符,空字符
|
||
content = content.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/,"");
|
||
// 编译
|
||
content = await editorMarked.parse(content)
|
||
return content
|
||
}
|
||
async function makeViewContent(contents){
|
||
// 过滤不能识别,难识别的字符,空字符
|
||
let content = contents.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/,"");
|
||
// 编译
|
||
content = await viewerMarked.parse(content)
|
||
return content
|
||
}
|