vue-editify 0.1.35 → 0.1.37
Sign up to get free protection for your applications and to get access to all the features.
- 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 +136 -78
- 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
|
//前一个元素
|