vue-editify 0.1.15 → 0.1.17
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 +6 -2
- package/lib/components/toolbar/toolbar.vue.d.ts +3 -3
- package/lib/editify/editify.vue.d.ts +16 -7
- package/lib/editify/props.d.ts +6 -2
- package/lib/editify.es.js +285 -144
- package/lib/editify.umd.js +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/style.css +1 -1
- package/package.json +3 -3
- package/src/components/menu/menu.less +0 -1
- package/src/components/menu/menu.vue +1 -2
- package/src/components/toolbar/toolbar.vue +2 -2
- package/src/components/tooltip/tooltip.vue +1 -1
- package/src/editify/editify.vue +4 -17
- package/src/editify/props.ts +7 -2
- package/src/index.ts +1 -1
- package/vite.config.ts +3 -0
package/examples/App.vue
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
<template>
|
2
2
|
<div style="padding: 80px 10px 10px 10px; height: 100%; box-sizing: border-box">
|
3
|
-
<Editify ref="editify" border v-model="val" :menu="menuConfig" style="height: 100%" placeholder="Please Enter Text..." locale="zh_CN"></Editify>
|
3
|
+
<Editify ref="editify" border v-model="val" :menu="menuConfig" style="height: 100%" placeholder="Please Enter Text..." locale="zh_CN" allowPasteHtml :custom-image-paste="customImagePaste"></Editify>
|
4
4
|
</div>
|
5
5
|
</template>
|
6
6
|
<script setup lang="ts">
|
7
7
|
import { ref } from 'vue'
|
8
|
-
import { Editify } from '../src/index'
|
8
|
+
import { Editify, insertImage, insertVideo } from '../src/index'
|
9
9
|
import { MenuConfigType } from '../src/index'
|
10
10
|
const val = ref<string>('<p><br></p>')
|
11
11
|
const editify = ref<InstanceType<typeof Editify> | null>(null)
|
@@ -22,6 +22,10 @@ const menuConfig = ref<MenuConfigType>({
|
|
22
22
|
show: true
|
23
23
|
}
|
24
24
|
})
|
25
|
+
const customImagePaste = url => {
|
26
|
+
console.log(url)
|
27
|
+
insertImage(editify.value!.editor!, url)
|
28
|
+
}
|
25
29
|
</script>
|
26
30
|
<style lang="less">
|
27
31
|
html,
|
@@ -13,7 +13,7 @@ declare const _default: import('vue').DefineComponent<{
|
|
13
13
|
validator(value: any): boolean;
|
14
14
|
};
|
15
15
|
config: {
|
16
|
-
type: import("vue").PropType<import("
|
16
|
+
type: import("vue").PropType<import("../../core/tool").ToolbarConfigType>;
|
17
17
|
default: null;
|
18
18
|
};
|
19
19
|
color: {
|
@@ -37,7 +37,7 @@ declare const _default: import('vue').DefineComponent<{
|
|
37
37
|
validator(value: any): boolean;
|
38
38
|
};
|
39
39
|
config: {
|
40
|
-
type: import("vue").PropType<import("
|
40
|
+
type: import("vue").PropType<import("../../core/tool").ToolbarConfigType>;
|
41
41
|
default: null;
|
42
42
|
};
|
43
43
|
color: {
|
@@ -51,6 +51,6 @@ declare const _default: import('vue').DefineComponent<{
|
|
51
51
|
type: "link" | "text" | "image" | "video" | "table" | "codeBlock";
|
52
52
|
modelValue: boolean;
|
53
53
|
node: string | HTMLElement;
|
54
|
-
config: import("
|
54
|
+
config: import("../../core/tool").ToolbarConfigType;
|
55
55
|
}, {}>;
|
56
56
|
export default _default;
|
@@ -60,11 +60,15 @@ declare const _default: import('vue').DefineComponent<{
|
|
60
60
|
default: boolean;
|
61
61
|
};
|
62
62
|
customImagePaste: {
|
63
|
-
type: import("vue").PropType<(url: string) =>
|
63
|
+
type: import("vue").PropType<(url: string) => void | Promise<void>>;
|
64
64
|
default: null;
|
65
65
|
};
|
66
66
|
customVideoPaste: {
|
67
|
-
type: import("vue").PropType<(url: string) =>
|
67
|
+
type: import("vue").PropType<(url: string) => void | Promise<void>>;
|
68
|
+
default: null;
|
69
|
+
};
|
70
|
+
customFilePaste: {
|
71
|
+
type: import("vue").PropType<(url: string) => void | Promise<void>>;
|
68
72
|
default: null;
|
69
73
|
};
|
70
74
|
menu: {
|
@@ -109,6 +113,7 @@ declare const _default: import('vue').DefineComponent<{
|
|
109
113
|
customHtmlPaste: ((AlexElements: AlexElement[], html: string) => void | Promise<void>) | null;
|
110
114
|
customImagePaste: ((url: string) => void | Promise<void>) | null;
|
111
115
|
customVideoPaste: ((url: string) => void | Promise<void>) | null;
|
116
|
+
customFilePaste: ((url: string) => void | Promise<void>) | null;
|
112
117
|
customMerge: ((mergeElement: AlexElement, targetElement: AlexElement) => void | Promise<void>) | null;
|
113
118
|
customParseNode: ((el: AlexElement) => AlexElement) | null;
|
114
119
|
useClipboard: boolean;
|
@@ -410,7 +415,6 @@ declare const _default: import('vue').DefineComponent<{
|
|
410
415
|
text: string;
|
411
416
|
html: string;
|
412
417
|
} | undefined>;
|
413
|
-
paste: () => Promise<void>;
|
414
418
|
delete: () => void;
|
415
419
|
insertText: (data: string) => void;
|
416
420
|
insertParagraph: () => void;
|
@@ -604,11 +608,15 @@ declare const _default: import('vue').DefineComponent<{
|
|
604
608
|
default: boolean;
|
605
609
|
};
|
606
610
|
customImagePaste: {
|
607
|
-
type: import("vue").PropType<(url: string) =>
|
611
|
+
type: import("vue").PropType<(url: string) => void | Promise<void>>;
|
608
612
|
default: null;
|
609
613
|
};
|
610
614
|
customVideoPaste: {
|
611
|
-
type: import("vue").PropType<(url: string) =>
|
615
|
+
type: import("vue").PropType<(url: string) => void | Promise<void>>;
|
616
|
+
default: null;
|
617
|
+
};
|
618
|
+
customFilePaste: {
|
619
|
+
type: import("vue").PropType<(url: string) => void | Promise<void>>;
|
612
620
|
default: null;
|
613
621
|
};
|
614
622
|
menu: {
|
@@ -665,8 +673,9 @@ declare const _default: import('vue').DefineComponent<{
|
|
665
673
|
allowPasteHtml: boolean;
|
666
674
|
videoRatio: number;
|
667
675
|
showWordLength: boolean;
|
668
|
-
customImagePaste: (url: string) =>
|
669
|
-
customVideoPaste: (url: string) =>
|
676
|
+
customImagePaste: (url: string) => void | Promise<void>;
|
677
|
+
customVideoPaste: (url: string) => void | Promise<void>;
|
678
|
+
customFilePaste: (url: string) => void | Promise<void>;
|
670
679
|
pasteKeepMarks: ObjectType;
|
671
680
|
pasteKeepStyles: ObjectType;
|
672
681
|
customParseNode: (el: AlexElement) => AlexElement;
|
package/lib/editify/props.d.ts
CHANGED
@@ -71,11 +71,15 @@ export declare const EditifyProps: {
|
|
71
71
|
default: boolean;
|
72
72
|
};
|
73
73
|
customImagePaste: {
|
74
|
-
type: PropType<(url: string) =>
|
74
|
+
type: PropType<(url: string) => void | Promise<void>>;
|
75
75
|
default: null;
|
76
76
|
};
|
77
77
|
customVideoPaste: {
|
78
|
-
type: PropType<(url: string) =>
|
78
|
+
type: PropType<(url: string) => void | Promise<void>>;
|
79
|
+
default: null;
|
80
|
+
};
|
81
|
+
customFilePaste: {
|
82
|
+
type: PropType<(url: string) => void | Promise<void>>;
|
79
83
|
default: null;
|
80
84
|
};
|
81
85
|
menu: {
|
package/lib/editify.es.js
CHANGED
@@ -1146,6 +1146,151 @@ const event$1 = {
|
|
1146
1146
|
return events;
|
1147
1147
|
}
|
1148
1148
|
};
|
1149
|
+
const file$1 = {
|
1150
|
+
/**
|
1151
|
+
* 根据文件获取可预览的图片路径
|
1152
|
+
* @param {Object} file
|
1153
|
+
*/
|
1154
|
+
getImageUrl(file2) {
|
1155
|
+
if (!file2 || !(file2 instanceof File)) {
|
1156
|
+
throw new TypeError("The argument must be a File object");
|
1157
|
+
}
|
1158
|
+
return window.URL.createObjectURL(file2);
|
1159
|
+
},
|
1160
|
+
/**
|
1161
|
+
* 将JS的file对象转为BASE64位字符串,通过then方法回调,参数为base64字符串
|
1162
|
+
* @param {Object} file
|
1163
|
+
*/
|
1164
|
+
dataFileToBase64(file2) {
|
1165
|
+
return new Promise((resolve, reject) => {
|
1166
|
+
if (!file2 || !(file2 instanceof File)) {
|
1167
|
+
reject(new TypeError("The argument must be a File object"));
|
1168
|
+
}
|
1169
|
+
let reader = new FileReader();
|
1170
|
+
reader.readAsDataURL(file2);
|
1171
|
+
reader.onloadend = () => {
|
1172
|
+
let dataURL = reader.result;
|
1173
|
+
resolve(dataURL);
|
1174
|
+
};
|
1175
|
+
});
|
1176
|
+
},
|
1177
|
+
/**
|
1178
|
+
* 将base64位格式文件转换为file对象
|
1179
|
+
* @param {Object} base64String base64位格式字符串
|
1180
|
+
* @param {Object} fileName 转换后的文件名字,包含后缀
|
1181
|
+
*/
|
1182
|
+
dataBase64toFile(base64String, fileName) {
|
1183
|
+
if (!base64String || typeof base64String != "string") {
|
1184
|
+
throw new TypeError("The first argument must be a string");
|
1185
|
+
}
|
1186
|
+
if (!fileName || typeof fileName != "string") {
|
1187
|
+
throw new TypeError("The second argument must be a string");
|
1188
|
+
}
|
1189
|
+
let arr = base64String.split(",");
|
1190
|
+
let mime = arr[0].match(/:(.*?);/)[1];
|
1191
|
+
let bstr = atob(arr[1]);
|
1192
|
+
let n = bstr.length;
|
1193
|
+
let u8arr = new Uint8Array(n);
|
1194
|
+
while (n--) {
|
1195
|
+
u8arr[n] = bstr.charCodeAt(n);
|
1196
|
+
}
|
1197
|
+
return new File([u8arr], fileName, {
|
1198
|
+
type: mime
|
1199
|
+
});
|
1200
|
+
},
|
1201
|
+
/**
|
1202
|
+
* 图片压缩方法
|
1203
|
+
* @param {*} file 需要压缩的图片File文件
|
1204
|
+
* @param {*} opts 压缩参数
|
1205
|
+
*/
|
1206
|
+
compressImage(file2, opts) {
|
1207
|
+
const options = {
|
1208
|
+
//压缩图片的宽,单位px,如果不设置默认为原图宽
|
1209
|
+
width: void 0,
|
1210
|
+
//压缩图片质量,默认为原图的0.8
|
1211
|
+
quality: 0.8,
|
1212
|
+
//图片类型,jpeg或者webp,默认为jpeg
|
1213
|
+
mimeType: "jpeg",
|
1214
|
+
//压缩后的最大值,单位kb,默认为0表示不设置此值
|
1215
|
+
maxSize: 0,
|
1216
|
+
//小于该大小的图片不进行压缩,单位kb,默认为0表示任何图片都要压缩
|
1217
|
+
minSize: 0
|
1218
|
+
};
|
1219
|
+
if (common$1.isObject(opts)) {
|
1220
|
+
if (number$1.isNumber(opts.width)) {
|
1221
|
+
options.width = opts.width;
|
1222
|
+
}
|
1223
|
+
if (number$1.isNumber(opts.quality) && opts.quality >= 0 && opts.quality <= 1) {
|
1224
|
+
options.quality = opts.quality;
|
1225
|
+
}
|
1226
|
+
if (opts.mimeType == "jpeg" || opts.mimeType == "webp") {
|
1227
|
+
options.mimeType = opts.mimeType;
|
1228
|
+
}
|
1229
|
+
if (number$1.isNumber(opts.maxSize)) {
|
1230
|
+
options.maxSize = opts.maxSize;
|
1231
|
+
}
|
1232
|
+
if (number$1.isNumber(opts.minSize)) {
|
1233
|
+
options.minSize = opts.minSize;
|
1234
|
+
}
|
1235
|
+
}
|
1236
|
+
const createFile = (canvas, fileName, quality) => {
|
1237
|
+
let url = canvas.toDataURL("image/" + options.mimeType, quality);
|
1238
|
+
let file22 = this.dataBase64toFile(url, fileName);
|
1239
|
+
if (options.maxSize > 0 && file22.size > options.maxSize * 1024) {
|
1240
|
+
quality = quality <= 0 ? 0 : Number((quality - 0.01).toFixed(2));
|
1241
|
+
const res = createFile(canvas, fileName, quality);
|
1242
|
+
url = res.url;
|
1243
|
+
file22 = res.file;
|
1244
|
+
quality = res.quality;
|
1245
|
+
}
|
1246
|
+
return {
|
1247
|
+
file: file22,
|
1248
|
+
url,
|
1249
|
+
quality
|
1250
|
+
};
|
1251
|
+
};
|
1252
|
+
return new Promise((resolve, reject) => {
|
1253
|
+
let reader = new FileReader();
|
1254
|
+
reader.readAsDataURL(file2);
|
1255
|
+
reader.onload = () => {
|
1256
|
+
let url = reader.result;
|
1257
|
+
let img = new Image();
|
1258
|
+
img.src = url;
|
1259
|
+
img.onload = () => {
|
1260
|
+
if (options.minSize > 0 && file2.size <= options.minSize * 1024) {
|
1261
|
+
resolve({
|
1262
|
+
file: file2,
|
1263
|
+
url,
|
1264
|
+
quality: 1,
|
1265
|
+
width: img.width,
|
1266
|
+
height: img.height
|
1267
|
+
});
|
1268
|
+
return;
|
1269
|
+
}
|
1270
|
+
let canvas = document.createElement("canvas");
|
1271
|
+
let context = canvas.getContext("2d");
|
1272
|
+
canvas.width = options.width || img.width;
|
1273
|
+
canvas.height = options.width ? options.width / (img.width / img.height) : img.height;
|
1274
|
+
context.drawImage(img, 0, 0, canvas.width, canvas.height);
|
1275
|
+
let index = file2.name.lastIndexOf(".");
|
1276
|
+
const fileName = file2.name.substring(0, index) + "." + options.mimeType;
|
1277
|
+
let res = createFile(canvas, fileName, options.quality);
|
1278
|
+
resolve({
|
1279
|
+
...res,
|
1280
|
+
width: canvas.width,
|
1281
|
+
height: canvas.height
|
1282
|
+
});
|
1283
|
+
};
|
1284
|
+
img.onerror = () => {
|
1285
|
+
reject(new Error("Failed to load image file"));
|
1286
|
+
};
|
1287
|
+
};
|
1288
|
+
reader.onerror = () => {
|
1289
|
+
reject(new Error("Failed to load image file"));
|
1290
|
+
};
|
1291
|
+
});
|
1292
|
+
}
|
1293
|
+
};
|
1149
1294
|
const platform = {
|
1150
1295
|
//设备语言类型
|
1151
1296
|
language() {
|
@@ -1349,15 +1494,6 @@ const isContains = function(parentNode, childNode) {
|
|
1349
1494
|
}
|
1350
1495
|
return element$1.isContains(parentNode, childNode);
|
1351
1496
|
};
|
1352
|
-
const blobToBase64 = function(blob) {
|
1353
|
-
return new Promise((resolve) => {
|
1354
|
-
const fileReader = new FileReader();
|
1355
|
-
fileReader.onload = (e) => {
|
1356
|
-
resolve(e.target.result);
|
1357
|
-
};
|
1358
|
-
fileReader.readAsDataURL(blob);
|
1359
|
-
});
|
1360
|
-
};
|
1361
1497
|
const canUseClipboard = function() {
|
1362
1498
|
if (!window.ClipboardItem) {
|
1363
1499
|
console.warn("window.ClipboardItem must be obtained in a secure environment, such as localhost, 127.0.0.1, or https, so the editor's copy, paste, and cut functions cannot be used");
|
@@ -1395,6 +1531,7 @@ const initEditorOptions = function(options) {
|
|
1395
1531
|
customHtmlPaste: null,
|
1396
1532
|
customImagePaste: null,
|
1397
1533
|
customVideoPaste: null,
|
1534
|
+
customFilePaste: null,
|
1398
1535
|
customMerge: null,
|
1399
1536
|
customParseNode: null
|
1400
1537
|
};
|
@@ -1432,6 +1569,9 @@ const initEditorOptions = function(options) {
|
|
1432
1569
|
if (typeof options.customVideoPaste == "function") {
|
1433
1570
|
opts.customVideoPaste = options.customVideoPaste;
|
1434
1571
|
}
|
1572
|
+
if (typeof options.customFilePaste == "function") {
|
1573
|
+
opts.customFilePaste = options.customFilePaste;
|
1574
|
+
}
|
1435
1575
|
if (typeof options.customMerge == "function") {
|
1436
1576
|
opts.customMerge = options.customMerge;
|
1437
1577
|
}
|
@@ -2805,18 +2945,126 @@ const handleCut = async function(e) {
|
|
2805
2945
|
this.rangeRender();
|
2806
2946
|
}
|
2807
2947
|
};
|
2948
|
+
const doPaste = async function(html, text, files) {
|
2949
|
+
if (html) {
|
2950
|
+
if (this.allowPasteHtml) {
|
2951
|
+
const elements = this.parseHtml(html).filter((el) => {
|
2952
|
+
return !el.isEmpty();
|
2953
|
+
});
|
2954
|
+
if (typeof this.customHtmlPaste == "function") {
|
2955
|
+
await this.customHtmlPaste.apply(this, [elements, html]);
|
2956
|
+
} else {
|
2957
|
+
for (let i = 0; i < elements.length; i++) {
|
2958
|
+
this.insertElement(elements[i], false);
|
2959
|
+
}
|
2960
|
+
this.emit("pasteHtml", elements, html);
|
2961
|
+
}
|
2962
|
+
} else if (text) {
|
2963
|
+
if (typeof this.customTextPaste == "function") {
|
2964
|
+
await this.customTextPaste.apply(this, [text]);
|
2965
|
+
} else {
|
2966
|
+
this.insertText(text);
|
2967
|
+
this.emit("pasteText", text);
|
2968
|
+
}
|
2969
|
+
}
|
2970
|
+
} else {
|
2971
|
+
if (text) {
|
2972
|
+
if (typeof this.customTextPaste == "function") {
|
2973
|
+
await this.customTextPaste.apply(this, [text]);
|
2974
|
+
} else {
|
2975
|
+
this.insertText(text);
|
2976
|
+
this.emit("pasteText", text);
|
2977
|
+
}
|
2978
|
+
} else {
|
2979
|
+
let length = files.length;
|
2980
|
+
for (let i = 0; i < length; i++) {
|
2981
|
+
const url = await file$1.dataFileToBase64(files[i]);
|
2982
|
+
if (files[i].type.startsWith("image/")) {
|
2983
|
+
if (typeof this.customImagePaste == "function") {
|
2984
|
+
await this.customImagePaste.apply(this, [url]);
|
2985
|
+
} else {
|
2986
|
+
const image = new AlexElement(
|
2987
|
+
"closed",
|
2988
|
+
"img",
|
2989
|
+
{
|
2990
|
+
src: url
|
2991
|
+
},
|
2992
|
+
null,
|
2993
|
+
null
|
2994
|
+
);
|
2995
|
+
this.insertElement(image);
|
2996
|
+
this.emit("pasteImage", url);
|
2997
|
+
}
|
2998
|
+
} else if (files[i].type.startsWith("video/")) {
|
2999
|
+
if (typeof this.customVideoPaste == "function") {
|
3000
|
+
await this.customVideoPaste.apply(this, [url]);
|
3001
|
+
} else {
|
3002
|
+
const video = new AlexElement(
|
3003
|
+
"closed",
|
3004
|
+
"video",
|
3005
|
+
{
|
3006
|
+
src: url
|
3007
|
+
},
|
3008
|
+
null,
|
3009
|
+
null
|
3010
|
+
);
|
3011
|
+
this.insertElement(video);
|
3012
|
+
this.emit("pasteVideo", url);
|
3013
|
+
}
|
3014
|
+
} else {
|
3015
|
+
if (typeof this.customFilePaste == "function") {
|
3016
|
+
await this.customFilePaste.apply(this, [url]);
|
3017
|
+
}
|
3018
|
+
}
|
3019
|
+
}
|
3020
|
+
}
|
3021
|
+
}
|
3022
|
+
};
|
2808
3023
|
const handlePaste = async function(e) {
|
2809
3024
|
e.preventDefault();
|
2810
3025
|
if (this.disabled) {
|
2811
3026
|
return;
|
2812
3027
|
}
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
this.
|
3028
|
+
if (!this.range) {
|
3029
|
+
return;
|
3030
|
+
}
|
3031
|
+
if (!this.allowPaste) {
|
3032
|
+
return;
|
3033
|
+
}
|
3034
|
+
const event2 = e;
|
3035
|
+
if (event2.clipboardData) {
|
3036
|
+
const html = event2.clipboardData.getData("text/html");
|
3037
|
+
const text = event2.clipboardData.getData("text/plain");
|
3038
|
+
const files = event2.clipboardData.files;
|
3039
|
+
await doPaste.apply(this, [html, text, files]);
|
3040
|
+
this.formatElementStack();
|
3041
|
+
this.domRender();
|
3042
|
+
this.rangeRender();
|
3043
|
+
}
|
2817
3044
|
};
|
2818
|
-
const handleDragDrop = function(e) {
|
3045
|
+
const handleDragDrop = async function(e) {
|
2819
3046
|
e.preventDefault();
|
3047
|
+
if (e.type == "drop") {
|
3048
|
+
if (this.disabled) {
|
3049
|
+
return;
|
3050
|
+
}
|
3051
|
+
if (!this.range) {
|
3052
|
+
return;
|
3053
|
+
}
|
3054
|
+
if (!this.allowPaste) {
|
3055
|
+
return;
|
3056
|
+
}
|
3057
|
+
const event2 = e;
|
3058
|
+
if (event2.dataTransfer) {
|
3059
|
+
const html = event2.dataTransfer.getData("text/html");
|
3060
|
+
const text = event2.dataTransfer.getData("text/plain");
|
3061
|
+
const files = event2.dataTransfer.files;
|
3062
|
+
await doPaste.apply(this, [html, text, files]);
|
3063
|
+
this.formatElementStack();
|
3064
|
+
this.domRender();
|
3065
|
+
this.rangeRender();
|
3066
|
+
}
|
3067
|
+
}
|
2820
3068
|
};
|
2821
3069
|
const handleFocus = function() {
|
2822
3070
|
if (this.disabled) {
|
@@ -2844,6 +3092,7 @@ class AlexEditor {
|
|
2844
3092
|
__publicField(this, "customHtmlPaste");
|
2845
3093
|
__publicField(this, "customImagePaste");
|
2846
3094
|
__publicField(this, "customVideoPaste");
|
3095
|
+
__publicField(this, "customFilePaste");
|
2847
3096
|
__publicField(this, "customMerge");
|
2848
3097
|
__publicField(this, "customParseNode");
|
2849
3098
|
__publicField(this, "useClipboard", canUseClipboard());
|
@@ -2869,6 +3118,7 @@ class AlexEditor {
|
|
2869
3118
|
this.customHtmlPaste = options.customHtmlPaste;
|
2870
3119
|
this.customImagePaste = options.customImagePaste;
|
2871
3120
|
this.customVideoPaste = options.customVideoPaste;
|
3121
|
+
this.customFilePaste = options.customFilePaste;
|
2872
3122
|
this.customMerge = options.customMerge;
|
2873
3123
|
this.customParseNode = options.customParseNode;
|
2874
3124
|
this.stack = this.parseHtml(this.value);
|
@@ -2881,7 +3131,7 @@ class AlexEditor {
|
|
2881
3131
|
event$1.on(this.$el, "cut.alex_editor", handleCut.bind(this));
|
2882
3132
|
event$1.on(this.$el, "paste.alex_editor", handlePaste.bind(this));
|
2883
3133
|
event$1.on(this.$el, "copy.alex_editor", handleCopy.bind(this));
|
2884
|
-
event$1.on(this.$el, "dragstart.alex_editor drop.alex_editor
|
3134
|
+
event$1.on(this.$el, "dragstart.alex_editor drop.alex_editor", handleDragDrop.bind(this));
|
2885
3135
|
event$1.on(this.$el, "focus.alex_editor", handleFocus.bind(this));
|
2886
3136
|
event$1.on(this.$el, "blur.alex_editor", handleBlur.bind(this));
|
2887
3137
|
}
|
@@ -2958,114 +3208,6 @@ class AlexEditor {
|
|
2958
3208
|
}
|
2959
3209
|
return result;
|
2960
3210
|
}
|
2961
|
-
/**
|
2962
|
-
* 根据光标进行粘贴操作
|
2963
|
-
*/
|
2964
|
-
async paste() {
|
2965
|
-
if (this.disabled) {
|
2966
|
-
return;
|
2967
|
-
}
|
2968
|
-
if (!this.range) {
|
2969
|
-
return;
|
2970
|
-
}
|
2971
|
-
if (!this.useClipboard) {
|
2972
|
-
return;
|
2973
|
-
}
|
2974
|
-
if (!this.allowPaste) {
|
2975
|
-
return;
|
2976
|
-
}
|
2977
|
-
const clipboardItems = await navigator.clipboard.read();
|
2978
|
-
const clipboardItem = clipboardItems[0];
|
2979
|
-
const getTypeFunctions = [];
|
2980
|
-
clipboardItem.types.forEach((type) => {
|
2981
|
-
getTypeFunctions.push(clipboardItem.getType(type));
|
2982
|
-
});
|
2983
|
-
const blobs = await Promise.all(getTypeFunctions);
|
2984
|
-
const length = blobs.length;
|
2985
|
-
const hasHtml = blobs.some((blob) => {
|
2986
|
-
return blob.type == "text/html";
|
2987
|
-
});
|
2988
|
-
if (hasHtml) {
|
2989
|
-
for (let i = 0; i < length; i++) {
|
2990
|
-
const blob = blobs[i];
|
2991
|
-
if (blob.type == "text/plain" && !this.allowPasteHtml) {
|
2992
|
-
const data2 = await blob.text();
|
2993
|
-
if (data2) {
|
2994
|
-
if (typeof this.customTextPaste == "function") {
|
2995
|
-
await this.customTextPaste.apply(this, [data2]);
|
2996
|
-
} else {
|
2997
|
-
this.insertText(data2);
|
2998
|
-
this.emit("pasteText", data2);
|
2999
|
-
}
|
3000
|
-
}
|
3001
|
-
} else if (blob.type == "text/html" && this.allowPasteHtml) {
|
3002
|
-
const data2 = await blob.text();
|
3003
|
-
if (data2) {
|
3004
|
-
const elements = this.parseHtml(data2).filter((el) => {
|
3005
|
-
return !el.isEmpty();
|
3006
|
-
});
|
3007
|
-
if (typeof this.customHtmlPaste == "function") {
|
3008
|
-
await this.customHtmlPaste.apply(this, [elements, data2]);
|
3009
|
-
} else {
|
3010
|
-
for (let i2 = 0; i2 < elements.length; i2++) {
|
3011
|
-
this.insertElement(elements[i2], false);
|
3012
|
-
}
|
3013
|
-
this.emit("pasteHtml", elements, data2);
|
3014
|
-
}
|
3015
|
-
}
|
3016
|
-
}
|
3017
|
-
}
|
3018
|
-
} else {
|
3019
|
-
for (let i = 0; i < length; i++) {
|
3020
|
-
const blob = blobs[i];
|
3021
|
-
if (blob.type.startsWith("image/")) {
|
3022
|
-
const url = await blobToBase64(blob);
|
3023
|
-
if (typeof this.customImagePaste == "function") {
|
3024
|
-
await this.customImagePaste.apply(this, [url]);
|
3025
|
-
} else {
|
3026
|
-
const image = new AlexElement(
|
3027
|
-
"closed",
|
3028
|
-
"img",
|
3029
|
-
{
|
3030
|
-
src: url
|
3031
|
-
},
|
3032
|
-
null,
|
3033
|
-
null
|
3034
|
-
);
|
3035
|
-
this.insertElement(image);
|
3036
|
-
this.emit("pasteImage", url);
|
3037
|
-
}
|
3038
|
-
} else if (blob.type.startsWith("video/")) {
|
3039
|
-
const url = await blobToBase64(blob);
|
3040
|
-
if (typeof this.customVideoPaste == "function") {
|
3041
|
-
await this.customVideoPaste.apply(this, [url]);
|
3042
|
-
} else {
|
3043
|
-
const video = new AlexElement(
|
3044
|
-
"closed",
|
3045
|
-
"video",
|
3046
|
-
{
|
3047
|
-
src: url
|
3048
|
-
},
|
3049
|
-
null,
|
3050
|
-
null
|
3051
|
-
);
|
3052
|
-
this.insertElement(video);
|
3053
|
-
this.emit("pasteVideo", url);
|
3054
|
-
}
|
3055
|
-
} else if (blob.type == "text/plain") {
|
3056
|
-
const data2 = await blob.text();
|
3057
|
-
if (data2) {
|
3058
|
-
if (typeof this.customTextPaste == "function") {
|
3059
|
-
await this.customTextPaste.apply(this, [data2]);
|
3060
|
-
} else {
|
3061
|
-
this.insertText(data2);
|
3062
|
-
this.emit("pasteText", data2);
|
3063
|
-
}
|
3064
|
-
}
|
3065
|
-
}
|
3066
|
-
}
|
3067
|
-
}
|
3068
|
-
}
|
3069
3211
|
/**
|
3070
3212
|
* 根据光标进行删除操作
|
3071
3213
|
*/
|
@@ -3789,6 +3931,9 @@ class AlexEditor {
|
|
3789
3931
|
const marks = getAttributes(node);
|
3790
3932
|
const styles = getStyles(node);
|
3791
3933
|
const parsedom = node.nodeName.toLocaleLowerCase();
|
3934
|
+
if (parsedom == "style" || parsedom == "meta" || parsedom == "script" || parsedom == "link") {
|
3935
|
+
return new AlexElement("text", null, null, null, null);
|
3936
|
+
}
|
3792
3937
|
const block = blockParse.find((item) => item.parsedom == parsedom);
|
3793
3938
|
const inblock = inblockParse.find((item) => item.parsedom == parsedom);
|
3794
3939
|
const inline = inlineParse.find((item) => item.parsedom == parsedom);
|
@@ -20537,7 +20682,8 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
20537
20682
|
"show-triangle": "",
|
20538
20683
|
color: "#fff",
|
20539
20684
|
placement: "bottom",
|
20540
|
-
animation: "fade"
|
20685
|
+
animation: "fade",
|
20686
|
+
"z-index": 10
|
20541
20687
|
}, {
|
20542
20688
|
default: withCtx(() => [
|
20543
20689
|
createElementVNode("div", _hoisted_1$a, toDisplayString(_ctx.content), 1)
|
@@ -20548,7 +20694,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
20548
20694
|
};
|
20549
20695
|
}
|
20550
20696
|
});
|
20551
|
-
const Tooltip = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-
|
20697
|
+
const Tooltip = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-8372de0b"]]);
|
20552
20698
|
const IconProps = {
|
20553
20699
|
//图标值
|
20554
20700
|
value: {
|
@@ -21905,7 +22051,8 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
21905
22051
|
border: "",
|
21906
22052
|
placement: "bottom-start",
|
21907
22053
|
onShow: layerShow,
|
21908
|
-
useRange: _ctx.type == "text"
|
22054
|
+
useRange: _ctx.type == "text",
|
22055
|
+
"z-index": 10
|
21909
22056
|
}, {
|
21910
22057
|
default: withCtx(() => [
|
21911
22058
|
createElementVNode("div", {
|
@@ -22617,7 +22764,7 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
22617
22764
|
};
|
22618
22765
|
}
|
22619
22766
|
});
|
22620
|
-
const Toolbar = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-
|
22767
|
+
const Toolbar = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-44b03ca9"]]);
|
22621
22768
|
const InsertLinkProps = {
|
22622
22769
|
//主题色
|
22623
22770
|
color: {
|
@@ -24567,7 +24714,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
24567
24714
|
};
|
24568
24715
|
}
|
24569
24716
|
});
|
24570
|
-
const Menu = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-
|
24717
|
+
const Menu = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-226bbacd"]]);
|
24571
24718
|
const EditifyProps = {
|
24572
24719
|
//国际化语言类型
|
24573
24720
|
locale: {
|
@@ -24652,6 +24799,11 @@ const EditifyProps = {
|
|
24652
24799
|
type: Function,
|
24653
24800
|
default: null
|
24654
24801
|
},
|
24802
|
+
//自定义粘贴文件
|
24803
|
+
customFilePaste: {
|
24804
|
+
type: Function,
|
24805
|
+
default: null
|
24806
|
+
},
|
24655
24807
|
//菜单栏配置
|
24656
24808
|
menu: {
|
24657
24809
|
type: Object,
|
@@ -25075,8 +25227,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
25075
25227
|
allowPaste: props.allowPaste,
|
25076
25228
|
allowCut: props.allowCut,
|
25077
25229
|
allowPasteHtml: props.allowPasteHtml,
|
25078
|
-
customImagePaste:
|
25079
|
-
customVideoPaste:
|
25230
|
+
customImagePaste: props.customImagePaste,
|
25231
|
+
customVideoPaste: props.customVideoPaste,
|
25232
|
+
customFilePaste: props.customFilePaste,
|
25080
25233
|
customMerge: handleCustomMerge,
|
25081
25234
|
customParseNode: handleCustomParseNode
|
25082
25235
|
});
|
@@ -25206,18 +25359,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
25206
25359
|
}
|
25207
25360
|
}
|
25208
25361
|
};
|
25209
|
-
const handleCustomImagePaste = async (url) => {
|
25210
|
-
const newUrl = await props.customImagePaste.apply(instance.proxy, [url]);
|
25211
|
-
if (newUrl) {
|
25212
|
-
insertImage(editor.value, newUrl);
|
25213
|
-
}
|
25214
|
-
};
|
25215
|
-
const handleCustomVideoPaste = async (url) => {
|
25216
|
-
const newUrl = await props.customVideoPaste.apply(instance.proxy, [url]);
|
25217
|
-
if (newUrl) {
|
25218
|
-
insertVideo(editor.value, newUrl);
|
25219
|
-
}
|
25220
|
-
};
|
25221
25362
|
const handleCustomMerge = (ele, preEle) => {
|
25222
25363
|
const uneditable = preEle.getUneditableElement();
|
25223
25364
|
if (uneditable) {
|
@@ -25578,8 +25719,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
25578
25719
|
};
|
25579
25720
|
}
|
25580
25721
|
});
|
25581
|
-
const Editify = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
25582
|
-
const version = "0.1.
|
25722
|
+
const Editify = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-fed58116"]]);
|
25723
|
+
const version = "0.1.17";
|
25583
25724
|
const install = (app) => {
|
25584
25725
|
app.component(Editify.name, Editify);
|
25585
25726
|
};
|