Markdown的烦心事

ATSAST开发中,我们多处用到了Markdown语法来制作,但是这其中也存在不少问题。

昨晚在上线新的markdown编辑器后,我遇到了尴尬一幕,编辑器乱码了?查阅发现,原先这个编辑器是一个代码块,里面填写了HTML代码,原来如此,markdown支持HTML代码,因而HTML代码串了。style之类的都是body的,就应用全局了。

那么怎么解决才好?对于编辑来说,一边是CodeMirror一边是VSCode,不影响使用。但是显示的时候就会有一大堆问题。查阅资料,发现我们使用的marked.js提供了sanitize选项,可以指定一个函数去做清洁工作,删除不允许的代码,剩下的代码就会直接转成markdown啦!

使用也不难,直接:

marked(DOMPurify.sanitize(dirty))

就好啦,但是尴尬的是,我发现我们使用的Markdown可视化编辑器预览也有问题,怎么办?

于是我打开源代码,在中间部分,可以清楚发现toolbar定义中如下代码:

	"preview": {
		name: "preview",
		action: togglePreview,
		className: "fa fa-eye no-disable",
		title: "Toggle Preview",
		default: true
	},

其中togglePreview应该就是了吧?

/**
 * Preview action.
 */
function togglePreview(editor) {
	var cm = editor.codemirror;
	var wrapper = cm.getWrapperElement();
	var toolbar_div = wrapper.previousSibling;
	var toolbar = editor.options.toolbar ? editor.toolbarElements.preview : false;
	var preview = wrapper.lastChild;
	if(!preview || !/editor-preview/.test(preview.className)) {
		preview = document.createElement("div");
		preview.className = "editor-preview";
		wrapper.appendChild(preview);
	}
	if(/editor-preview-active/.test(preview.className)) {
		preview.className = preview.className.replace(
			/\s*editor-preview-active\s*/g, ""
		);
		if(toolbar) {
			toolbar.className = toolbar.className.replace(/\s*active\s*/g, "");
			toolbar_div.className = toolbar_div.className.replace(/\s*disabled-for-preview*/g, "");
		}
	} else {
		// When the preview button is clicked for the first time,
		// give some time for the transition from editor.css to fire and the view to slide from right to left,
		// instead of just appearing.
		setTimeout(function() {
			preview.className += " editor-preview-active";
		}, 1);
		if(toolbar) {
			toolbar.className += " active";
			toolbar_div.className += " disabled-for-preview";
		}
	}
	preview.innerHTML = editor.options.previewRender(editor.value(), preview);

	// Turn off side by side if needed
	var sidebyside = cm.getWrapperElement().nextSibling;
	if(/editor-preview-active-side/.test(sidebyside.className))
		toggleSideBySide(editor);
}

这里的preview.innerHTML = editor.options.previewRender(editor.value(), preview);就是核心代码啦!那么我们再看看previewRender函数:

	// Add default preview rendering function
	if(!options.previewRender) {
		options.previewRender = function(plainText) {
			// Note: "this" refers to the options object
			return this.parent.markdown(plainText);
		};
	}

这里,我们只要改成return this.parent.markdown(DOMPurify.sanitize(plainText));,就大功告成啦!

真的吗?

事情没这么简单……

欲知后事如何,参见Markdown的烦心事(续)

只有 1 条评论, 不如再加一个评论?

留下你的评论呗...

电子邮件地址不会被公开。 必填项已用*标注