vue-editify 0.1.36 → 0.1.37
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 +2 -1
- package/lib/core/function.d.ts +7 -0
- package/lib/core/rule.d.ts +2 -2
- package/lib/core/tool.d.ts +1 -0
- package/lib/editify.es.js +135 -77
- package/lib/editify.umd.js +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/style.css +1 -1
- package/package.json +2 -2
- package/src/components/menu/menu.vue +33 -1
- package/src/components/tooltip/tooltip.less +2 -2
- package/src/core/function.ts +20 -0
- package/src/core/rule.ts +27 -11
- package/src/core/tool.ts +45 -34
- package/src/css/base.less +2 -0
- package/src/editify/editify.less +11 -2
- package/src/editify/editify.vue +2 -13
- package/src/icon/iconfont.css +4 -16
- package/src/icon/iconfont.ttf +0 -0
- package/src/icon/iconfont.woff +0 -0
- package/src/index.ts +4 -5
- package/src/locale/en_US.ts +1 -0
- package/src/locale/zh_CN.ts +1 -0
- package/src/plugins/attachment/index.ts +22 -19
package/src/core/tool.ts
CHANGED
@@ -167,6 +167,7 @@ export type MenuConfigType = {
|
|
167
167
|
heading?: MenuDisplayButtonType
|
168
168
|
indent?: MenuSelectButtonType
|
169
169
|
quote?: MenuButtonType
|
170
|
+
separator?: MenuButtonType
|
170
171
|
align?: MenuSelectButtonType
|
171
172
|
orderList?: MenuButtonType
|
172
173
|
unorderList?: MenuButtonType
|
@@ -825,30 +826,31 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
825
826
|
heading: 2,
|
826
827
|
indent: 3,
|
827
828
|
quote: 4,
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
829
|
+
separator: 5,
|
830
|
+
align: 6,
|
831
|
+
orderList: 7,
|
832
|
+
unorderList: 8,
|
833
|
+
task: 9,
|
834
|
+
bold: 10,
|
835
|
+
underline: 11,
|
836
|
+
italic: 12,
|
837
|
+
strikethrough: 13,
|
838
|
+
code: 14,
|
839
|
+
super: 15,
|
840
|
+
sub: 16,
|
841
|
+
formatClear: 17,
|
842
|
+
fontSize: 18,
|
843
|
+
fontFamily: 19,
|
844
|
+
lineHeight: 20,
|
845
|
+
foreColor: 21,
|
846
|
+
backColor: 22,
|
847
|
+
link: 23,
|
848
|
+
image: 24,
|
849
|
+
video: 25,
|
850
|
+
table: 26,
|
851
|
+
codeBlock: 27,
|
852
|
+
sourceView: 28,
|
853
|
+
fullScreen: 29
|
852
854
|
},
|
853
855
|
//撤销按钮配置
|
854
856
|
undo: {
|
@@ -900,7 +902,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
900
902
|
//右侧边框是否显示
|
901
903
|
rightBorder: false
|
902
904
|
},
|
903
|
-
|
905
|
+
//引用
|
904
906
|
quote: {
|
905
907
|
//是否显示此按钮
|
906
908
|
show: true,
|
@@ -909,6 +911,15 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
909
911
|
//右侧边框是否显示
|
910
912
|
rightBorder: false
|
911
913
|
},
|
914
|
+
//分隔线
|
915
|
+
separator: {
|
916
|
+
//是否显示此按钮
|
917
|
+
show: true,
|
918
|
+
//左侧边框是否显示
|
919
|
+
leftBorder: false,
|
920
|
+
//右侧边框是否显示
|
921
|
+
rightBorder: false
|
922
|
+
},
|
912
923
|
//对齐方式
|
913
924
|
align: {
|
914
925
|
//是否显示此工具
|
@@ -924,7 +935,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
924
935
|
//右侧边框是否显示
|
925
936
|
rightBorder: false
|
926
937
|
},
|
927
|
-
|
938
|
+
//有序列表
|
928
939
|
orderList: {
|
929
940
|
//是否显示此按钮
|
930
941
|
show: true,
|
@@ -933,7 +944,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
933
944
|
//右侧边框是否显示
|
934
945
|
rightBorder: false
|
935
946
|
},
|
936
|
-
|
947
|
+
//无序列表
|
937
948
|
unorderList: {
|
938
949
|
//是否显示此按钮
|
939
950
|
show: true,
|
@@ -942,7 +953,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
942
953
|
//右侧边框是否显示
|
943
954
|
rightBorder: false
|
944
955
|
},
|
945
|
-
|
956
|
+
//任务列表
|
946
957
|
task: {
|
947
958
|
//是否显示此按钮
|
948
959
|
show: true,
|
@@ -951,7 +962,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
951
962
|
//右侧边框是否显示
|
952
963
|
rightBorder: false
|
953
964
|
},
|
954
|
-
|
965
|
+
//粗体
|
955
966
|
bold: {
|
956
967
|
//是否显示此按钮
|
957
968
|
show: true,
|
@@ -960,7 +971,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
960
971
|
//右侧边框是否显示
|
961
972
|
rightBorder: false
|
962
973
|
},
|
963
|
-
|
974
|
+
//下划线
|
964
975
|
underline: {
|
965
976
|
//是否显示此按钮
|
966
977
|
show: true,
|
@@ -969,7 +980,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
969
980
|
//右侧边框是否显示
|
970
981
|
rightBorder: false
|
971
982
|
},
|
972
|
-
|
983
|
+
//斜体
|
973
984
|
italic: {
|
974
985
|
//是否显示此按钮
|
975
986
|
show: true,
|
@@ -978,7 +989,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
978
989
|
//右侧边框是否显示
|
979
990
|
rightBorder: false
|
980
991
|
},
|
981
|
-
|
992
|
+
//删除线
|
982
993
|
strikethrough: {
|
983
994
|
//是否显示此按钮
|
984
995
|
show: true,
|
@@ -987,7 +998,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
987
998
|
//右侧边框是否显示
|
988
999
|
rightBorder: false
|
989
1000
|
},
|
990
|
-
|
1001
|
+
//行内代码
|
991
1002
|
code: {
|
992
1003
|
//是否显示此按钮
|
993
1004
|
show: true,
|
@@ -1174,7 +1185,7 @@ export const getMenuConfig = function (editTrans: (key: string) => any, editLoca
|
|
1174
1185
|
//是否显示此工具
|
1175
1186
|
show: false,
|
1176
1187
|
//左侧边框是否显示
|
1177
|
-
leftBorder:
|
1188
|
+
leftBorder: true,
|
1178
1189
|
//右侧边框是否显示
|
1179
1190
|
rightBorder: false
|
1180
1191
|
},
|
package/src/css/base.less
CHANGED
package/src/editify/editify.less
CHANGED
@@ -285,6 +285,15 @@
|
|
285
285
|
color: @font-color-light;
|
286
286
|
border-radius: 0;
|
287
287
|
}
|
288
|
+
//分隔线样式
|
289
|
+
:deep(hr) {
|
290
|
+
display: block;
|
291
|
+
width: 100%;
|
292
|
+
height: 1px;
|
293
|
+
background-color: @font-color-disabled;
|
294
|
+
border: none;
|
295
|
+
margin: 10px 0;
|
296
|
+
}
|
288
297
|
//任务列表样式
|
289
298
|
:deep(div[data-editify-task]) {
|
290
299
|
margin-bottom: 15px;
|
@@ -343,7 +352,7 @@
|
|
343
352
|
}
|
344
353
|
|
345
354
|
//附件样式
|
346
|
-
:deep(span[data-attachment]) {
|
355
|
+
:deep(span[data-editify-attachment]) {
|
347
356
|
display: inline;
|
348
357
|
color: @font-color-link;
|
349
358
|
transition: all 200ms;
|
@@ -360,7 +369,7 @@
|
|
360
369
|
}
|
361
370
|
//附件名称
|
362
371
|
&::after {
|
363
|
-
content: attr(data-attachment-name);
|
372
|
+
content: attr(data-editify-attachment-name);
|
364
373
|
margin-left: 6px;
|
365
374
|
font-size: inherit;
|
366
375
|
}
|
package/src/editify/editify.vue
CHANGED
@@ -23,7 +23,7 @@ import { computed, getCurrentInstance, nextTick, onBeforeUnmount, onMounted, pro
|
|
23
23
|
import { AlexEditor, AlexElement, AlexElementRangeType, AlexElementsRangeType } from 'alex-editor'
|
24
24
|
import { element as DapElement, event as DapEvent, data as DapData, number as DapNumber, color as DapColor } from 'dap-util'
|
25
25
|
import { pasteKeepData, mergeObject, getToolbarConfig, getMenuConfig, MenuConfigType, ObjectType, ToolbarConfigType, PluginResultType } from '../core/tool'
|
26
|
-
import { parseList, orderdListHandle,
|
26
|
+
import { parseList, orderdListHandle, commonElementHandle, tableHandle, preHandle, specialInblockHandle } from '../core/rule'
|
27
27
|
import { isTask, elementToParagraph, getCurrentParsedomElement, hasTableInRange, hasLinkInRange, hasPreInRange, hasImageInRange, hasVideoInRange } from '../core/function'
|
28
28
|
import Toolbar from '../components/toolbar/toolbar.vue'
|
29
29
|
import Menu from '../components/menu/menu.vue'
|
@@ -261,7 +261,7 @@ const createEditor = () => {
|
|
261
261
|
orderdListHandle(editor.value!, el)
|
262
262
|
},
|
263
263
|
el => {
|
264
|
-
|
264
|
+
commonElementHandle(editor.value!, el)
|
265
265
|
},
|
266
266
|
el => {
|
267
267
|
tableHandle(editor.value!, el)
|
@@ -501,17 +501,6 @@ const handleCustomMerge = (ele: AlexElement, preEle: AlexElement) => {
|
|
501
501
|
}
|
502
502
|
//针对node转为元素进行额外的处理
|
503
503
|
const handleCustomParseNode = (ele: AlexElement) => {
|
504
|
-
if (ele.parsedom == 'code') {
|
505
|
-
ele.parsedom = 'span'
|
506
|
-
const marks = {
|
507
|
-
'data-editify-code': true
|
508
|
-
}
|
509
|
-
if (ele.hasMarks()) {
|
510
|
-
Object.assign(ele.marks!, marks)
|
511
|
-
} else {
|
512
|
-
ele.marks = marks
|
513
|
-
}
|
514
|
-
}
|
515
504
|
//注册插件:自定义元素转换处理
|
516
505
|
pluginResultList.value.forEach(pluginResult => {
|
517
506
|
if (pluginResult.customParseNode) {
|
package/src/icon/iconfont.css
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
.editify-icon-separator:before {
|
2
|
+
content: '\e6e5';
|
3
|
+
}
|
4
|
+
|
1
5
|
.editify-icon-attachment:before {
|
2
6
|
content: '\e689';
|
3
7
|
}
|
@@ -98,14 +102,6 @@
|
|
98
102
|
content: '\e620';
|
99
103
|
}
|
100
104
|
|
101
|
-
.editify-icon-width:before {
|
102
|
-
content: '\e674';
|
103
|
-
}
|
104
|
-
|
105
|
-
.editify-icon-edit:before {
|
106
|
-
content: '\e817';
|
107
|
-
}
|
108
|
-
|
109
105
|
.editify-icon-table:before {
|
110
106
|
content: '\e6c4';
|
111
107
|
}
|
@@ -166,14 +162,6 @@
|
|
166
162
|
content: '\e7a1';
|
167
163
|
}
|
168
164
|
|
169
|
-
.editify-icon-paragraph:before {
|
170
|
-
content: '\e7a3';
|
171
|
-
}
|
172
|
-
|
173
|
-
.editify-icon-separator:before {
|
174
|
-
content: '\e7a4';
|
175
|
-
}
|
176
|
-
|
177
165
|
.editify-icon-subscript:before {
|
178
166
|
content: '\e7a5';
|
179
167
|
}
|
package/src/icon/iconfont.ttf
CHANGED
Binary file
|
package/src/icon/iconfont.woff
CHANGED
Binary file
|
package/src/index.ts
CHANGED
@@ -9,9 +9,6 @@ export type { ButtonTypeType, ButtonOptionsItemType, ButtonSelectConfigType, But
|
|
9
9
|
export type { InsertImageUploadErrorType } from './components/insertImage/props'
|
10
10
|
export type { InsertVideoUploadErrorType } from './components/insertVideo/props'
|
11
11
|
export type { MenuButtonType, MenuSelectButtonType, MenuDisplayButtonType, MenuImageButtonType, MenuVideoButtonType, MenuTableButtonType, MenuCustomButtonType, CodeBlockToolbarType, TextToolbarType, ToolbarConfigType, MenuSequenceType, MenuModeType, MenuExtendType, MenuConfigType, PluginType, PluginResultType } from './core/tool'
|
12
|
-
//导出插件相关类型
|
13
|
-
export type { AttachmentOptionsType } from './plugins/attachment'
|
14
|
-
export type { InsertAttachmentUploadErrorType } from './plugins/attachment/insertAttachment/props'
|
15
12
|
|
16
13
|
//导出编辑器操作方法
|
17
14
|
export { getParsedomElementByElement, getCurrentParsedomElement, elementIsInList, elementIsInTask, isList, isTask, hasPreInRange, isRangeInPre, hasQuoteInRange, isRangeInQuote, hasListInRange, isRangeInList, hasTaskInRange, isRangeInTask, hasLinkInRange, hasTableInRange, hasImageInRange, hasVideoInRange, queryTextStyle, queryTextMark, getRangeText, setIndentIncrease, setIndentDecrease, setQuote, setAlign, setList, setTask, setTextStyle, setTextMark, removeTextStyle, removeTextMark, setLineHeight, insertLink, insertImage, insertVideo, insertTable, insertCodeBlock } from './core/function'
|
@@ -21,12 +18,14 @@ const install: FunctionPlugin = (app: App) => {
|
|
21
18
|
app.component(Editify.name!, Editify)
|
22
19
|
}
|
23
20
|
//版本号
|
24
|
-
const version = '0.1.
|
21
|
+
const version = '0.1.37'
|
25
22
|
|
26
23
|
//导出AlexElement元素
|
27
24
|
export { AlexElement } from 'alex-editor'
|
28
25
|
|
29
|
-
|
26
|
+
//导出attachment插件相关的方法和类型
|
27
|
+
export type { AttachmentOptionsType } from './plugins/attachment'
|
28
|
+
export type { InsertAttachmentUploadErrorType } from './plugins/attachment/insertAttachment/props'
|
30
29
|
export { attachment, isAttachment, hasAttachmentInRange } from './plugins/attachment'
|
31
30
|
|
32
31
|
//导出组件和安装函数
|
package/src/locale/en_US.ts
CHANGED
package/src/locale/zh_CN.ts
CHANGED
@@ -43,7 +43,7 @@ export const isAttachment = (element: AlexElement) => {
|
|
43
43
|
if (element.isEmpty()) {
|
44
44
|
return false
|
45
45
|
}
|
46
|
-
return element.parsedom == 'span' && element.type == 'closed' && element.hasMarks() && element.marks!['data-attachment']
|
46
|
+
return element.parsedom == 'span' && element.type == 'closed' && element.hasMarks() && element.marks!['data-editify-attachment']
|
47
47
|
}
|
48
48
|
|
49
49
|
/**
|
@@ -124,23 +124,22 @@ export const attachment = (options?: AttachmentOptionsType) => {
|
|
124
124
|
//遍历地址数组
|
125
125
|
urls.forEach(url => {
|
126
126
|
const marks: ObjectType = {
|
127
|
-
'data-attachment': url,
|
128
|
-
'data-attachment-name': name || editTrans('attachmentDefaultName')
|
129
|
-
contenteditable: 'false'
|
127
|
+
'data-editify-attachment': url,
|
128
|
+
'data-editify-attachment-name': name || editTrans('attachmentDefaultName')
|
130
129
|
}
|
131
130
|
//创建元素
|
132
131
|
const attachmentElement = new AlexElement('closed', 'span', marks, null, null)
|
133
132
|
//插入编辑器
|
134
133
|
editor.insertElement(attachmentElement)
|
135
134
|
//创建空文本元素
|
136
|
-
const
|
137
|
-
const
|
135
|
+
const leftSpace = AlexElement.getSpaceElement()
|
136
|
+
const rightSpace = AlexElement.getSpaceElement()
|
138
137
|
//将空白文本元素插入附件两端
|
139
|
-
editor.
|
140
|
-
editor.
|
138
|
+
editor.addElementBefore(leftSpace, attachmentElement)
|
139
|
+
editor.addElementAfter(rightSpace, attachmentElement)
|
141
140
|
//移动光标到新插入的元素
|
142
|
-
editor.range!.anchor.
|
143
|
-
editor.range!.focus.
|
141
|
+
editor.range!.anchor.moveToEnd(rightSpace)
|
142
|
+
editor.range!.focus.moveToEnd(rightSpace)
|
144
143
|
})
|
145
144
|
//渲染
|
146
145
|
editor.formatElementStack()
|
@@ -157,12 +156,12 @@ export const attachment = (options?: AttachmentOptionsType) => {
|
|
157
156
|
updateView: () => {
|
158
157
|
const editor = <AlexEditor>editifyInstance.exposed!.editor.value
|
159
158
|
AlexElement.flatElements(editor.stack).forEach(el => {
|
160
|
-
if (el.parsedom == 'span' && el.hasMarks() && el.marks!['data-attachment']) {
|
159
|
+
if (el.parsedom == 'span' && el.hasMarks() && el.marks!['data-editify-attachment']) {
|
161
160
|
DapEvent.off(<HTMLElement>el.elm, 'click')
|
162
161
|
//单击下载
|
163
162
|
DapEvent.on(<HTMLElement>el.elm, 'click', async () => {
|
164
163
|
//获取文件地址
|
165
|
-
const url = el.marks!['data-attachment']
|
164
|
+
const url = el.marks!['data-editify-attachment']
|
166
165
|
//使用fetch读取文件地址
|
167
166
|
const res = await fetch(url, {
|
168
167
|
method: 'GET'
|
@@ -173,29 +172,33 @@ export const attachment = (options?: AttachmentOptionsType) => {
|
|
173
172
|
const a = document.createElement('a')
|
174
173
|
a.setAttribute('target', '_blank')
|
175
174
|
a.setAttribute('href', URL.createObjectURL(blob))
|
176
|
-
a.setAttribute('download', el.marks!['data-attachment-name'])
|
175
|
+
a.setAttribute('download', el.marks!['data-editify-attachment-name'])
|
177
176
|
a.click()
|
178
177
|
})
|
179
178
|
}
|
180
179
|
})
|
181
180
|
},
|
182
|
-
//span含有data-attachment的元素设为自闭合元素
|
181
|
+
//span含有data-editify-attachment的元素设为自闭合元素
|
183
182
|
customParseNode: (el: AlexElement) => {
|
184
|
-
if (el.hasMarks() && el.marks!['data-attachment'] && el.parsedom == 'span') {
|
183
|
+
if (el.hasMarks() && el.marks!['data-editify-attachment'] && el.parsedom == 'span') {
|
185
184
|
el.type = 'closed'
|
186
185
|
}
|
187
186
|
return el
|
188
187
|
},
|
189
|
-
//span元素粘贴保留data-attachment
|
188
|
+
//span元素粘贴保留data-editify-attachment
|
190
189
|
pasteKeepMarks: {
|
191
|
-
'data-attachment': ['span'],
|
192
|
-
'data-attachment-name': ['span']
|
190
|
+
'data-editify-attachment': ['span'],
|
191
|
+
'data-editify-attachment-name': ['span']
|
193
192
|
},
|
194
193
|
//自定义渲染规范
|
195
194
|
renderRule: (el: AlexElement) => {
|
196
|
-
if (el.
|
195
|
+
if (el.hasMarks() && el.marks!['data-editify-attachment']) {
|
197
196
|
//设置title
|
198
197
|
el.marks!['title'] = editTrans('attachmentDownloadTitle')
|
198
|
+
//如果名称没有则设置名称
|
199
|
+
if (!el.marks!['data-editify-attachment-name']) {
|
200
|
+
el.marks!['data-editify-attachment-name'] = editTrans('attachmentDefaultName')
|
201
|
+
}
|
199
202
|
//获取editor对象
|
200
203
|
const editor = <AlexEditor>editifyInstance.exposed!.editor.value
|
201
204
|
//前一个元素
|