@vuux/editor
Version:
Vue Nuxt 富文本编辑器
174 lines (173 loc) • 6.71 kB
JavaScript
import { _getDefaults as m } from "./defaults.mjs";
import { _Lexer as h } from "./Lexer.mjs";
import { _Parser as p } from "./Parser.mjs";
import { _Hooks as u } from "./Hooks.mjs";
import { _Renderer as d } from "./Renderer.mjs";
import { _Tokenizer as T } from "./Tokenizer.mjs";
import { _TextRenderer as w } from "./TextRenderer.mjs";
import { escape as x } from "./helpers.mjs";
class H {
defaults = m();
options = this.setOptions;
parse = this.parseMarkdown(!0);
parseInline = this.parseMarkdown(!1);
Parser = p;
Renderer = d;
TextRenderer = w;
Lexer = h;
Tokenizer = T;
Hooks = u;
constructor(...l) {
this.use(...l);
}
walkTokens(l, r) {
let o = [];
for (const n of l)
switch (o = o.concat(r.call(this, n)), n.type) {
case "table": {
const e = n;
for (const s of e.header)
o = o.concat(this.walkTokens(s.tokens, r));
for (const s of e.rows)
for (const t of s)
o = o.concat(this.walkTokens(t.tokens, r));
break;
}
case "list": {
const e = n;
o = o.concat(this.walkTokens(e.items, r));
break;
}
default: {
const e = n;
if (this.defaults.extensions?.childTokens?.[e.type])
for (const s of this.defaults.extensions.childTokens[e.type]) {
const t = e[s].flat(1 / 0);
o = o.concat(this.walkTokens(t, r));
}
else e.tokens && (o = o.concat(this.walkTokens(e.tokens, r)));
}
}
return o;
}
use(...l) {
const r = this.defaults.extensions || { renderers: {}, childTokens: {} };
for (const o of l) {
const n = { ...o };
if (n.async = this.defaults.async || n.async || !1, o.extensions) {
for (const e of o.extensions) {
if (e.name || console.error("需要扩展名"), "renderer" in e) {
const s = r.renderers[e.name];
s ? r.renderers[e.name] = function(...t) {
let i = e.renderer.apply(this, t);
return i === !1 && (i = s.apply(this, t)), i;
} : r.renderers[e.name] = e.renderer;
}
if ("tokenizer" in e) {
(!e.level || e.level !== "block" && e.level !== "inline") && console.error("扩展级别必须为block或inline");
const s = r[e.level];
s ? s.unshift(e.tokenizer) : r[e.level] = [e.tokenizer], e.start && (e.level === "block" ? r.startBlock ? r.startBlock.push(e.start) : r.startBlock = [e.start] : e.level === "inline" && (r.startInline ? r.startInline.push(e.start) : r.startInline = [e.start]));
}
"childTokens" in e && e.childTokens && (r.childTokens[e.name] = e.childTokens);
}
n.extensions = r;
}
if (o.renderer) {
const e = this.defaults.renderer || new d(this.defaults);
for (const s in o.renderer) {
if (s in e || console.error(`渲染器'${s}'不存在`), ["options", "parser"].includes(s))
continue;
const t = s, i = o.renderer[t], f = e[t];
e[t] = (...k) => {
let a = i.apply(e, k);
return a === !1 && (a = f.apply(e, k)), a || "";
};
}
n.renderer = e;
}
if (o.tokenizer) {
const e = this.defaults.tokenizer || new T(this.defaults);
for (const s in o.tokenizer) {
if (s in e || console.error(`标记器'${s}'不存在`), ["options", "rules", "lexer"].includes(s))
continue;
const t = s, i = o.tokenizer[t], f = e[t];
e[t] = (...k) => {
let a = i.apply(e, k);
return a === !1 && (a = f.apply(e, k)), a;
};
}
n.tokenizer = e;
}
if (o.hooks) {
const e = this.defaults.hooks || new u();
for (const s in o.hooks) {
if (s in e || console.error(`钩子'${s}'不存在`), ["options", "block"].includes(s))
continue;
const t = s, i = o.hooks[t], f = e[t];
u.passThroughHooks.has(s) ? e[t] = (k) => {
if (this.defaults.async && u.passThroughHooksRespectAsync.has(s))
return Promise.resolve(i.call(e, k)).then((c) => f.call(e, c));
const a = i.call(e, k);
return f.call(e, a);
} : e[t] = (...k) => {
let a = i.apply(e, k);
return a === !1 && (a = f.apply(e, k)), a;
};
}
n.hooks = e;
}
if (o.walkTokens) {
const e = this.defaults.walkTokens, s = o.walkTokens;
n.walkTokens = function(t) {
let i = [];
return i.push(s.call(this, t)), e && (i = i.concat(e.call(this, t))), i;
};
}
this.defaults = { ...this.defaults, ...n };
}
return this;
}
setOptions(l) {
return this.defaults = { ...this.defaults, ...l }, this;
}
lexer(l, r) {
return h.lex(l, r ?? this.defaults);
}
parser(l, r) {
return p.parse(l, r ?? this.defaults);
}
parseMarkdown(l) {
return (o, n) => {
const e = { ...n }, s = { ...this.defaults, ...e }, t = this.onError(!!s.silent, !!s.async);
if (this.defaults.async === !0 && e.async === !1)
return t(new Error("marked():异步选项被扩展设置为true"));
if (typeof o > "u" || o === null)
return t(new Error("marked():输入参数未定义或为空"));
if (typeof o != "string")
return t(new Error("marked():输入参数为类型" + Object.prototype.toString.call(o) + "字符串"));
s.hooks && (s.hooks.options = s, s.hooks.block = l);
const i = s.hooks ? s.hooks.provideLexer() : l ? h.lex : h.lexInline, f = s.hooks ? s.hooks.provideParser() : l ? p.parse : p.parseInline;
if (s.async)
return Promise.resolve(s.hooks ? s.hooks.preprocess(o) : o).then((c) => i(c, s)).then((c) => s.hooks ? s.hooks.processAllTokens(c) : c).then((c) => s.walkTokens ? Promise.all(this.walkTokens(c, s.walkTokens)).then(() => c) : c).then((c) => f(c, s)).then((c) => s.hooks ? s.hooks.postprocess(c) : c).catch(t);
s.hooks && (o = s.hooks.preprocess(o));
let k = i(o, s);
s.hooks && (k = s.hooks.processAllTokens(k)), s.walkTokens && this.walkTokens(k, s.walkTokens);
let a = f(k, s);
return s.hooks && (a = s.hooks.postprocess(a)), a;
};
}
onError(l, r) {
return (o) => {
if (o.message += "请将此报告至https://www.usuuu.com", l) {
const n = "<p>发生错误:</p><pre>" + x(o.message + "", !0) + "</pre>";
return r ? Promise.resolve(n) : n;
}
if (r)
return Promise.reject(o);
throw o;
};
}
}
export {
H as Marked
};