You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:09:12