vue-editify 0.0.34 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/examples/App.vue CHANGED
@@ -1,19 +1,22 @@
1
1
  <template>
2
2
  <div style="padding: 100px 50px 50px 50px">
3
- <editify v-model="value" placeholder="请输入正文内容..." allow-paste-html border @change="change" :menu="menuConfig" ref="editify" height="400px"></editify>
3
+ <editify v-model="value" placeholder="请输入正文内容..." allow-paste-html border @change="change" :menu="menuConfig" ref="editify" height="400px" @after-render="afterRender" :paste-keep-marks="{ 'data-zip': ['span'] }" :custom-parse-node="parseNode"></editify>
4
4
  </div>
5
5
  </template>
6
6
  <script>
7
+ import { AlexElement } from '../src'
7
8
  import { h } from 'vue'
9
+ import Dap from 'dap-util'
8
10
  export default {
9
11
  name: 'App',
10
12
  data() {
11
13
  return {
12
- value: '<p><span>这是一个基于 </span><span data-editify-code="true">Vue3 + alex-editor</span><span> 构建的一套</span><span style="font-weight: bold;">精美UI样式</span><span>的</span><span style="font-weight: bold;">开箱即用</span><span>的</span><span style="color: #ec1a0a;">富文本编辑器</span></p>',
14
+ value: '<p><span>这是一个基于 </span><code>Vue3 + alex-editor</code><span> 构建的一套</span><span style="font-weight: bold;">精美UI样式</span><span>的</span><span style="font-weight: bold;">开箱即用</span><span>的</span><span style="color: #ec1a0a;">富文本编辑器</span></p>',
13
15
  menuConfig: {
14
16
  //mode: 'inner',
15
17
  sequence: {
16
- alert: 100
18
+ alert: 100,
19
+ zip: 101
17
20
  },
18
21
  table: {
19
22
  maxRows: 20,
@@ -23,6 +26,38 @@ export default {
23
26
  show: true
24
27
  },
25
28
  extends: {
29
+ zip: {
30
+ title: '上传压缩包',
31
+ default: () => {
32
+ return h('span', {}, 'zip')
33
+ },
34
+ onOperate: () => {
35
+ //选择文件上传
36
+ const upload = document.createElement('input')
37
+ upload.setAttribute('type', 'file')
38
+ upload.setAttribute('accept', 'application/zip')
39
+ upload.onchange = async e => {
40
+ //获取到文件
41
+ const file = e.currentTarget.files[0]
42
+ if (file) {
43
+ //转成base64
44
+ const base64 = await Dap.file.dataFileToBase64(file)
45
+ //创建元素
46
+ const zipEle = new AlexElement('closed', 'span', { 'data-zip': 'true', contenteditable: 'false' }, null, null)
47
+ //插入编辑器
48
+ this.$refs.editify.editor.insertElement(zipEle)
49
+ //移动光标到新插入的元素
50
+ this.$refs.editify.editor.range.anchor.moveToStart(zipEle)
51
+ this.$refs.editify.editor.range.focus.moveToStart(zipEle)
52
+ //格式化
53
+ this.$refs.editify.editor.formatElementStack()
54
+ //渲染
55
+ this.$refs.editify.editor.domRender()
56
+ }
57
+ }
58
+ upload.click()
59
+ }
60
+ },
26
61
  alert: {
27
62
  title: '自定义菜单按钮',
28
63
  leftBorder: true,
@@ -66,6 +101,23 @@ export default {
66
101
  // }, 3000)
67
102
  },
68
103
  methods: {
104
+ afterRender() {
105
+ this.$refs.editify.$el.querySelectorAll('[data-zip]').forEach(el => {
106
+ el.onclick = function () {
107
+ const url = el.getAttribute('data-zip')
108
+ const a = document.createElement('a')
109
+ a.setAttribute('href', url)
110
+ a.setAttribute('download', 'download.zip')
111
+ a.click()
112
+ }
113
+ })
114
+ },
115
+ parseNode(ele) {
116
+ if (ele.hasMarks() && ele.marks['data-zip']) {
117
+ ele.type = 'closed'
118
+ }
119
+ return ele
120
+ },
69
121
  change() {
70
122
  console.log(this.$refs.editify.textValue)
71
123
  },
@@ -88,4 +140,14 @@ body {
88
140
  height: 100%;
89
141
  overflow: auto;
90
142
  }
143
+
144
+ span[data-zip] {
145
+ display: inline-block;
146
+ width: 40px;
147
+ height: 40px;
148
+ background: url(https://www.ling0523.cn/images/image_0_1702456046669.png) no-repeat center;
149
+ background-size: cover;
150
+ cursor: pointer;
151
+ margin: 0 10px;
152
+ }
91
153
  </style>
package/lib/editify.es.js CHANGED
@@ -1844,7 +1844,9 @@ const initEditorOptions = (options) => {
1844
1844
  //自定义视频粘贴方法
1845
1845
  customVideoPaste: null,
1846
1846
  //自定义处理不可编辑元素合并的逻辑
1847
- customMerge: null
1847
+ customMerge: null,
1848
+ //自定义dom转为非文本元素的后续处理逻辑
1849
+ customParseNode: null
1848
1850
  };
1849
1851
  if (obj$1.common.isObject(options)) {
1850
1852
  if (typeof options.disabled == "boolean") {
@@ -1883,6 +1885,9 @@ const initEditorOptions = (options) => {
1883
1885
  if (typeof options.customMerge == "function") {
1884
1886
  opts.customMerge = options.customMerge;
1885
1887
  }
1888
+ if (typeof options.customParseNode == "function") {
1889
+ opts.customParseNode = options.customParseNode;
1890
+ }
1886
1891
  }
1887
1892
  return opts;
1888
1893
  };
@@ -3258,6 +3263,7 @@ class AlexEditor {
3258
3263
  this.customImagePaste = options.customImagePaste;
3259
3264
  this.customVideoPaste = options.customVideoPaste;
3260
3265
  this.customMerge = options.customMerge;
3266
+ this.customParseNode = options.customParseNode;
3261
3267
  this.useClipboard = canUseClipboard();
3262
3268
  this.history = new AlexHistory();
3263
3269
  this.stack = this.parseHtml(this.value);
@@ -4251,6 +4257,9 @@ class AlexEditor {
4251
4257
  }
4252
4258
  });
4253
4259
  }
4260
+ if (typeof this.customParseNode == "function") {
4261
+ element2 = this.customParseNode.apply(this, [element2]);
4262
+ }
4254
4263
  return element2;
4255
4264
  }
4256
4265
  /**
@@ -15387,6 +15396,21 @@ const editorProps = {
15387
15396
  menu: {
15388
15397
  type: Object,
15389
15398
  default: null
15399
+ },
15400
+ //dom转换时的额外处理
15401
+ customParseNode: {
15402
+ type: Function,
15403
+ default: null
15404
+ },
15405
+ //粘贴html时额外保留的标记(全部元素生效)
15406
+ pasteKeepMarks: {
15407
+ type: Object,
15408
+ default: null
15409
+ },
15410
+ //粘贴html时额外保留的样式(仅在非文本元素生效)
15411
+ pasteKeepStyles: {
15412
+ type: Object,
15413
+ default: null
15390
15414
  }
15391
15415
  };
15392
15416
  const getColNumbers = (row) => {
@@ -15479,19 +15503,6 @@ const parseList = function(element2) {
15479
15503
  }
15480
15504
  }
15481
15505
  };
15482
- const parseCode = function(element2) {
15483
- if (element2.parsedom == "code") {
15484
- element2.parsedom = "span";
15485
- const marks = {
15486
- "data-editify-code": true
15487
- };
15488
- if (element2.hasMarks()) {
15489
- Object.assign(element2.marks, marks);
15490
- } else {
15491
- element2.marks = marks;
15492
- }
15493
- }
15494
- };
15495
15506
  const mediaHandle = function(element2) {
15496
15507
  if (element2.parsedom == "img" || element2.parsedom == "video" || element2.parsedom == "a") {
15497
15508
  const marks = {
@@ -21186,7 +21197,7 @@ function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
21186
21197
  ], 14, _hoisted_1$1);
21187
21198
  }
21188
21199
  const Menu = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-42f60b43"]]);
21189
- const Editify_vue_vue_type_style_index_0_scoped_237c369a_lang = "";
21200
+ const Editify_vue_vue_type_style_index_0_scoped_8415c1dc_lang = "";
21190
21201
  const _sfc_main = {
21191
21202
  name: "editify",
21192
21203
  props: { ...editorProps },
@@ -21312,7 +21323,6 @@ const _sfc_main = {
21312
21323
  disabled: this.disabled,
21313
21324
  renderRules: [
21314
21325
  parseList,
21315
- parseCode,
21316
21326
  mediaHandle,
21317
21327
  tableHandle,
21318
21328
  (el) => {
@@ -21327,7 +21337,8 @@ const _sfc_main = {
21327
21337
  allowPasteHtml: this.allowPasteHtml,
21328
21338
  customImagePaste: this.customImagePaste,
21329
21339
  customVideoPaste: this.customVideoPaste,
21330
- customMerge: this.handleCustomMerge
21340
+ customMerge: this.handleCustomMerge,
21341
+ customParseNode: this.handleCustomParseNode
21331
21342
  });
21332
21343
  this.internalModify(this.editor.value);
21333
21344
  this.editor.on("change", this.handleEditorChange);
@@ -21468,6 +21479,24 @@ const _sfc_main = {
21468
21479
  ele.children = null;
21469
21480
  }
21470
21481
  },
21482
+ //针对node转为元素进行额外的处理
21483
+ handleCustomParseNode(ele) {
21484
+ if (ele.parsedom == "code") {
21485
+ ele.parsedom = "span";
21486
+ const marks = {
21487
+ "data-editify-code": true
21488
+ };
21489
+ if (ele.hasMarks()) {
21490
+ Object.assign(ele.marks, marks);
21491
+ } else {
21492
+ ele.marks = marks;
21493
+ }
21494
+ }
21495
+ if (typeof this.customParseNode == "function") {
21496
+ ele = this.customParseNode.apply(this, [ele]);
21497
+ }
21498
+ return ele;
21499
+ },
21471
21500
  //隐藏工具条
21472
21501
  hideToolbar() {
21473
21502
  this.toolbarOptions.show = false;
@@ -21703,20 +21732,22 @@ const _sfc_main = {
21703
21732
  },
21704
21733
  //编辑器粘贴html
21705
21734
  handlePasteHtml(elements, data2) {
21735
+ const keepStyles = Object.assign(pasteKeepData.styles, this.pasteKeepStyles || {});
21736
+ const keepMarks = Object.assign(pasteKeepData.marks, this.pasteKeepMarks || {});
21706
21737
  AlexElement.flatElements(elements).forEach((el) => {
21707
21738
  let marks = {};
21708
21739
  let styles = {};
21709
21740
  if (el.hasMarks()) {
21710
- for (let key in pasteKeepData.marks) {
21711
- if (el.marks.hasOwnProperty(key) && (Array.isArray(pasteKeepData.marks[key]) && pasteKeepData.marks[key].includes(el.parsedom) || pasteKeepData.marks[key] == "*")) {
21741
+ for (let key in keepMarks) {
21742
+ if (el.marks.hasOwnProperty(key) && (Array.isArray(keepMarks[key]) && keepMarks[key].includes(el.parsedom) || keepMarks[key] == "*")) {
21712
21743
  marks[key] = el.marks[key];
21713
21744
  }
21714
21745
  }
21715
21746
  el.marks = marks;
21716
21747
  }
21717
21748
  if (el.hasStyles() && !el.isText()) {
21718
- for (let key in pasteKeepData.styles) {
21719
- if (el.styles.hasOwnProperty(key) && (Array.isArray(pasteKeepData.styles[key]) && pasteKeepData.styles[key].includes(el.parsedom) || pasteKeepData.styles[key] == "*")) {
21749
+ for (let key in keepStyles) {
21750
+ if (el.styles.hasOwnProperty(key) && (Array.isArray(keepStyles[key]) && keepStyles[key].includes(el.parsedom) || keepStyles[key] == "*")) {
21720
21751
  styles[key] = el.styles[key];
21721
21752
  }
21722
21753
  }
@@ -22783,7 +22814,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
22783
22814
  ])) : createCommentVNode("", true)
22784
22815
  ]);
22785
22816
  }
22786
- const Editify = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-237c369a"]]);
22817
+ const Editify = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-8415c1dc"]]);
22787
22818
  const iconfont = "";
22788
22819
  const en_US = {
22789
22820
  textWrapUp: "Up feed",
@@ -22962,7 +22993,7 @@ const i18n = (locale) => {
22962
22993
  return translations[locale][key];
22963
22994
  };
22964
22995
  };
22965
- const version = "0.0.34";
22996
+ const version = "0.0.35";
22966
22997
  const install = (app, props) => {
22967
22998
  const locale = (props ? props.locale : "zh_CN") || "zh_CN";
22968
22999
  app.provide("$editTrans", i18n(locale));