如何配置TinyMCE保留内联样式中的大写值
TinyMCE内联样式大写保留通用解决方案
TinyMCE默认会在解析、序列化内容的阶段对CSS属性和值做标准化小写处理,没有提供全局开关直接关闭这个行为,但可以通过官方开放的扩展钩子实现全场景的大写保留,不需要在存库环节做正则替换。
方案1:序列化/解析双钩子拦截(推荐,全场景通用)
该方案兼容TinyMCE 5/6/7全版本,不需要修改框架源码,也不需要针对特定样式键值写静态规则,所有自定义占位符的原始大小写都会被自动保留,同时不影响框架默认的XSS清洗、标准CSS校验逻辑。
初始化编辑器时直接加入以下配置即可:
tinymce.init({ // 替换为项目原有配置,比如selector、toolbar、plugins等 setup: (editor) => { editor.on('PreInit', () => { // 缓存原生CSS解析、序列化方法 const originalParseCss = editor.parser.parseCss; const originalSerializeCss = editor.serializer.serializeCss; // 匹配需要保留大小写的自定义占位符规则,可根据业务场景调整正则 const placeholderReg = /\[([A-Za-z0-9_.]+)\]/g; // 拦截CSS解析流程(加载/粘贴内容时触发) editor.parser.parseCss = function(cssContent) { const placeholderStore = []; // 临时替换占位符为不会被转小写的标记 const protectedCss = cssContent.replace(placeholderReg, (match) => { placeholderStore.push(match); return `%%TINY_MCE_PH_${placeholderStore.length - 1}%%`; }); // 走原生解析逻辑 const parseResult = originalParseCss.call(this, protectedCss); // 还原占位符,保留原始大小写 Object.keys(parseResult).forEach((prop) => { if (typeof parseResult[prop] === 'string') { parseResult[prop] = parseResult[prop].replace(/%%TINY_MCE_PH_(\d+)%%/g, (_, idx) => { return placeholderStore[Number(idx)]; }); } }); return parseResult; }; // 拦截CSS序列化流程(输出内容时触发) editor.serializer.serializeCss = function(stylesMap) { const placeholderStore = []; const protectedStyles = {}; Object.keys(stylesMap).forEach((prop) => { const value = stylesMap[prop]; if (typeof value === 'string' && placeholderReg.test(value)) { placeholderStore.length = 0; protectedStyles[prop] = value.replace(placeholderReg, (match) => { placeholderStore.push(match); return `%%TINY_MCE_PH_${placeholderStore.length - 1}%%`; }); } else { protectedStyles[prop] = value; } }); // 走原生序列化逻辑 let serializeResult = originalSerializeCss.call(this, protectedStyles); // 还原占位符 serializeResult = serializeResult.replace(/%%TINY_MCE_PH_(\d+)%%/g, (_, idx) => { return placeholderStore[Number(idx)]; }); return serializeResult; }; }); } });
如果自定义值不是[Xxx.Yyy]格式,只要修改代码里的placeholderReg正则适配业务规则即可。
方案2:固定样式白名单配置(仅适用于少量固定场景)
如果只需要用到固定的几个标准CSS属性,没有动态自定义值的需求,可以通过配置样式白名单减少强制转换的触发概率:
tinymce.init({ // 原有配置... keep_styles: true, // 把项目里会用到的所有标准CSS属性列在对应标签下,*代表匹配所有标签 valid_styles: { '*': 'height,width,border,background-color,color,font-size,margin,padding,text-align' } });
注意:这个方案对动态自定义占位符的大小写保留效果不稳定,动态场景优先选择方案1。
不建议使用存库前正则转大写的临时方案:该方案会误把内容里本身就是小写的同名普通文本转成大写,后续新增自定义值格式时需要不断修改正则,维护成本极高。
内容的提问来源于stack exchange,提问作者Hguedez
相关产品推荐
相关产品推荐

