🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

gjs-email-editor

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gjs-email-editor

基于 [GrapesJS](https://grapesjs.com/) 框架及其插件 [preset-newsletter](https://github.com/GrapesJS/preset-newsletter) 二次开发的邮件编辑器

1.0.26
latest
npm
Version published
Weekly downloads
0
-100%
Maintainers
1
Weekly downloads
 
Created
Source

gjs-email-editor

基于 GrapesJS 框架及其插件 preset-newsletter 二次开发的邮件编辑器

GrapesJS 是一个开源的 HTML 编辑器,通过低代码的形式,快速创建 HTML / Email 代码来使用,有很不错的扩展性,开发者可以在 GrapesJS 核心功能上自定义自己的编辑器

官方已经提供了不少的插件,详情列表可参考:https://github.com/GrapesJS/grapesjs#plugins 。可以重点关注下面三个插件:

GrapesJS 提供了不少的组件和 API,但是要组件成型的编辑器还是要花不少的功夫的(参考官方教程 getting-started),上面三个插件类似于 脚手架,帮你完成了初始的编辑器模型。

而这个仓库就是基于 grapesjs-preset-newsletter 的基础上,再进行二次开发的。

npm地址:https://www.npmjs.com/package/gjs-email-editor

学习建议

官方的学习文档:https://grapesjs.com/docs/ ,以及 API介绍:https://grapesjs.com/docs/api/ ,基本能掌握 GrapesJS 的使用

之后阅读 https://github.com/GrapesJS/preset-newsletter 的源码(也很简单,几百行代码而已),基本就能自己进行二次开发了

注意事项

Ckeditor 插件接入

官网提供了 ckeditor 编辑器的插件:ckeditor

使用的 ckeditor 的 v4 版本,不支持 import 的方式,需要在入口 html 加入 ckeditor 链接,参考如下 https://github.com/cody1991/gjs-email-editor/blob/master/vite.config.js#L7-L14

const htmlPluginConfig = htmlConfig({
  headScripts: [
    {
      src: 'https://grapesjs.com/js/ckeditor/ckeditor.js',
    },
    'CKEDITOR.dtd.$editable.td = 1;',
  ],
});

TD 支持编辑

TD 元素本身是不支持编辑的,所以进行了以下的改造,具体代码在:https://github.com/cody1991/gjs-email-editor/blob/master/src/email-editor/index.ts#L55-L83

GrapesJS 的 issues 也有几个相关的提问,比如 https://github.com/GrapesJS/grapesjs/issues/1262 ,可做参考

editor.Components.addType('cell', {
    isComponent(el) {
      if (!(['td', 'th'].indexOf(el.tagName?.toLowerCase()) >= 0)) {
        return false;
      }

      const allChildNodes: Node[] = [];
      function collectChildNodes(arr: Node) {
        const { childNodes } = arr;
        if (childNodes.length > 0) {
          for (let index = 0; index < childNodes.length; index += 1) {
            const arrayChildNode = childNodes[index];
            if (arrayChildNode.childNodes?.length > 0) {
              collectChildNodes(arrayChildNode);
            } else {
              allChildNodes.push(arrayChildNode);
            }
          }
        } else {
          allChildNodes.push(arr);
        }
      }
      collectChildNodes(el);

      return !allChildNodes.every(
        (item) => item.nodeType === 3 || item.nodeName?.toLowerCase() === 'br',
      );
    },
  });

这里修改了 CellisComponent 定义,循环遍历收集了 TD 内部的所有的子节点,最终判断全部都是文本节点或者 br 元素的时候,就不认定为 TD 元素,而认为是一个文本组件。那么就可以支持编辑了

自定义样式

编辑器部分内容是嵌到 iframe 内部的,所以在外部我们无法方便的调整样式,可以参考这里的代码 https://github.com/cody1991/gjs-email-editor/blob/master/src/App.jsx#L25-L32

canvasCss: `
  .gjs-selected {
    outline: 2px solid #14CC97 !important;
  }
  .gjs-dashed *[data-gjs-highlightable] {
    outline: 1px dashed #14CC97;
  }
`,

配置 canvasCss,加入自定义的 CSS 代码,最终会插入到编辑器 iframe 的头部 style 标签内

GrapesJS 本身可提供配置项挺多的,但是官方文档并没有列出来,只能自己看看源码了,幸运的是他们的注释很详细

多语言支持

框架对于多语言的说明并不多,这个也是看了源码之后才了解了如何配置,具体可以参考文件:https://github.com/cody1991/gjs-email-editor/blob/master/src/email-editor/locale/zh.ts

export default {
  'gjs-email-editor': {
    blocks: {
      names: {
        placeholder: '占位符',
        wrapper: '背景板',
        '1 Section': '排版',
        '1/2 Section': '1/2排版',
        '1/3 Section': '1/3排版',
        '3/7 Section': '3/7排版',
        Button: '按钮',
        Divider: '分隔线',
        Text: '文字',
        'Text Section': '文字块',
        Image: '图片',
        Quote: '引用',
        Link: '链接',
        'Link Block': '链接块',
        'Grid Items': '网格项',
        'List Items': '列表项',
      },
    },
  },
  styleManager: {
    properties: {
      margin: '外边距',
      'margin-top-sub': '上',
      'margin-right-sub': '右',
      'margin-bottom-sub': '下',
      'margin-left-sub': '左',

      padding: '内边距',
      'padding-top-sub': '上',
      'padding-right-sub': '右',
      'padding-bottom-sub': '下',
      'padding-left-sub': '左',

      'text-shadow-h': 'X',
      'text-shadow-v': 'Y',

      'text-shadow-blur': '模糊半径',
      'text-shadow-color': '颜色',

      'box-shadow-h': 'X',
      'box-shadow-v': 'Y',
      'box-shadow-blur': '模糊半径',
      'box-shadow-spread': '扩展半径',
      'box-shadow-color': '颜色',
      'box-shadow-type': '类型',

      'border-width-sub': '宽度',
      'border-style-sub': '样式',
      'border-color-sub': '颜色',
      'border-top-left-radius-sub': '左上',
      'border-top-right-radius-sub': '右上',
      'border-bottom-right-radius-sub': '右下',
      'border-bottom-left-radius-sub': '左下',

      'transform-rotate-x': 'Rotate X',
      'transform-rotate-y': 'Rotate Y',
      'transform-rotate-z': 'Rotate Z',
      'transform-scale-x': 'Scale X',
      'transform-scale-y': 'Scale Y',
      'transform-scale-z': 'Scale Z',

      'transition-property-sub': '属性',
      'transition-duration-sub': '间隔',
      'transition-timing-function-sub': '时间',

      'background-image-sub': '图片',
      'background-repeat-sub': '重复',
      'background-position-sub': '位置',
      'background-attachment-sub': '附件',
      'background-size-sub': '尺寸',

      'width-sub': '宽度',
      'height-sub': '高度',
      'max-width-sub': '最大宽度',
      'min-height-sub': '最小高度',
      width: '宽度',
      height: '高度',
      'max-width': '最大宽度',
      'min-height': '最小高度',

      'font-family': '字型',
      'font-size': '字体大小',
      'font-weight': '字体粗细',
      color: '颜色',
      'letter-spacing': '字体间隙',
      'line-height': '行高',
      'text-align': '文字排列',
      'text-decoration': '文字装饰',
      'font-style': '文字样式',
      'vertical-align': '垂直对齐方式',
      'text-shadow': '文字阴影',

      background: '背景',

      'background-color': '背景颜色',
      'border-collapse': '边框折叠',
      'border-radius': '边框圆角',
      border: '边框',
    },
  },
};

styleManager 中有我们常用需要配置的一些属性,需要给他们配置多语言,比如给 padding 配置,除了外围的 padding 需要配置,上下左右属性也要有对应的文案配置,key 值最后需要加上 -sub

padding: '内边距',
'padding-top-sub': '上',
'padding-right-sub': '右',
'padding-bottom-sub': '下',
'padding-left-sub': '左',

image

颜色选择器错位问题

Color picker displays wrong position

参考:https://github.com/GrapesJS/grapesjs/issues/596#issuecomment-415044955

项目中也加入了下面的配置:https://github.com/cody1991/gjs-email-editor/blob/master/src/App.jsx#L33-L36

colorPicker: {
  appendTo: 'parent',
  offset: { top: 26, left: -166 },
},

参考线错位问题

BUG: Block Highlight Display Bug

参考:https://github.com/GrapesJS/grapesjs/issues/3063

如果编辑器所在的页面超过一屏,滚动的时候可能会导致参考线错位,我们可以指定 listenToEl 属性,那么当指定的元素发生滚动的时候,画布会整体 resize,纠正 参考线错位 错位问题

自定义上传

这个也是直接看源码知道了使用方法的:https://github.com/GrapesJS/grapesjs/blob/6184b6c86c92af2cc30fe79665351747b346bfa2/src/asset_manager/config/config.ts

assetManager: {
  uploadFile: (param: any) => {
    const files = param.dataTransfer
      ? param.dataTransfer.files
      : param.target.files;
    const [file] = files;
    // upload file
    const cos = new Cosapi({
      file,
      onProgress: () => {
        console.log(1);
      },
    });
    return cos.uploadFile((err: any, res: any) => {
      if (err) {
        // handle error
        return;
      }
      if (res) {
        // res is a url
        curEditor.AssetManager.add([res]);
      }
    });
  },
},

FAQs

Package last updated on 10 Apr 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts