@opentiny/fluent-editor 3.20.0 → 3.20.2-alpha.0
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/es/attributors/index.es.js +1 -1
- package/es/config/base64-image.es.js.map +1 -1
- package/es/config/editor.config.es.js.map +1 -1
- package/es/config/editor.utils.es.js +12 -12
- package/es/config/editor.utils.es.js.map +1 -1
- package/es/{config.es.js → config/index.es.js} +14 -7
- package/es/config/index.es.js.map +1 -0
- package/es/config/types/index.es.js +2 -2
- package/es/counter/index.es.js +2 -1
- package/es/counter/index.es.js.map +1 -1
- package/es/custom-clipboard.es.js +14 -14
- package/es/custom-clipboard.es.js.map +1 -1
- package/es/custom-image/BlotFormatter.es.js +1 -1
- package/es/custom-image/BlotFormatter.es.js.map +1 -1
- package/es/custom-image/actions/CustomResizeAction.es.js +6 -4
- package/es/custom-image/actions/CustomResizeAction.es.js.map +1 -1
- package/es/custom-image/image.es.js +3 -3
- package/es/custom-image/image.es.js.map +1 -1
- package/es/custom-image/specs/BlotSpec.es.js.map +1 -1
- package/es/custom-uploader.es.js +4 -7
- package/es/custom-uploader.es.js.map +1 -1
- package/es/emoji/emoji-list/people.es.js.map +1 -1
- package/es/emoji/formats/emoji-blot.es.js +2 -2
- package/es/emoji/formats/emoji-blot.es.js.map +1 -1
- package/es/emoji/modules/emoji.es.js +7 -7
- package/es/emoji/modules/emoji.es.js.map +1 -1
- package/es/emoji/modules/toolbar-emoji.es.js +15 -15
- package/es/emoji/modules/toolbar-emoji.es.js.map +1 -1
- package/es/file/modules/file-bar.es.js +3 -3
- package/es/file/modules/file-bar.es.js.map +1 -1
- package/es/fluent-editor.es.js +4 -4
- package/es/fluent-editor.es.js.map +1 -1
- package/es/format-painter/index.es.js.map +1 -1
- package/es/global-link/formats/work-item-link.es.js.map +1 -1
- package/es/global-link/index.es.js +1 -1
- package/es/global-link/index.es.js.map +1 -1
- package/es/index.es.js +17 -1
- package/es/index.es.js.map +1 -1
- package/es/link/formats/link.es.js +1 -1
- package/es/link/formats/link.es.js.map +1 -1
- package/es/link/index.es.js.map +1 -1
- package/es/link/modules/tooltip.es.js +3 -3
- package/es/link/modules/tooltip.es.js.map +1 -1
- package/es/mention/Mention.es.js +7 -12
- package/es/mention/Mention.es.js.map +1 -1
- package/es/quick-menu/index.es.js +1 -1
- package/es/quick-menu/index.es.js.map +1 -1
- package/es/screenshot/index.es.js +42 -7
- package/es/screenshot/index.es.js.map +1 -1
- package/es/strike/index.es.js.map +1 -1
- package/es/syntax/index.es.js.map +1 -1
- package/es/table/better-table.es.js +4 -5
- package/es/table/better-table.es.js.map +1 -1
- package/es/table/formats/list.es.js +3 -3
- package/es/table/formats/list.es.js.map +1 -1
- package/es/table/formats/table.es.js +26 -27
- package/es/table/formats/table.es.js.map +1 -1
- package/es/table/modules/table-column-tool.es.js +8 -8
- package/es/table/modules/table-column-tool.es.js.map +1 -1
- package/es/table/modules/table-operation-menu.es.js +7 -8
- package/es/table/modules/table-operation-menu.es.js.map +1 -1
- package/es/table/modules/table-scroll-bar.es.js +1 -1
- package/es/table/modules/table-scroll-bar.es.js.map +1 -1
- package/es/table/modules/table-selection.es.js +0 -1
- package/es/table/modules/table-selection.es.js.map +1 -1
- package/es/table/utils/node-matchers.es.js +14 -14
- package/es/table/utils/node-matchers.es.js.map +1 -1
- package/es/toolbar/better-picker.es.js.map +1 -1
- package/es/toolbar/index.es.js +1 -1
- package/es/toolbar/index.es.js.map +1 -1
- package/es/utils/debounce.es.js.map +1 -1
- package/es/utils/image.es.js +26 -0
- package/es/utils/image.es.js.map +1 -0
- package/es/utils/method.es.js +2 -2
- package/es/utils/method.es.js.map +1 -1
- package/es/utils/scroll-lock.es.js +47 -0
- package/es/utils/scroll-lock.es.js.map +1 -0
- package/es/video/index.es.js +6 -3
- package/es/video/index.es.js.map +1 -1
- package/lib/attributors/index.cjs.js +2 -2
- package/lib/config/base64-image.cjs.js.map +1 -1
- package/lib/config/editor.config.cjs.js.map +1 -1
- package/lib/config/editor.utils.cjs.js +12 -12
- package/lib/config/editor.utils.cjs.js.map +1 -1
- package/lib/{config.cjs.js → config/index.cjs.js} +27 -21
- package/lib/config/index.cjs.js.map +1 -0
- package/lib/config/types/index.cjs.js +2 -2
- package/lib/counter/index.cjs.js +5 -4
- package/lib/counter/index.cjs.js.map +1 -1
- package/lib/custom-clipboard.cjs.js +14 -14
- package/lib/custom-clipboard.cjs.js.map +1 -1
- package/lib/custom-image/BlotFormatter.cjs.js +1 -1
- package/lib/custom-image/BlotFormatter.cjs.js.map +1 -1
- package/lib/custom-image/actions/CustomResizeAction.cjs.js +6 -4
- package/lib/custom-image/actions/CustomResizeAction.cjs.js.map +1 -1
- package/lib/custom-image/image.cjs.js +3 -3
- package/lib/custom-image/image.cjs.js.map +1 -1
- package/lib/custom-image/specs/BlotSpec.cjs.js.map +1 -1
- package/lib/custom-uploader.cjs.js +4 -7
- package/lib/custom-uploader.cjs.js.map +1 -1
- package/lib/emoji/emoji-list/people.cjs.js.map +1 -1
- package/lib/emoji/formats/emoji-blot.cjs.js +2 -2
- package/lib/emoji/formats/emoji-blot.cjs.js.map +1 -1
- package/lib/emoji/modules/emoji.cjs.js +7 -7
- package/lib/emoji/modules/emoji.cjs.js.map +1 -1
- package/lib/emoji/modules/toolbar-emoji.cjs.js +15 -15
- package/lib/emoji/modules/toolbar-emoji.cjs.js.map +1 -1
- package/lib/file/modules/file-bar.cjs.js +3 -3
- package/lib/file/modules/file-bar.cjs.js.map +1 -1
- package/lib/fluent-editor.cjs.js +32 -32
- package/lib/fluent-editor.cjs.js.map +1 -1
- package/lib/format-painter/index.cjs.js.map +1 -1
- package/lib/global-link/formats/work-item-link.cjs.js.map +1 -1
- package/lib/global-link/index.cjs.js +1 -1
- package/lib/global-link/index.cjs.js.map +1 -1
- package/lib/index.cjs.js +16 -0
- package/lib/index.cjs.js.map +1 -1
- package/lib/link/formats/link.cjs.js +1 -1
- package/lib/link/formats/link.cjs.js.map +1 -1
- package/lib/link/index.cjs.js.map +1 -1
- package/lib/link/modules/tooltip.cjs.js +3 -3
- package/lib/link/modules/tooltip.cjs.js.map +1 -1
- package/lib/mention/Mention.cjs.js +7 -12
- package/lib/mention/Mention.cjs.js.map +1 -1
- package/lib/quick-menu/index.cjs.js +1 -1
- package/lib/quick-menu/index.cjs.js.map +1 -1
- package/lib/screenshot/index.cjs.js +44 -9
- package/lib/screenshot/index.cjs.js.map +1 -1
- package/lib/strike/index.cjs.js.map +1 -1
- package/lib/syntax/index.cjs.js.map +1 -1
- package/lib/table/better-table.cjs.js +4 -5
- package/lib/table/better-table.cjs.js.map +1 -1
- package/lib/table/formats/list.cjs.js +3 -3
- package/lib/table/formats/list.cjs.js.map +1 -1
- package/lib/table/formats/table.cjs.js +26 -27
- package/lib/table/formats/table.cjs.js.map +1 -1
- package/lib/table/modules/table-column-tool.cjs.js +8 -8
- package/lib/table/modules/table-column-tool.cjs.js.map +1 -1
- package/lib/table/modules/table-operation-menu.cjs.js +7 -8
- package/lib/table/modules/table-operation-menu.cjs.js.map +1 -1
- package/lib/table/modules/table-scroll-bar.cjs.js +1 -1
- package/lib/table/modules/table-scroll-bar.cjs.js.map +1 -1
- package/lib/table/modules/table-selection.cjs.js +0 -1
- package/lib/table/modules/table-selection.cjs.js.map +1 -1
- package/lib/table/utils/node-matchers.cjs.js +14 -14
- package/lib/table/utils/node-matchers.cjs.js.map +1 -1
- package/lib/toolbar/better-picker.cjs.js.map +1 -1
- package/lib/toolbar/index.cjs.js +1 -1
- package/lib/toolbar/index.cjs.js.map +1 -1
- package/lib/utils/debounce.cjs.js.map +1 -1
- package/lib/utils/image.cjs.js +26 -0
- package/lib/utils/image.cjs.js.map +1 -0
- package/lib/utils/method.cjs.js +2 -2
- package/lib/utils/method.cjs.js.map +1 -1
- package/lib/utils/scroll-lock.cjs.js +47 -0
- package/lib/utils/scroll-lock.cjs.js.map +1 -0
- package/lib/video/index.cjs.js +6 -3
- package/lib/video/index.cjs.js.map +1 -1
- package/package.json +16 -28
- package/{theme/style.css → style.css} +86 -17
- package/es/config.es.js.map +0 -1
- package/es/types/vue.d.es.js +0 -2
- package/es/types/vue.d.es.js.map +0 -1
- package/lib/config.cjs.js.map +0 -1
- package/lib/types/vue.d.cjs.js +0 -2
- package/lib/types/vue.d.cjs.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../../../src/counter/index.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../../../src/counter/index.ts"],"sourcesContent":["import type { ICounterOption } from '../config/types'\r\nimport Quill from 'quill'\r\nimport { LANG_CONF } from '../config'\r\n\r\nexport default class Counter {\r\n container: HTMLDivElement\r\n options: ICounterOption\r\n defaultOptions: ICounterOption = {\r\n format: 'text',\r\n unit: 'char',\r\n template: LANG_CONF['counter-template'],\r\n count: 500,\r\n }\r\n\r\n // @ts-ignore\r\n constructor(private quill: Quill, options: ICounterOption) {\r\n this.options = { ...this.defaultOptions, ...options }\r\n this.container = quill.addContainer('ql-counter')\r\n quill.on(Quill.events.TEXT_CHANGE, this.renderCount)\r\n this.renderCount()\r\n }\r\n\r\n renderCount = () => {\r\n setTimeout(() => {\r\n // @ts-ignore\r\n const { format, count: totalCount, unit, template: counterTemplate, errorTemplate } = this.options\r\n const count = this.getContentLength(format)\r\n const restCount = totalCount - count\r\n const countUnit = unit === 'char' ? LANG_CONF.char : LANG_CONF.word\r\n let template: any = counterTemplate\r\n if (typeof template === 'function') {\r\n template = template(count, restCount)\r\n }\r\n const desc = template.replace('{{count}}', count)\r\n .replace('{{totalCount}}', String(totalCount))\r\n .replace('{{restCount}}', String(restCount))\r\n .replace(/{{countUnit}}/g, countUnit)\r\n\r\n let limitTemplate: any = errorTemplate || LANG_CONF['counter-limit-tips']\r\n if (typeof limitTemplate === 'function') {\r\n limitTemplate = limitTemplate(count, restCount)\r\n }\r\n const limitTips = limitTemplate.replace('{{countUnit}}', countUnit)\r\n if (restCount < 0) {\r\n this.container.innerHTML = errorTemplate ? limitTips : `<span style=\"color:red\">${limitTips}</span>`\r\n }\r\n else {\r\n this.container.innerHTML = desc\r\n }\r\n })\r\n }\r\n\r\n getContentLength(format) {\r\n let content = this.quill.getText()\r\n if (format === 'html') {\r\n let html = this.quill.root.innerHTML\r\n // 编辑器初始时\r\n if (html === '<p><br></p>' || html === '<div><br><div>') {\r\n html = ''\r\n }\r\n content = html\r\n }\r\n const text = content.replace(/\\s/g, '').trim()\r\n if (this.options.unit === 'word') {\r\n return !content.trim() ? 0 : content.trim().split(/\\s+/).length\r\n }\r\n return text.length\r\n }\r\n}\r\n"],"names":[],"mappings":";;;AAIA,MAAqB,QAAQ;AAAA;AAAA,EAW3B,YAAoB,OAAc,SAAyB;AAAvC,SAAA,QAAA;AARa,SAAA,iBAAA;AAAA,MAC/B,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,UAAU,UAAU,kBAAkB;AAAA,MACtC,OAAO;AAAA,IAAA;AAWT,SAAA,cAAc,MAAM;AAClB,iBAAW,MAAM;AAET,cAAA,EAAE,QAAQ,OAAO,YAAY,MAAM,UAAU,iBAAiB,cAAc,IAAI,KAAK;AACrF,cAAA,QAAQ,KAAK,iBAAiB,MAAM;AAC1C,cAAM,YAAY,aAAa;AAC/B,cAAM,YAAY,SAAS,SAAS,UAAU,OAAO,UAAU;AAC/D,YAAI,WAAgB;AAChB,YAAA,OAAO,aAAa,YAAY;AACvB,qBAAA,SAAS,OAAO,SAAS;AAAA,QACtC;AACM,cAAA,OAAO,SAAS,QAAQ,aAAa,KAAK,EAC7C,QAAQ,kBAAkB,OAAO,UAAU,CAAC,EAC5C,QAAQ,iBAAiB,OAAO,SAAS,CAAC,EAC1C,QAAQ,kBAAkB,SAAS;AAElC,YAAA,gBAAqB,iBAAiB,UAAU,oBAAoB;AACpE,YAAA,OAAO,kBAAkB,YAAY;AACvB,0BAAA,cAAc,OAAO,SAAS;AAAA,QAChD;AACA,cAAM,YAAY,cAAc,QAAQ,iBAAiB,SAAS;AAClE,YAAI,YAAY,GAAG;AACjB,eAAK,UAAU,YAAY,gBAAgB,YAAY,2BAA2B,SAAS;AAAA,QAAA,OAExF;AACH,eAAK,UAAU,YAAY;AAAA,QAC7B;AAAA,MAAA,CACD;AAAA,IAAA;AAjCD,SAAK,UAAU,EAAE,GAAG,KAAK,gBAAgB,GAAG;AACvC,SAAA,YAAY,MAAM,aAAa,YAAY;AAChD,UAAM,GAAG,MAAM,OAAO,aAAa,KAAK,WAAW;AACnD,SAAK,YAAY;AAAA,EACnB;AAAA,EAgCA,iBAAiB,QAAQ;AACnB,QAAA,UAAU,KAAK,MAAM,QAAQ;AACjC,QAAI,WAAW,QAAQ;AACjB,UAAA,OAAO,KAAK,MAAM,KAAK;AAEvB,UAAA,SAAS,iBAAiB,SAAS,kBAAkB;AAChD,eAAA;AAAA,MACT;AACU,gBAAA;AAAA,IACZ;AACA,UAAM,OAAO,QAAQ,QAAQ,OAAO,EAAE,EAAE;AACpC,QAAA,KAAK,QAAQ,SAAS,QAAQ;AACzB,aAAA,CAAC,QAAQ,KAAS,IAAA,IAAI,QAAQ,KAAK,EAAE,MAAM,KAAK,EAAE;AAAA,IAC3D;AACA,WAAO,KAAK;AAAA,EACd;AACF;"}
|
|
@@ -3,7 +3,7 @@ import { ERROR_IMAGE_PLACEHOLDER_EN, ERROR_IMAGE_PLACEHOLDER_CN } from "./config
|
|
|
3
3
|
import { BIG_DELTA_LIMIT, LANG_CONF } from "./config/editor.config.es.js";
|
|
4
4
|
import { isNullOrUndefined, insideTable, replaceDeltaImage, imageFileToUrl, imageUrlToFile, splitWithBreak, omit, hexToRgbA } from "./config/editor.utils.es.js";
|
|
5
5
|
const Clipboard = Quill.imports["modules/clipboard"];
|
|
6
|
-
const Delta = Quill.
|
|
6
|
+
const Delta = Quill.import("delta");
|
|
7
7
|
class CustomClipboard extends Clipboard {
|
|
8
8
|
prepareMatching(container, nodeMatches) {
|
|
9
9
|
const elementMatchers = [];
|
|
@@ -48,7 +48,7 @@ class CustomClipboard extends Clipboard {
|
|
|
48
48
|
e.clipboardData = {
|
|
49
49
|
types: "text/plain",
|
|
50
50
|
setData: (_type, value) => {
|
|
51
|
-
return window
|
|
51
|
+
return window.clipboardData.setData("Text", value);
|
|
52
52
|
}
|
|
53
53
|
};
|
|
54
54
|
}
|
|
@@ -75,7 +75,7 @@ class CustomClipboard extends Clipboard {
|
|
|
75
75
|
e.clipboardData = {
|
|
76
76
|
types: "text/plain",
|
|
77
77
|
getData: () => {
|
|
78
|
-
return window
|
|
78
|
+
return window.clipboardData.getData("Text");
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
}
|
|
@@ -100,7 +100,7 @@ class CustomClipboard extends Clipboard {
|
|
|
100
100
|
}
|
|
101
101
|
onPaste(range, { html, text, files: clipboardFiles, rtf }) {
|
|
102
102
|
const hexImages = this.extractImageDataFromRtf(rtf);
|
|
103
|
-
const rootBgColor = getComputedStyle(this.quill.root)
|
|
103
|
+
const rootBgColor = getComputedStyle(this.quill.root).backgroundColor;
|
|
104
104
|
const formats = this.quill.getFormat(range.index);
|
|
105
105
|
let pastedDelta = this.convert({ text, html }, formats);
|
|
106
106
|
pastedDelta = replaceDeltaWhiteSpace(pastedDelta, rootBgColor);
|
|
@@ -108,7 +108,7 @@ class CustomClipboard extends Clipboard {
|
|
|
108
108
|
let loadingTipsContainer;
|
|
109
109
|
if (deltaLength > BIG_DELTA_LIMIT) {
|
|
110
110
|
loadingTipsContainer = this.quill.addContainer("ql-loading-tips");
|
|
111
|
-
loadingTipsContainer.innerHTML = LANG_CONF
|
|
111
|
+
loadingTipsContainer.innerHTML = LANG_CONF.pasting;
|
|
112
112
|
}
|
|
113
113
|
const linePos = { index: range.index, length: range.length, fix: 0 };
|
|
114
114
|
const [line, offset] = this.quill.getLine(range.index);
|
|
@@ -116,7 +116,7 @@ class CustomClipboard extends Clipboard {
|
|
|
116
116
|
const handlePasteContent = (content) => {
|
|
117
117
|
let pastedContent = content;
|
|
118
118
|
const tableBreaker = pastedContent.ops.find((op) => {
|
|
119
|
-
return op.attributes && (op.attributes
|
|
119
|
+
return op.attributes && (op.attributes.blockquote || op.attributes["code-block"]);
|
|
120
120
|
});
|
|
121
121
|
if (isInsideTable) {
|
|
122
122
|
const table = line.domNode.closest("table.quill-better-table");
|
|
@@ -133,7 +133,7 @@ class CustomClipboard extends Clipboard {
|
|
|
133
133
|
linePos.length = 0;
|
|
134
134
|
} else if (range.index === tableEndPos - 1 && anchorNode instanceof HTMLDivElement && anchorNode.classList.contains("quill-better-table-wrapper")) {
|
|
135
135
|
const list = pastedContent.filter(
|
|
136
|
-
(op) => op.attributes && op.attributes
|
|
136
|
+
(op) => op.attributes && op.attributes.list
|
|
137
137
|
);
|
|
138
138
|
if (list && list.length) {
|
|
139
139
|
return;
|
|
@@ -150,7 +150,7 @@ class CustomClipboard extends Clipboard {
|
|
|
150
150
|
const isString = op.insert && typeof op.insert === "string";
|
|
151
151
|
const isLine = isString && regexp.test(op.insert);
|
|
152
152
|
const isCellLine = isLine && op.attributes && op.attributes["table-cell-line"];
|
|
153
|
-
const isList = isLine && op.attributes && op.attributes
|
|
153
|
+
const isList = isLine && op.attributes && op.attributes.list;
|
|
154
154
|
const isPureLine = isLine && !isCellLine && !isList;
|
|
155
155
|
const isTableCol = isLine && op.attributes && op.attributes["table-col"];
|
|
156
156
|
const isLastCellLine = isCellLine && index === deltaLength - 1;
|
|
@@ -164,7 +164,7 @@ class CustomClipboard extends Clipboard {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
const lastChild = pastedContent.ops[pastedContent.ops.length - 1];
|
|
167
|
-
const hasList = lastChild && lastChild.attributes && lastChild.attributes
|
|
167
|
+
const hasList = lastChild && lastChild.attributes && lastChild.attributes.list;
|
|
168
168
|
if (hasList && offset === 0 && line && line.cache.length === 1 && (line.statics.blotName === "block" || line.statics.blotName === "table-cell-line") && (!line.next || line.next.statics.blotName !== "table-view")) {
|
|
169
169
|
linePos.index = this.quill.getIndex(line);
|
|
170
170
|
linePos.length = line.length();
|
|
@@ -238,7 +238,7 @@ class CustomClipboard extends Clipboard {
|
|
|
238
238
|
}
|
|
239
239
|
files2urls(files, placeholders, originalUrls, pastedDelta, imageIndexs) {
|
|
240
240
|
return Promise.all(
|
|
241
|
-
files.map((imageFile, index) => {
|
|
241
|
+
files.map(async (imageFile, index) => {
|
|
242
242
|
const netImgExp = /^((http|https)\:)?\/\/([\s\S]+)$/;
|
|
243
243
|
if (!placeholders[index] && originalUrls[index] && netImgExp.test(originalUrls[index])) {
|
|
244
244
|
return new Promise((resolve) => {
|
|
@@ -275,7 +275,7 @@ class CustomClipboard extends Clipboard {
|
|
|
275
275
|
convertHexToBase64(hexString) {
|
|
276
276
|
return btoa(
|
|
277
277
|
hexString.match(/\w{2}/g).map((char) => {
|
|
278
|
-
return String.fromCharCode(parseInt(char, 16));
|
|
278
|
+
return String.fromCharCode(Number.parseInt(char, 16));
|
|
279
279
|
}).join("")
|
|
280
280
|
);
|
|
281
281
|
}
|
|
@@ -286,7 +286,7 @@ class CustomClipboard extends Clipboard {
|
|
|
286
286
|
}
|
|
287
287
|
const regexPictureHeader = /{\\pict[\s\S]+?\\bliptag-?\d+(\\blipupi-?\d+)?({\\\*\\blipuid\s?[\da-fA-F]+)?[\s}]*?/;
|
|
288
288
|
const regexPicture = new RegExp(
|
|
289
|
-
|
|
289
|
+
`(?:(${regexPictureHeader.source}))([\\da-fA-F\\s]+)\\}`,
|
|
290
290
|
"g"
|
|
291
291
|
);
|
|
292
292
|
const images = rtfData.match(regexPicture);
|
|
@@ -447,7 +447,7 @@ function renderStyles(html) {
|
|
|
447
447
|
iframeDoc.close();
|
|
448
448
|
let collection;
|
|
449
449
|
let pointer;
|
|
450
|
-
const rules = iframeDoc.styleSheets[iframeDoc.styleSheets.length - 1]
|
|
450
|
+
const rules = iframeDoc.styleSheets[iframeDoc.styleSheets.length - 1].cssRules;
|
|
451
451
|
for (let idx = 0; idx < rules.length; idx++) {
|
|
452
452
|
if (rules[idx].selectorText === "") {
|
|
453
453
|
continue;
|
|
@@ -459,7 +459,7 @@ function renderStyles(html) {
|
|
|
459
459
|
collection[pointer].style.cssText += rules[idx].style.cssText;
|
|
460
460
|
}
|
|
461
461
|
}
|
|
462
|
-
const convertedString = iframeDoc.firstChild
|
|
462
|
+
const convertedString = iframeDoc.firstChild.outerHTML;
|
|
463
463
|
iframe.parentNode.removeChild(iframe);
|
|
464
464
|
return convertedString;
|
|
465
465
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-clipboard.es.js","sources":["../../src/custom-clipboard.ts"],"sourcesContent":["import Quill from 'quill'\r\nimport {\r\n ERROR_IMAGE_PLACEHOLDER_CN,\r\n ERROR_IMAGE_PLACEHOLDER_EN,\r\n} from './config/base64-image'\r\nimport { BIG_DELTA_LIMIT, LANG_CONF } from './config/editor.config'\r\nimport {\r\n hexToRgbA,\r\n imageFileToUrl,\r\n imageUrlToFile,\r\n insideTable,\r\n isNullOrUndefined,\r\n omit,\r\n replaceDeltaImage,\r\n splitWithBreak,\r\n} from './config/editor.utils'\r\n\r\nconst Clipboard = Quill.imports['modules/clipboard']\r\nconst Delta = Quill.imports['delta']\r\n\r\nclass CustomClipboard extends Clipboard {\r\n quill\r\n convert\r\n onCopy\r\n matchers\r\n\r\n prepareMatching(container, nodeMatches) {\r\n const elementMatchers = []\r\n const textMatchers = []\r\n this.matchers.forEach((pair) => {\r\n const [selector, matcher] = pair\r\n switch (selector) {\r\n case Node.TEXT_NODE:\r\n textMatchers.push(matcher)\r\n break\r\n case Node.ELEMENT_NODE:\r\n elementMatchers.push(matcher)\r\n break\r\n default: {\r\n // word 的 v:shape 系列标签只能通过 getElementsByTagName 获取\r\n const vRegex = /v:(.+)/\r\n const nodeList = vRegex.test(selector)\r\n ? Array.from(container.getElementsByTagName(selector))\r\n : Array.from(container.querySelectorAll(selector))\r\n nodeList.forEach((node) => {\r\n if (nodeMatches.has(node)) {\r\n const matches = nodeMatches.get(node)\r\n matches.push(matcher)\r\n }\r\n else {\r\n nodeMatches.set(node, [matcher])\r\n }\r\n })\r\n break\r\n }\r\n }\r\n })\r\n return [elementMatchers, textMatchers]\r\n }\r\n\r\n onCaptureCopy(e, isCut = false) {\r\n if (e.defaultPrevented) {\r\n return\r\n }\r\n e.preventDefault()\r\n const [range] = this.quill.selection.getRange()\r\n if (isNullOrUndefined(range)) {\r\n return\r\n }\r\n const { html, text } = this.onCopy(range, isCut)\r\n\r\n // 兼容IE11浏览器`\r\n if (!e.clipboardData) {\r\n e.clipboardData = {\r\n types: 'text/plain',\r\n setData: (_type, value) => {\r\n return window['clipboardData'].setData('Text', value)\r\n },\r\n }\r\n }\r\n\r\n // 复制代码时移除utf8中产生的不间断空格\\u00A0\r\n let plainText = text\r\n if (html.startsWith('<pre>')) {\r\n plainText = text.replace(/\\u00A0/g, ' ')\r\n }\r\n\r\n e.clipboardData.setData('text/html', html)\r\n e.clipboardData.setData('text/plain', plainText)\r\n if (isCut) {\r\n this.quill.deleteText(range, Quill.sources.USER)\r\n }\r\n }\r\n\r\n onCapturePaste(e) {\r\n if (e.defaultPrevented || !this.quill.isEnabled()) {\r\n return\r\n }\r\n e.preventDefault()\r\n const range = this.quill.getSelection(true)\r\n if (isNullOrUndefined(range)) {\r\n return\r\n }\r\n\r\n // 兼容IE11浏览器\r\n if (!e.clipboardData) {\r\n e.clipboardData = {\r\n types: 'text/plain',\r\n getData: () => {\r\n return window['clipboardData'].getData('Text')\r\n },\r\n }\r\n }\r\n\r\n const html = e.clipboardData.getData('text/html')\r\n const text = e.clipboardData.getData('text/plain')\r\n const files = Array.from(e.clipboardData.files || [])\r\n const msExcelCheck = /<meta.*?Microsoft Excel\\s[\\d].*?>/\r\n\r\n if (html.search(msExcelCheck) === -1 && files.length > 0) {\r\n this.quill.uploader.upload(range, files)\r\n }\r\n else {\r\n const msWordCheck1\r\n = /<meta\\s*name=\"?generator\"?\\s*content=\"?microsoft\\s*word\\s*\\d+\"?\\/?>/i\r\n const msWordCheck2 = /xmlns:o=\"urn:schemas-microsoft-com/i\r\n const result = { html, text, files, rtf: null }\r\n if (html.search(msExcelCheck) !== -1) {\r\n result.html = renderStyles(html)\r\n }\r\n if (msWordCheck1.test(html) || msWordCheck2.test(html)) {\r\n // TODO: 当word文档包含heading时text/rtf读取为空,无法获取hex图片,待修复。可参考ckeditor5/issues/2493\r\n result.rtf = e.clipboardData.getData('text/rtf')\r\n }\r\n this.onPaste(range, result)\r\n }\r\n }\r\n\r\n onPaste(range, { html, text, files: clipboardFiles, rtf }) {\r\n const hexImages = this.extractImageDataFromRtf(rtf)\r\n const rootBgColor = getComputedStyle(this.quill.root)['backgroundColor']\r\n const formats = this.quill.getFormat(range.index)\r\n let pastedDelta = this.convert({ text, html }, formats)\r\n pastedDelta = replaceDeltaWhiteSpace(pastedDelta, rootBgColor)\r\n const deltaLength = pastedDelta.ops.length\r\n\r\n let loadingTipsContainer\r\n if (deltaLength > BIG_DELTA_LIMIT) {\r\n loadingTipsContainer = this.quill.addContainer('ql-loading-tips')\r\n loadingTipsContainer.innerHTML = LANG_CONF['pasting']\r\n }\r\n\r\n const linePos = { index: range.index, length: range.length, fix: 0 }\r\n const [line, offset] = this.quill.getLine(range.index)\r\n const isInsideTable = insideTable.call(this)\r\n\r\n const handlePasteContent = (content: any) => {\r\n let pastedContent = content\r\n // fix: 阻止粘贴代码块和引用导致表格断裂\r\n const tableBreaker = pastedContent.ops.find((op) => {\r\n return (\r\n op.attributes\r\n && (op.attributes['blockquote'] || op.attributes['code-block'])\r\n )\r\n })\r\n if (isInsideTable) {\r\n // fix: 阻止带有表格内容粘贴在表格里\r\n const table = line.domNode.closest('table.quill-better-table')\r\n const tableBlot = Quill.find(table)\r\n const tableIndex = this.quill.getIndex(tableBlot)\r\n const tableLength = tableBlot.length()\r\n const tableEndPos = tableIndex + tableLength\r\n const anchorNode = getSelection().anchorNode\r\n if (tableBreaker) {\r\n return\r\n }\r\n if (formats['table-col']) {\r\n // fix: 光标在表格前端的table-col处时,获取整个表格的index后以此为基准向前移动一位插入粘贴内容且不删除任何内容\r\n linePos.index = tableIndex - 1\r\n linePos.length = 0\r\n }\r\n else if (\r\n range.index === tableEndPos - 1\r\n && anchorNode instanceof HTMLDivElement\r\n && anchorNode.classList.contains('quill-better-table-wrapper')\r\n ) {\r\n const list = pastedContent.filter(\r\n op => op.attributes && op.attributes['list'],\r\n )\r\n if (list && list.length) {\r\n return\r\n }\r\n // fix: 光标在表格末端时,向后移动一位插入粘贴内容且不删除任何内容\r\n // TODO\r\n // 当表格最后一格有内容时,没法区分在表格最后一格最末尾和光标在表格后这两种情况,它们的 range 是一样\r\n // 这会导致在这两处粘贴表格内容都会将该内容粘贴到表格下一行中\r\n linePos.index = tableEndPos\r\n linePos.length = 0\r\n }\r\n else {\r\n if (!formats['table-cell-line']) {\r\n return\r\n }\r\n // fix: 解决表格内粘贴问题\r\n // 缺陷描述:将表格内的换行文本复制粘贴到别的单元格,会导致表格断开\r\n // 原因是:换行的文本delta对象有问题,delta对象前面多了一个纯换行和表格控制头(table-col)\r\n // 解决方法:将多余的delta项移除\r\n pastedContent = {\r\n ops: pastedContent.filter((op, index) => {\r\n const regexp = /^[\\n\\r]+$/\r\n const isString = op.insert && typeof op.insert === 'string'\r\n const isLine = isString && regexp.test(op.insert)\r\n const isCellLine\r\n = isLine && op.attributes && op.attributes['table-cell-line']\r\n const isList = isLine && op.attributes && op.attributes['list']\r\n const isPureLine = isLine && !isCellLine && !isList\r\n const isTableCol\r\n = isLine && op.attributes && op.attributes['table-col']\r\n const isLastCellLine = isCellLine && index === deltaLength - 1\r\n return !isPureLine && !isTableCol && !isLastCellLine\r\n }),\r\n }\r\n // fix: 解决从表格外粘贴多行文本导致表格断开的问题\r\n pastedContent = rebuildDelta(\r\n new Delta(pastedContent.ops),\r\n formats['table-cell-line'],\r\n )\r\n }\r\n }\r\n\r\n // fix: 粘贴内容末尾为List,且粘贴位置的block或table-cell-line无内容则删除该block或table-cell-line\r\n // TODO 这里的lastChild如果不存在,则可能报错\r\n const lastChild = pastedContent.ops[pastedContent.ops.length - 1]\r\n const hasList\r\n = lastChild && lastChild.attributes && lastChild.attributes['list']\r\n if (\r\n hasList\r\n && offset === 0\r\n && line\r\n && line.cache.length === 1\r\n && (line.statics.blotName === 'block'\r\n || line.statics.blotName === 'table-cell-line')\r\n && (!line.next || line.next.statics.blotName !== 'table-view')\r\n ) {\r\n linePos.index = this.quill.getIndex(line)\r\n linePos.length = line.length()\r\n linePos.fix = 1\r\n }\r\n\r\n const oldDelta = new Delta().retain(linePos.index).delete(linePos.length)\r\n const delta = oldDelta.concat(pastedContent)\r\n\r\n setTimeout(() => {\r\n this.quill.updateContents(delta, Quill.sources.USER)\r\n this.quill.setSelection(\r\n delta.length() - linePos.length - linePos.fix,\r\n Quill.sources.SILENT,\r\n )\r\n this.quill.scrollIntoView()\r\n if (loadingTipsContainer) {\r\n loadingTipsContainer.remove()\r\n }\r\n })\r\n }\r\n\r\n ;(async () => {\r\n try {\r\n const [files, placeholders, originalUrls, imageIndexs] = this.flipFilesArray(\r\n await this.extractFilesFromDelta(\r\n pastedDelta,\r\n clipboardFiles,\r\n hexImages,\r\n ),\r\n )\r\n\r\n if (files.length === 0) {\r\n handlePasteContent(pastedDelta)\r\n }\r\n else {\r\n if (this.quill.options.editorPaste && this.quill.options.editorPaste.observers.length !== 0) {\r\n // 设置editorPaste回调的情况\r\n this.quill.options.editorPaste.emit({\r\n files: files,\r\n callback: ({ code, message, data }) => {\r\n if (code === 0) {\r\n const { imageUrls } = data\r\n pastedDelta = replaceDeltaImage(\r\n pastedDelta,\r\n imageUrls,\r\n placeholders,\r\n )\r\n handlePasteContent(pastedDelta)\r\n }\r\n else {\r\n console.error('error message:', message)\r\n }\r\n },\r\n })\r\n }\r\n else {\r\n // 没有originalUrls 也没有文件粘贴\r\n if (files[0] !== undefined || originalUrls.length === 0) {\r\n // 没有设置editorPaste回调的情况下,File格式的占位图需要手动转换成url格式,插入到编辑器中\r\n const imageUrls = await this.files2urls(\r\n files,\r\n placeholders,\r\n originalUrls,\r\n pastedDelta,\r\n imageIndexs,\r\n )\r\n pastedDelta = replaceDeltaImage(\r\n pastedDelta,\r\n imageUrls,\r\n placeholders,\r\n )\r\n }\r\n handlePasteContent(pastedDelta)\r\n }\r\n }\r\n }\r\n catch (_e) {\r\n throw new Error('Paste failed.')\r\n }\r\n })()\r\n }\r\n\r\n files2urls(files, placeholders, originalUrls, pastedDelta, imageIndexs) {\r\n return Promise.all(\r\n files.map((imageFile, index) => {\r\n const netImgExp = /^((http|https)\\:)?\\/\\/([\\s\\S]+)$/\r\n if (\r\n !placeholders[index]\r\n && originalUrls[index]\r\n && netImgExp.test(originalUrls[index])\r\n ) {\r\n // 不是占位图的普通url图片直接返回url\r\n return new Promise((resolve) => {\r\n resolve(originalUrls[index])\r\n })\r\n }\r\n else if (this.quill.options.uploadOption.imageUploadToServer) {\r\n const range = this.getImgSelection(pastedDelta, imageIndexs[index])\r\n this.quill.uploader.upload(range, [imageFile])\r\n }\r\n else {\r\n // 占位图或者跨域图需要手动转换成url格式\r\n return imageFileToUrl(imageFile)\r\n }\r\n }),\r\n )\r\n }\r\n\r\n flipFilesArray(filesArr) {\r\n const files = []\r\n const placeholders = []\r\n const originalUrls = []\r\n const imageIndexs = []\r\n filesArr.forEach((item: any) => {\r\n if (item) {\r\n const [file, placeholder, originalUrl, imageIndex] = item\r\n files.push(file)\r\n placeholders.push(placeholder)\r\n originalUrls.push(originalUrl)\r\n if (imageIndex === 0 || imageIndex) {\r\n imageIndexs.push(imageIndex)\r\n }\r\n }\r\n })\r\n return [files, placeholders, originalUrls, imageIndexs]\r\n }\r\n\r\n // 将图片从hex转为base64\r\n convertHexToBase64(hexString) {\r\n return btoa(\r\n hexString\r\n .match(/\\w{2}/g)\r\n .map((char) => {\r\n return String.fromCharCode(parseInt(char, 16))\r\n })\r\n .join(''),\r\n )\r\n }\r\n\r\n // 匹配rtf中的图片,存储为{hex, type}对象数组\r\n extractImageDataFromRtf(rtfData) {\r\n if (!rtfData) {\r\n return []\r\n }\r\n\r\n const regexPictureHeader\r\n = /{\\\\pict[\\s\\S]+?\\\\bliptag-?\\d+(\\\\blipupi-?\\d+)?({\\\\\\*\\\\blipuid\\s?[\\da-fA-F]+)?[\\s}]*?/\r\n const regexPicture = new RegExp(\r\n '(?:(' + regexPictureHeader.source + '))([\\\\da-fA-F\\\\s]+)\\\\}',\r\n 'g',\r\n )\r\n const images = rtfData.match(regexPicture)\r\n const result = []\r\n\r\n if (images) {\r\n for (const image of images) {\r\n let imageType = ''\r\n\r\n if (image.includes('\\\\pngblip')) {\r\n imageType = 'image/png'\r\n }\r\n else if (image.includes('\\\\jpegblip')) {\r\n imageType = 'image/jpeg'\r\n }\r\n\r\n if (imageType) {\r\n result.push({\r\n hex: image\r\n .replace(regexPictureHeader, '')\r\n .replace(/[^\\da-fA-F]/g, ''),\r\n type: imageType,\r\n })\r\n }\r\n }\r\n }\r\n\r\n return result\r\n }\r\n\r\n extractFilesFromDelta(delta, clipboardFiles, hexImages?) {\r\n let index = -1\r\n return Promise.all(\r\n delta.map(async (op) => {\r\n index++\r\n const image = op.insert.image\r\n if (!image || image.hasExisted) {\r\n return\r\n }\r\n\r\n let file\r\n let isPlaceholderImage = false\r\n let imageIndex\r\n try {\r\n // hex 图片存在则为 file:/// 协议本地图片,使用 hex 图片转为 base64 读取\r\n const hexImage = hexImages.length && hexImages.shift()\r\n const newImage\r\n = hexImage\r\n && `data:${hexImage.type};base64,${this.convertHexToBase64(\r\n hexImage.hex,\r\n )}`\r\n imageIndex = index\r\n file = await imageUrlToFile(newImage || image.src || image)\r\n }\r\n catch (_err) {\r\n if (clipboardFiles.length !== 0) {\r\n // 跨域获取图片失败时从剪切板获取图片\r\n const clipboardFile = clipboardFiles[0]\r\n const imageType\r\n = clipboardFile.type?.indexOf('image') === -1\r\n ? 'image/png'\r\n : clipboardFile.type\r\n const blob = clipboardFile.slice(0, clipboardFile.size, imageType)\r\n file = new File([blob], `image-CORS-${new Date().getTime()}.png`, {\r\n type: imageType,\r\n })\r\n }\r\n else if (image.src.startsWith('http')) {\r\n // 什么都不做\r\n }\r\n else {\r\n // 剪切板中无图片,用失败占位图替换\r\n const errorImagePlaceholderJpg\r\n = LANG_CONF['img-error'] === 'Image Copy Error'\r\n ? ERROR_IMAGE_PLACEHOLDER_EN\r\n : ERROR_IMAGE_PLACEHOLDER_CN\r\n file = await imageUrlToFile(errorImagePlaceholderJpg, true)\r\n isPlaceholderImage = true\r\n }\r\n }\r\n\r\n return [file, isPlaceholderImage, image, imageIndex]\r\n }),\r\n )\r\n }\r\n\r\n getImgSelection(delta, imageIndex) {\r\n let length = 0\r\n delta.ops.every((op, index) => {\r\n if (index === imageIndex) {\r\n return false\r\n }\r\n if (typeof op.insert === 'string') {\r\n length += op.insert.length\r\n }\r\n return true\r\n })\r\n const range = {\r\n index: length,\r\n length: 0,\r\n }\r\n return range\r\n }\r\n}\r\n\r\nfunction rebuildDelta(delta, cellLine) {\r\n const { cell: cellId, colspan, row: rowId, rowspan } = cellLine\r\n const buildedDelta = delta.reduce((newDelta, op) => {\r\n if (op.insert && typeof op.insert === 'string') {\r\n const lines = splitWithBreak(op.insert)\r\n\r\n lines.forEach((text) => {\r\n if (text === '\\n') {\r\n // 对换行增加 table-cell-line 格式,以避免表格断开\r\n newDelta.insert('\\n', {\r\n ...op.attributes,\r\n 'table-cell-line': { row: rowId, cell: cellId, rowspan, colspan },\r\n })\r\n }\r\n else {\r\n text = text.endsWith('\\r') ? text.slice(0, -1) : text\r\n newDelta.insert(\r\n text,\r\n omit(op.attributes, ['table', 'table-cell-line']),\r\n )\r\n }\r\n })\r\n }\r\n else {\r\n newDelta.insert(op.insert, op.attributes)\r\n }\r\n\r\n return newDelta\r\n }, new Delta())\r\n\r\n return buildedDelta\r\n}\r\n\r\nfunction replaceStrWhiteSpace(str) {\r\n const isWhiteSpace = value => /^(\\u3000|\\u0020){1}$/.test(value) // 空白字符\r\n let textWithWhiteSpace = ''\r\n let beginHasChar = false\r\n for (const char of str) {\r\n if (isWhiteSpace(char) && !beginHasChar) {\r\n textWithWhiteSpace += '\\u00a0'\r\n }\r\n else {\r\n textWithWhiteSpace += char\r\n beginHasChar = true\r\n }\r\n }\r\n return textWithWhiteSpace\r\n}\r\n\r\nfunction replaceDeltaWhiteSpace(delta, rootBgColor?) {\r\n return delta.reduce((newDelta, op) => {\r\n // fix: 当粘贴文字颜色和编辑器背景色一致且自身无背景色的情况下移除文字颜色样式,避免误导用户粘贴无效\r\n if (\r\n rootBgColor\r\n && op.attributes\r\n && op.attributes.color\r\n && !op.attributes.background\r\n ) {\r\n const originColor = op.attributes.color\r\n const fontColor\r\n = originColor.indexOf('#') === 0 ? hexToRgbA(originColor) : originColor\r\n if (\r\n fontColor === rootBgColor\r\n || (fontColor === 'rgba(255,255,255,1)'\r\n && rootBgColor === 'rgba(0, 0, 0, 0)')\r\n ) {\r\n delete op.attributes.color\r\n }\r\n }\r\n if (op.insert && typeof op.insert === 'string') {\r\n const lines = splitWithBreak(op.insert)\r\n let insertWithWhiteSpace = ''\r\n lines.forEach((text) => {\r\n insertWithWhiteSpace += replaceStrWhiteSpace(text)\r\n })\r\n newDelta.insert(insertWithWhiteSpace, op.attributes)\r\n }\r\n else {\r\n newDelta.insert(op.insert, op.attributes)\r\n }\r\n return newDelta\r\n }, new Delta())\r\n}\r\n\r\nfunction renderStyles(html) {\r\n let htmlString = html\r\n // Trim unnecessary parts.\r\n htmlString = htmlString.substring(\r\n htmlString.indexOf('<html '),\r\n htmlString.length,\r\n )\r\n htmlString = htmlString.substring(\r\n 0,\r\n htmlString.lastIndexOf('</html>') + '</html>'.length,\r\n )\r\n\r\n // Add temporary iframe.\r\n const iframe = document.createElement('iframe')\r\n iframe.style.display = 'none'\r\n document.body.appendChild(iframe)\r\n\r\n const iframeDoc = iframe.contentDocument || iframe.contentWindow.document\r\n iframeDoc.open()\r\n iframeDoc.write(htmlString)\r\n iframeDoc.close()\r\n\r\n let collection\r\n let pointer\r\n const rules\r\n = iframeDoc.styleSheets[iframeDoc.styleSheets.length - 1]['cssRules']\r\n\r\n // Convert internal styles to inline style of respective node.\r\n for (let idx = 0; idx < rules.length; idx++) {\r\n if ((rules[idx] as CSSStyleRule).selectorText === '') {\r\n continue\r\n }\r\n collection = iframeDoc.body.querySelectorAll(\r\n (rules[idx] as CSSStyleRule).selectorText,\r\n )\r\n\r\n for (pointer = 0; pointer < collection.length; pointer++) {\r\n collection[pointer].style.cssText += (\r\n rules[idx] as CSSStyleRule\r\n ).style.cssText\r\n }\r\n }\r\n\r\n const convertedString = iframeDoc.firstChild['outerHTML']\r\n // Remove temporary iframe.\r\n iframe.parentNode.removeChild(iframe)\r\n\r\n return convertedString\r\n}\r\n\r\nexport default CustomClipboard\r\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"custom-clipboard.es.js","sources":["../../src/custom-clipboard.ts"],"sourcesContent":["import Quill from 'quill'\r\nimport {\r\n ERROR_IMAGE_PLACEHOLDER_CN,\r\n ERROR_IMAGE_PLACEHOLDER_EN,\r\n} from './config/base64-image'\r\nimport { BIG_DELTA_LIMIT, LANG_CONF } from './config/editor.config'\r\nimport {\r\n hexToRgbA,\r\n imageFileToUrl,\r\n imageUrlToFile,\r\n insideTable,\r\n isNullOrUndefined,\r\n omit,\r\n replaceDeltaImage,\r\n splitWithBreak,\r\n} from './config/editor.utils'\r\n\r\nconst Clipboard = Quill.imports['modules/clipboard']\r\nconst Delta = Quill.import('delta')\r\n\r\nclass CustomClipboard extends Clipboard {\r\n quill\r\n convert\r\n onCopy\r\n matchers\r\n\r\n prepareMatching(container, nodeMatches) {\r\n const elementMatchers = []\r\n const textMatchers = []\r\n this.matchers.forEach((pair) => {\r\n const [selector, matcher] = pair\r\n switch (selector) {\r\n case Node.TEXT_NODE:\r\n textMatchers.push(matcher)\r\n break\r\n case Node.ELEMENT_NODE:\r\n elementMatchers.push(matcher)\r\n break\r\n default: {\r\n // word 的 v:shape 系列标签只能通过 getElementsByTagName 获取\r\n const vRegex = /v:(.+)/\r\n const nodeList = vRegex.test(selector)\r\n ? Array.from(container.getElementsByTagName(selector))\r\n : Array.from(container.querySelectorAll(selector))\r\n nodeList.forEach((node) => {\r\n if (nodeMatches.has(node)) {\r\n const matches = nodeMatches.get(node)\r\n matches.push(matcher)\r\n }\r\n else {\r\n nodeMatches.set(node, [matcher])\r\n }\r\n })\r\n break\r\n }\r\n }\r\n })\r\n return [elementMatchers, textMatchers]\r\n }\r\n\r\n onCaptureCopy(e, isCut = false) {\r\n if (e.defaultPrevented) {\r\n return\r\n }\r\n e.preventDefault()\r\n const [range] = this.quill.selection.getRange()\r\n if (isNullOrUndefined(range)) {\r\n return\r\n }\r\n const { html, text } = this.onCopy(range, isCut)\r\n\r\n // 兼容IE11浏览器`\r\n if (!e.clipboardData) {\r\n e.clipboardData = {\r\n types: 'text/plain',\r\n setData: (_type, value) => {\r\n return window.clipboardData.setData('Text', value)\r\n },\r\n }\r\n }\r\n\r\n // 复制代码时移除utf8中产生的不间断空格\\u00A0\r\n let plainText = text\r\n if (html.startsWith('<pre>')) {\r\n plainText = text.replace(/\\u00A0/g, ' ')\r\n }\r\n\r\n e.clipboardData.setData('text/html', html)\r\n e.clipboardData.setData('text/plain', plainText)\r\n if (isCut) {\r\n this.quill.deleteText(range, Quill.sources.USER)\r\n }\r\n }\r\n\r\n onCapturePaste(e) {\r\n if (e.defaultPrevented || !this.quill.isEnabled()) {\r\n return\r\n }\r\n e.preventDefault()\r\n const range = this.quill.getSelection(true)\r\n if (isNullOrUndefined(range)) {\r\n return\r\n }\r\n\r\n // 兼容IE11浏览器\r\n if (!e.clipboardData) {\r\n e.clipboardData = {\r\n types: 'text/plain',\r\n getData: () => {\r\n return window.clipboardData.getData('Text')\r\n },\r\n }\r\n }\r\n\r\n const html = e.clipboardData.getData('text/html')\r\n const text = e.clipboardData.getData('text/plain')\r\n const files = Array.from(e.clipboardData.files || [])\r\n const msExcelCheck = /<meta.*?Microsoft Excel\\s[\\d].*?>/\r\n\r\n if (html.search(msExcelCheck) === -1 && files.length > 0) {\r\n this.quill.uploader.upload(range, files)\r\n }\r\n else {\r\n const msWordCheck1\r\n = /<meta\\s*name=\"?generator\"?\\s*content=\"?microsoft\\s*word\\s*\\d+\"?\\/?>/i\r\n const msWordCheck2 = /xmlns:o=\"urn:schemas-microsoft-com/i\r\n const result = { html, text, files, rtf: null }\r\n if (html.search(msExcelCheck) !== -1) {\r\n result.html = renderStyles(html)\r\n }\r\n if (msWordCheck1.test(html) || msWordCheck2.test(html)) {\r\n // TODO: 当word文档包含heading时text/rtf读取为空,无法获取hex图片,待修复。可参考ckeditor5/issues/2493\r\n result.rtf = e.clipboardData.getData('text/rtf')\r\n }\r\n this.onPaste(range, result)\r\n }\r\n }\r\n\r\n onPaste(range, { html, text, files: clipboardFiles, rtf }) {\r\n const hexImages = this.extractImageDataFromRtf(rtf)\r\n const rootBgColor = getComputedStyle(this.quill.root).backgroundColor\r\n const formats = this.quill.getFormat(range.index)\r\n let pastedDelta = this.convert({ text, html }, formats)\r\n pastedDelta = replaceDeltaWhiteSpace(pastedDelta, rootBgColor)\r\n const deltaLength = pastedDelta.ops.length\r\n\r\n let loadingTipsContainer\r\n if (deltaLength > BIG_DELTA_LIMIT) {\r\n loadingTipsContainer = this.quill.addContainer('ql-loading-tips')\r\n loadingTipsContainer.innerHTML = LANG_CONF.pasting\r\n }\r\n\r\n const linePos = { index: range.index, length: range.length, fix: 0 }\r\n const [line, offset] = this.quill.getLine(range.index)\r\n const isInsideTable = insideTable.call(this)\r\n\r\n const handlePasteContent = (content: any) => {\r\n let pastedContent = content\r\n // fix: 阻止粘贴代码块和引用导致表格断裂\r\n const tableBreaker = pastedContent.ops.find((op) => {\r\n return (\r\n op.attributes\r\n && (op.attributes.blockquote || op.attributes['code-block'])\r\n )\r\n })\r\n if (isInsideTable) {\r\n // fix: 阻止带有表格内容粘贴在表格里\r\n const table = line.domNode.closest('table.quill-better-table')\r\n const tableBlot = Quill.find(table)\r\n const tableIndex = this.quill.getIndex(tableBlot)\r\n const tableLength = tableBlot.length()\r\n const tableEndPos = tableIndex + tableLength\r\n const anchorNode = getSelection().anchorNode\r\n if (tableBreaker) {\r\n return\r\n }\r\n if (formats['table-col']) {\r\n // fix: 光标在表格前端的table-col处时,获取整个表格的index后以此为基准向前移动一位插入粘贴内容且不删除任何内容\r\n linePos.index = tableIndex - 1\r\n linePos.length = 0\r\n }\r\n else if (\r\n range.index === tableEndPos - 1\r\n && anchorNode instanceof HTMLDivElement\r\n && anchorNode.classList.contains('quill-better-table-wrapper')\r\n ) {\r\n const list = pastedContent.filter(\r\n op => op.attributes && op.attributes.list,\r\n )\r\n if (list && list.length) {\r\n return\r\n }\r\n // fix: 光标在表格末端时,向后移动一位插入粘贴内容且不删除任何内容\r\n // TODO\r\n // 当表格最后一格有内容时,没法区分在表格最后一格最末尾和光标在表格后这两种情况,它们的 range 是一样\r\n // 这会导致在这两处粘贴表格内容都会将该内容粘贴到表格下一行中\r\n linePos.index = tableEndPos\r\n linePos.length = 0\r\n }\r\n else {\r\n if (!formats['table-cell-line']) {\r\n return\r\n }\r\n // fix: 解决表格内粘贴问题\r\n // 缺陷描述:将表格内的换行文本复制粘贴到别的单元格,会导致表格断开\r\n // 原因是:换行的文本delta对象有问题,delta对象前面多了一个纯换行和表格控制头(table-col)\r\n // 解决方法:将多余的delta项移除\r\n pastedContent = {\r\n ops: pastedContent.filter((op, index) => {\r\n const regexp = /^[\\n\\r]+$/\r\n const isString = op.insert && typeof op.insert === 'string'\r\n const isLine = isString && regexp.test(op.insert)\r\n const isCellLine\r\n = isLine && op.attributes && op.attributes['table-cell-line']\r\n const isList = isLine && op.attributes && op.attributes.list\r\n const isPureLine = isLine && !isCellLine && !isList\r\n const isTableCol\r\n = isLine && op.attributes && op.attributes['table-col']\r\n const isLastCellLine = isCellLine && index === deltaLength - 1\r\n return !isPureLine && !isTableCol && !isLastCellLine\r\n }),\r\n }\r\n // fix: 解决从表格外粘贴多行文本导致表格断开的问题\r\n pastedContent = rebuildDelta(\r\n new Delta(pastedContent.ops),\r\n formats['table-cell-line'],\r\n )\r\n }\r\n }\r\n\r\n // fix: 粘贴内容末尾为List,且粘贴位置的block或table-cell-line无内容则删除该block或table-cell-line\r\n // TODO 这里的lastChild如果不存在,则可能报错\r\n const lastChild = pastedContent.ops[pastedContent.ops.length - 1]\r\n const hasList\r\n = lastChild && lastChild.attributes && lastChild.attributes.list\r\n if (\r\n hasList\r\n && offset === 0\r\n && line\r\n && line.cache.length === 1\r\n && (line.statics.blotName === 'block'\r\n || line.statics.blotName === 'table-cell-line')\r\n && (!line.next || line.next.statics.blotName !== 'table-view')\r\n ) {\r\n linePos.index = this.quill.getIndex(line)\r\n linePos.length = line.length()\r\n linePos.fix = 1\r\n }\r\n\r\n const oldDelta = new Delta().retain(linePos.index).delete(linePos.length)\r\n const delta = oldDelta.concat(pastedContent)\r\n\r\n setTimeout(() => {\r\n this.quill.updateContents(delta, Quill.sources.USER)\r\n this.quill.setSelection(\r\n delta.length() - linePos.length - linePos.fix,\r\n Quill.sources.SILENT,\r\n )\r\n this.quill.scrollIntoView()\r\n if (loadingTipsContainer) {\r\n loadingTipsContainer.remove()\r\n }\r\n })\r\n }\r\n\r\n ;(async () => {\r\n try {\r\n const [files, placeholders, originalUrls, imageIndexs] = this.flipFilesArray(\r\n await this.extractFilesFromDelta(\r\n pastedDelta,\r\n clipboardFiles,\r\n hexImages,\r\n ),\r\n )\r\n\r\n if (files.length === 0) {\r\n handlePasteContent(pastedDelta)\r\n }\r\n else {\r\n if (this.quill.options.editorPaste && this.quill.options.editorPaste.observers.length !== 0) {\r\n // 设置editorPaste回调的情况\r\n this.quill.options.editorPaste.emit({\r\n files,\r\n callback: ({ code, message, data }) => {\r\n if (code === 0) {\r\n const { imageUrls } = data\r\n pastedDelta = replaceDeltaImage(\r\n pastedDelta,\r\n imageUrls,\r\n placeholders,\r\n )\r\n handlePasteContent(pastedDelta)\r\n }\r\n else {\r\n console.error('error message:', message)\r\n }\r\n },\r\n })\r\n }\r\n else {\r\n // 没有originalUrls 也没有文件粘贴\r\n if (files[0] !== undefined || originalUrls.length === 0) {\r\n // 没有设置editorPaste回调的情况下,File格式的占位图需要手动转换成url格式,插入到编辑器中\r\n const imageUrls = await this.files2urls(\r\n files,\r\n placeholders,\r\n originalUrls,\r\n pastedDelta,\r\n imageIndexs,\r\n )\r\n pastedDelta = replaceDeltaImage(\r\n pastedDelta,\r\n imageUrls,\r\n placeholders,\r\n )\r\n }\r\n handlePasteContent(pastedDelta)\r\n }\r\n }\r\n }\r\n catch (_e) {\r\n throw new Error('Paste failed.')\r\n }\r\n })()\r\n }\r\n\r\n files2urls(files, placeholders, originalUrls, pastedDelta, imageIndexs) {\r\n return Promise.all(\r\n files.map(async (imageFile, index) => {\r\n const netImgExp = /^((http|https)\\:)?\\/\\/([\\s\\S]+)$/\r\n if (\r\n !placeholders[index]\r\n && originalUrls[index]\r\n && netImgExp.test(originalUrls[index])\r\n ) {\r\n // 不是占位图的普通url图片直接返回url\r\n return new Promise((resolve) => {\r\n resolve(originalUrls[index])\r\n })\r\n }\r\n else if (this.quill.options.uploadOption.imageUploadToServer) {\r\n const range = this.getImgSelection(pastedDelta, imageIndexs[index])\r\n this.quill.uploader.upload(range, [imageFile])\r\n }\r\n else {\r\n // 占位图或者跨域图需要手动转换成url格式\r\n return imageFileToUrl(imageFile)\r\n }\r\n }),\r\n )\r\n }\r\n\r\n flipFilesArray(filesArr) {\r\n const files = []\r\n const placeholders = []\r\n const originalUrls = []\r\n const imageIndexs = []\r\n filesArr.forEach((item: any) => {\r\n if (item) {\r\n const [file, placeholder, originalUrl, imageIndex] = item\r\n files.push(file)\r\n placeholders.push(placeholder)\r\n originalUrls.push(originalUrl)\r\n if (imageIndex === 0 || imageIndex) {\r\n imageIndexs.push(imageIndex)\r\n }\r\n }\r\n })\r\n return [files, placeholders, originalUrls, imageIndexs]\r\n }\r\n\r\n // 将图片从hex转为base64\r\n convertHexToBase64(hexString) {\r\n return btoa(\r\n hexString\r\n .match(/\\w{2}/g)\r\n .map((char) => {\r\n return String.fromCharCode(Number.parseInt(char, 16))\r\n })\r\n .join(''),\r\n )\r\n }\r\n\r\n // 匹配rtf中的图片,存储为{hex, type}对象数组\r\n extractImageDataFromRtf(rtfData) {\r\n if (!rtfData) {\r\n return []\r\n }\r\n\r\n const regexPictureHeader\r\n = /{\\\\pict[\\s\\S]+?\\\\bliptag-?\\d+(\\\\blipupi-?\\d+)?({\\\\\\*\\\\blipuid\\s?[\\da-fA-F]+)?[\\s}]*?/\r\n const regexPicture = new RegExp(\r\n `(?:(${regexPictureHeader.source}))([\\\\da-fA-F\\\\s]+)\\\\}`,\r\n 'g',\r\n )\r\n const images = rtfData.match(regexPicture)\r\n const result = []\r\n\r\n if (images) {\r\n for (const image of images) {\r\n let imageType = ''\r\n\r\n if (image.includes('\\\\pngblip')) {\r\n imageType = 'image/png'\r\n }\r\n else if (image.includes('\\\\jpegblip')) {\r\n imageType = 'image/jpeg'\r\n }\r\n\r\n if (imageType) {\r\n result.push({\r\n hex: image\r\n .replace(regexPictureHeader, '')\r\n .replace(/[^\\da-fA-F]/g, ''),\r\n type: imageType,\r\n })\r\n }\r\n }\r\n }\r\n\r\n return result\r\n }\r\n\r\n extractFilesFromDelta(delta, clipboardFiles, hexImages?) {\r\n let index = -1\r\n return Promise.all(\r\n delta.map(async (op) => {\r\n index++\r\n const image = op.insert.image\r\n if (!image || image.hasExisted) {\r\n return\r\n }\r\n\r\n let file\r\n let isPlaceholderImage = false\r\n let imageIndex\r\n try {\r\n // hex 图片存在则为 file:/// 协议本地图片,使用 hex 图片转为 base64 读取\r\n const hexImage = hexImages.length && hexImages.shift()\r\n const newImage\r\n = hexImage\r\n && `data:${hexImage.type};base64,${this.convertHexToBase64(\r\n hexImage.hex,\r\n )}`\r\n imageIndex = index\r\n file = await imageUrlToFile(newImage || image.src || image)\r\n }\r\n catch (_err) {\r\n if (clipboardFiles.length !== 0) {\r\n // 跨域获取图片失败时从剪切板获取图片\r\n const clipboardFile = clipboardFiles[0]\r\n const imageType\r\n = clipboardFile.type?.indexOf('image') === -1\r\n ? 'image/png'\r\n : clipboardFile.type\r\n const blob = clipboardFile.slice(0, clipboardFile.size, imageType)\r\n file = new File([blob], `image-CORS-${new Date().getTime()}.png`, {\r\n type: imageType,\r\n })\r\n }\r\n else if (image.src.startsWith('http')) {\r\n // 什么都不做\r\n }\r\n else {\r\n // 剪切板中无图片,用失败占位图替换\r\n const errorImagePlaceholderJpg\r\n = LANG_CONF['img-error'] === 'Image Copy Error'\r\n ? ERROR_IMAGE_PLACEHOLDER_EN\r\n : ERROR_IMAGE_PLACEHOLDER_CN\r\n file = await imageUrlToFile(errorImagePlaceholderJpg, true)\r\n isPlaceholderImage = true\r\n }\r\n }\r\n\r\n return [file, isPlaceholderImage, image, imageIndex]\r\n }),\r\n )\r\n }\r\n\r\n getImgSelection(delta, imageIndex) {\r\n let length = 0\r\n delta.ops.every((op, index) => {\r\n if (index === imageIndex) {\r\n return false\r\n }\r\n if (typeof op.insert === 'string') {\r\n length += op.insert.length\r\n }\r\n return true\r\n })\r\n const range = {\r\n index: length,\r\n length: 0,\r\n }\r\n return range\r\n }\r\n}\r\n\r\nfunction rebuildDelta(delta, cellLine) {\r\n const { cell: cellId, colspan, row: rowId, rowspan } = cellLine\r\n const buildedDelta = delta.reduce((newDelta, op) => {\r\n if (op.insert && typeof op.insert === 'string') {\r\n const lines = splitWithBreak(op.insert)\r\n\r\n lines.forEach((text) => {\r\n if (text === '\\n') {\r\n // 对换行增加 table-cell-line 格式,以避免表格断开\r\n newDelta.insert('\\n', {\r\n ...op.attributes,\r\n 'table-cell-line': { row: rowId, cell: cellId, rowspan, colspan },\r\n })\r\n }\r\n else {\r\n text = text.endsWith('\\r') ? text.slice(0, -1) : text\r\n newDelta.insert(\r\n text,\r\n omit(op.attributes, ['table', 'table-cell-line']),\r\n )\r\n }\r\n })\r\n }\r\n else {\r\n newDelta.insert(op.insert, op.attributes)\r\n }\r\n\r\n return newDelta\r\n }, new Delta())\r\n\r\n return buildedDelta\r\n}\r\n\r\nfunction replaceStrWhiteSpace(str) {\r\n const isWhiteSpace = value => /^(\\u3000|\\u0020){1}$/.test(value) // 空白字符\r\n let textWithWhiteSpace = ''\r\n let beginHasChar = false\r\n for (const char of str) {\r\n if (isWhiteSpace(char) && !beginHasChar) {\r\n textWithWhiteSpace += '\\u00A0'\r\n }\r\n else {\r\n textWithWhiteSpace += char\r\n beginHasChar = true\r\n }\r\n }\r\n return textWithWhiteSpace\r\n}\r\n\r\nfunction replaceDeltaWhiteSpace(delta, rootBgColor?) {\r\n return delta.reduce((newDelta, op) => {\r\n // fix: 当粘贴文字颜色和编辑器背景色一致且自身无背景色的情况下移除文字颜色样式,避免误导用户粘贴无效\r\n if (\r\n rootBgColor\r\n && op.attributes\r\n && op.attributes.color\r\n && !op.attributes.background\r\n ) {\r\n const originColor = op.attributes.color\r\n const fontColor\r\n = originColor.indexOf('#') === 0 ? hexToRgbA(originColor) : originColor\r\n if (\r\n fontColor === rootBgColor\r\n || (fontColor === 'rgba(255,255,255,1)'\r\n && rootBgColor === 'rgba(0, 0, 0, 0)')\r\n ) {\r\n delete op.attributes.color\r\n }\r\n }\r\n if (op.insert && typeof op.insert === 'string') {\r\n const lines = splitWithBreak(op.insert)\r\n let insertWithWhiteSpace = ''\r\n lines.forEach((text) => {\r\n insertWithWhiteSpace += replaceStrWhiteSpace(text)\r\n })\r\n newDelta.insert(insertWithWhiteSpace, op.attributes)\r\n }\r\n else {\r\n newDelta.insert(op.insert, op.attributes)\r\n }\r\n return newDelta\r\n }, new Delta())\r\n}\r\n\r\nfunction renderStyles(html) {\r\n let htmlString = html\r\n // Trim unnecessary parts.\r\n htmlString = htmlString.substring(\r\n htmlString.indexOf('<html '),\r\n htmlString.length,\r\n )\r\n htmlString = htmlString.substring(\r\n 0,\r\n htmlString.lastIndexOf('</html>') + '</html>'.length,\r\n )\r\n\r\n // Add temporary iframe.\r\n const iframe = document.createElement('iframe')\r\n iframe.style.display = 'none'\r\n document.body.appendChild(iframe)\r\n\r\n const iframeDoc = iframe.contentDocument || iframe.contentWindow.document\r\n iframeDoc.open()\r\n iframeDoc.write(htmlString)\r\n iframeDoc.close()\r\n\r\n let collection\r\n let pointer\r\n const rules\r\n = iframeDoc.styleSheets[iframeDoc.styleSheets.length - 1].cssRules\r\n\r\n // Convert internal styles to inline style of respective node.\r\n for (let idx = 0; idx < rules.length; idx++) {\r\n if ((rules[idx] as CSSStyleRule).selectorText === '') {\r\n continue\r\n }\r\n collection = iframeDoc.body.querySelectorAll(\r\n (rules[idx] as CSSStyleRule).selectorText,\r\n )\r\n\r\n for (pointer = 0; pointer < collection.length; pointer++) {\r\n collection[pointer].style.cssText += (\r\n rules[idx] as CSSStyleRule\r\n ).style.cssText\r\n }\r\n }\r\n\r\n const convertedString = iframeDoc.firstChild.outerHTML\r\n // Remove temporary iframe.\r\n iframe.parentNode.removeChild(iframe)\r\n\r\n return convertedString\r\n}\r\n\r\nexport default CustomClipboard\r\n"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { merge } from "lodash-es";
|
|
1
2
|
import Quill from "quill";
|
|
2
3
|
import CustomImage, { ImageContainerBlot as CustomImageContainer } from "./image.es.js";
|
|
3
4
|
import DefaultOptions from "./Options.es.js";
|
|
4
5
|
import { CustomImageSpec } from "./specs/CustomImageSpec.es.js";
|
|
5
|
-
import { merge } from "lodash-es";
|
|
6
6
|
const dontMerge = (_destination, source) => source;
|
|
7
7
|
class BlotFormatter {
|
|
8
8
|
constructor(quill, options = {}) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlotFormatter.es.js","sources":["../../../src/custom-image/BlotFormatter.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"BlotFormatter.es.js","sources":["../../../src/custom-image/BlotFormatter.ts"],"sourcesContent":["import type Action from './actions/Action'\r\nimport type { Options } from './Options'\r\nimport type BlotSpec from './specs/BlotSpec'\r\nimport { merge as deepmerge } from 'lodash-es'\r\nimport Quill from 'quill'\r\nimport ImageBlot, { ImageContainerBlot } from './image'\r\nimport DefaultOptions from './Options'\r\nimport { CustomImageSpec } from './specs/CustomImageSpec'\r\n\r\nconst dontMerge = (_destination: Array<any>, source: Array<any>) => source\r\n\r\n// @dynamic\r\nexport default class BlotFormatter {\r\n quill: any\r\n options: Options\r\n currentSpec: BlotSpec\r\n specs: BlotSpec[]\r\n overlay: HTMLElement\r\n actions: Action[]\r\n observer: any\r\n\r\n static register() {\r\n Quill.register('formats/image', ImageBlot, true)\r\n Quill.register('formats/image-container', ImageContainerBlot, true)\r\n Quill.register('modules/image-spec', CustomImageSpec, true)\r\n }\r\n\r\n constructor(quill: any, options: any = {}) {\r\n this.quill = quill\r\n this.options = deepmerge(DefaultOptions, options, { arrayMerge: dontMerge })\r\n this.currentSpec = null\r\n this.actions = []\r\n this.overlay = document.createElement('div')\r\n this.overlay.classList.add(this.options.overlay.className)\r\n if (this.options.overlay.style) {\r\n Object.assign(this.overlay.style, this.options.overlay.style)\r\n }\r\n\r\n // disable native image resizing on firefox\r\n document.execCommand('enableObjectResizing', false, 'false') // eslint-disable-next-line-line no-undef\r\n this.quill.root.parentNode.style.position = this.quill.root.parentNode.style.position || 'relative'\r\n this.quill.root.addEventListener('click', this.onClick)\r\n this.specs = this.options.specs.map((SpecClass: any) => new SpecClass(this))\r\n this.specs.forEach(spec => spec.init())\r\n }\r\n\r\n show(spec: BlotSpec) {\r\n this.currentSpec = spec\r\n this.currentSpec.setSelection()\r\n this.setUserSelect('none')\r\n this.quill.root.parentNode.appendChild(this.overlay)\r\n this.repositionOverlay()\r\n this.createActions(spec)\r\n\r\n // fix: 图片对齐之后,虚线外框应该跟随移动\r\n const imageDom = spec.getTargetElement()\r\n const win: any = window\r\n const MutationObserver = win.MutationObserver || win.WebKitMutationObserver || win.MozMutationObserver\r\n const element = imageDom.parentNode\r\n this.observer = new MutationObserver((mutationList) => {\r\n for (const mutation of mutationList) {\r\n const target = mutation.target\r\n const image = target.querySelector('img')\r\n if (image) {\r\n this.repositionOverlay()\r\n }\r\n }\r\n })\r\n this.observer.observe(element, {\r\n attributes: true,\r\n attributeFilter: ['class'],\r\n attributeOldValue: true,\r\n subtree: true,\r\n })\r\n document.body.addEventListener('click', this.hideImageOverlay, true)\r\n }\r\n\r\n hide() {\r\n if (!this.currentSpec) {\r\n return\r\n }\r\n\r\n const imgDom = this.currentSpec.getTargetElement()\r\n if (imgDom) {\r\n imgDom.classList.remove('current-select-img')\r\n }\r\n\r\n this.currentSpec.onHide()\r\n this.currentSpec = null\r\n this.quill.root.parentNode.removeChild(this.overlay)\r\n this.overlay.style.setProperty('display', 'none')\r\n this.setUserSelect('')\r\n this.destroyActions()\r\n }\r\n\r\n update() {\r\n this.repositionOverlay()\r\n this.actions.forEach(action => action.onUpdate())\r\n }\r\n\r\n createActions(spec: BlotSpec) {\r\n this.actions = spec.getActions().map((ActionClass: any) => {\r\n const action: Action = new ActionClass(this)\r\n action.onCreate()\r\n return action\r\n })\r\n }\r\n\r\n destroyActions() {\r\n this.actions.forEach((action: Action) => action.onDestroy())\r\n this.actions = []\r\n }\r\n\r\n repositionOverlay() {\r\n if (!this.currentSpec) {\r\n return\r\n }\r\n\r\n const overlayTarget = this.currentSpec.getOverlayElement()\r\n if (!overlayTarget) {\r\n return\r\n }\r\n\r\n const parent: HTMLElement = this.quill.root.parentNode\r\n const specRect = overlayTarget.getBoundingClientRect()\r\n const parentRect = parent.getBoundingClientRect()\r\n\r\n Object.assign(this.overlay.style, {\r\n display: 'block',\r\n left: `${specRect.left - parentRect.left - 1 + parent.scrollLeft}px`,\r\n top: `${specRect.top - parentRect.top + parent.scrollTop}px`,\r\n width: `${specRect.width}px`,\r\n height: `${specRect.height}px`,\r\n })\r\n }\r\n\r\n setUserSelect(value: string) {\r\n const props: string[] = [\r\n 'userSelect',\r\n 'mozUserSelect',\r\n 'webkitUserSelect',\r\n 'msUserSelect',\r\n ]\r\n\r\n props.forEach((prop: string) => {\r\n // set on contenteditable element and <html>\r\n this.quill.root.style.setProperty(prop, value)\r\n if (document.documentElement) {\r\n document.documentElement.style.setProperty(prop, value)\r\n }\r\n })\r\n }\r\n\r\n onClick = () => {\r\n this.hide()\r\n }\r\n\r\n hideImageOverlay = (event) => {\r\n const target = event.target\r\n const isBlotFormatter = target?.classList?.contains('blot-formatter__overlay')\r\n // 点击图片操作框之外应该将其销毁\r\n if (!isBlotFormatter) {\r\n this.hide()\r\n }\r\n document.body.removeEventListener('click', this.hideImageOverlay)\r\n }\r\n}\r\n"],"names":["deepmerge","ImageBlot","ImageContainerBlot"],"mappings":";;;;;AASA,MAAM,YAAY,CAAC,cAA0B,WAAuB;AAGpE,MAAqB,cAAc;AAAA,EAejC,YAAY,OAAY,UAAe,IAAI;AA8H3C,SAAA,UAAU,MAAM;AACd,WAAK,KAAK;AAAA,IAAA;AAGZ,SAAA,mBAAmB,CAAC,UAAU;;AAC5B,YAAM,SAAS,MAAM;AACrB,YAAM,mBAAkB,sCAAQ,cAAR,mBAAmB,SAAS;AAEpD,UAAI,CAAC,iBAAiB;AACpB,aAAK,KAAK;AAAA,MACZ;AACA,eAAS,KAAK,oBAAoB,SAAS,KAAK,gBAAgB;AAAA,IAAA;AAxIhE,SAAK,QAAQ;AACb,SAAK,UAAUA,MAAU,gBAAgB,SAAS,EAAE,YAAY,WAAW;AAC3E,SAAK,cAAc;AACnB,SAAK,UAAU;AACV,SAAA,UAAU,SAAS,cAAc,KAAK;AAC3C,SAAK,QAAQ,UAAU,IAAI,KAAK,QAAQ,QAAQ,SAAS;AACrD,QAAA,KAAK,QAAQ,QAAQ,OAAO;AAC9B,aAAO,OAAO,KAAK,QAAQ,OAAO,KAAK,QAAQ,QAAQ,KAAK;AAAA,IAC9D;AAGS,aAAA,YAAY,wBAAwB,OAAO,OAAO;AACtD,SAAA,MAAM,KAAK,WAAW,MAAM,WAAW,KAAK,MAAM,KAAK,WAAW,MAAM,YAAY;AACzF,SAAK,MAAM,KAAK,iBAAiB,SAAS,KAAK,OAAO;AACjD,SAAA,QAAQ,KAAK,QAAQ,MAAM,IAAI,CAAC,cAAmB,IAAI,UAAU,IAAI,CAAC;AAC3E,SAAK,MAAM,QAAQ,CAAQ,SAAA,KAAK,MAAM;AAAA,EACxC;AAAA,EAvBA,OAAO,WAAW;AACV,UAAA,SAAS,iBAAiBC,aAAW,IAAI;AACzC,UAAA,SAAS,2BAA2BC,sBAAoB,IAAI;AAC5D,UAAA,SAAS,sBAAsB,iBAAiB,IAAI;AAAA,EAC5D;AAAA,EAqBA,KAAK,MAAgB;AACnB,SAAK,cAAc;AACnB,SAAK,YAAY;AACjB,SAAK,cAAc,MAAM;AACzB,SAAK,MAAM,KAAK,WAAW,YAAY,KAAK,OAAO;AACnD,SAAK,kBAAkB;AACvB,SAAK,cAAc,IAAI;AAGjB,UAAA,WAAW,KAAK;AACtB,UAAM,MAAW;AACjB,UAAM,mBAAmB,IAAI,oBAAoB,IAAI,0BAA0B,IAAI;AACnF,UAAM,UAAU,SAAS;AACzB,SAAK,WAAW,IAAI,iBAAiB,CAAC,iBAAiB;AACrD,iBAAW,YAAY,cAAc;AACnC,cAAM,SAAS,SAAS;AAClB,cAAA,QAAQ,OAAO,cAAc,KAAK;AACxC,YAAI,OAAO;AACT,eAAK,kBAAkB;AAAA,QACzB;AAAA,MACF;AAAA,IAAA,CACD;AACI,SAAA,SAAS,QAAQ,SAAS;AAAA,MAC7B,YAAY;AAAA,MACZ,iBAAiB,CAAC,OAAO;AAAA,MACzB,mBAAmB;AAAA,MACnB,SAAS;AAAA,IAAA,CACV;AACD,aAAS,KAAK,iBAAiB,SAAS,KAAK,kBAAkB,IAAI;AAAA,EACrE;AAAA,EAEA,OAAO;AACD,QAAA,CAAC,KAAK,aAAa;AACrB;AAAA,IACF;AAEM,UAAA,SAAS,KAAK,YAAY,iBAAiB;AACjD,QAAI,QAAQ;AACH,aAAA,UAAU,OAAO,oBAAoB;AAAA,IAC9C;AAEA,SAAK,YAAY;AACjB,SAAK,cAAc;AACnB,SAAK,MAAM,KAAK,WAAW,YAAY,KAAK,OAAO;AACnD,SAAK,QAAQ,MAAM,YAAY,WAAW,MAAM;AAChD,SAAK,cAAc,EAAE;AACrB,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,SAAS;AACP,SAAK,kBAAkB;AACvB,SAAK,QAAQ,QAAQ,CAAU,WAAA,OAAO,UAAU;AAAA,EAClD;AAAA,EAEA,cAAc,MAAgB;AAC5B,SAAK,UAAU,KAAK,WAAA,EAAa,IAAI,CAAC,gBAAqB;AACnD,YAAA,SAAiB,IAAI,YAAY,IAAI;AAC3C,aAAO,SAAS;AACT,aAAA;AAAA,IAAA,CACR;AAAA,EACH;AAAA,EAEA,iBAAiB;AACf,SAAK,QAAQ,QAAQ,CAAC,WAAmB,OAAO,WAAW;AAC3D,SAAK,UAAU;EACjB;AAAA,EAEA,oBAAoB;AACd,QAAA,CAAC,KAAK,aAAa;AACrB;AAAA,IACF;AAEM,UAAA,gBAAgB,KAAK,YAAY,kBAAkB;AACzD,QAAI,CAAC,eAAe;AAClB;AAAA,IACF;AAEM,UAAA,SAAsB,KAAK,MAAM,KAAK;AACtC,UAAA,WAAW,cAAc;AACzB,UAAA,aAAa,OAAO;AAEnB,WAAA,OAAO,KAAK,QAAQ,OAAO;AAAA,MAChC,SAAS;AAAA,MACT,MAAM,GAAG,SAAS,OAAO,WAAW,OAAO,IAAI,OAAO,UAAU;AAAA,MAChE,KAAK,GAAG,SAAS,MAAM,WAAW,MAAM,OAAO,SAAS;AAAA,MACxD,OAAO,GAAG,SAAS,KAAK;AAAA,MACxB,QAAQ,GAAG,SAAS,MAAM;AAAA,IAAA,CAC3B;AAAA,EACH;AAAA,EAEA,cAAc,OAAe;AAC3B,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGI,UAAA,QAAQ,CAAC,SAAiB;AAE9B,WAAK,MAAM,KAAK,MAAM,YAAY,MAAM,KAAK;AAC7C,UAAI,SAAS,iBAAiB;AAC5B,iBAAS,gBAAgB,MAAM,YAAY,MAAM,KAAK;AAAA,MACxD;AAAA,IAAA,CACD;AAAA,EACH;AAeF;"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import Action from "./Action.es.js";
|
|
2
2
|
const MIN_WIDTH = 40;
|
|
3
|
-
|
|
3
|
+
function getElementStyle(element) {
|
|
4
|
+
return element.currentStyle ? element.currentStyle : window.getComputedStyle(element, null);
|
|
5
|
+
}
|
|
4
6
|
class CustomResizeAction extends Action {
|
|
5
7
|
constructor(formatter) {
|
|
6
8
|
super(formatter);
|
|
@@ -32,7 +34,7 @@ class CustomResizeAction extends Action {
|
|
|
32
34
|
root = this.formatter.quill.root;
|
|
33
35
|
rootStyle = getElementStyle(root);
|
|
34
36
|
}
|
|
35
|
-
this.maxWidth = root.clientWidth - parseFloat(rootStyle.paddingRight) - parseFloat(rootStyle.paddingLeft);
|
|
37
|
+
this.maxWidth = root.clientWidth - Number.parseFloat(rootStyle.paddingRight) - Number.parseFloat(rootStyle.paddingLeft);
|
|
36
38
|
document.addEventListener("mousemove", this.onDrag);
|
|
37
39
|
document.addEventListener("mouseup", this.onMouseUp);
|
|
38
40
|
};
|
|
@@ -129,10 +131,10 @@ class CustomResizeAction extends Action {
|
|
|
129
131
|
let handleYOffset = "0px";
|
|
130
132
|
if (handleStyle) {
|
|
131
133
|
if (handleStyle.width) {
|
|
132
|
-
handleXOffset = `${-parseFloat(handleStyle.width) / 2}px`;
|
|
134
|
+
handleXOffset = `${-Number.parseFloat(handleStyle.width) / 2}px`;
|
|
133
135
|
}
|
|
134
136
|
if (handleStyle.height) {
|
|
135
|
-
handleYOffset = `${-parseFloat(handleStyle.height) / 2}px`;
|
|
137
|
+
handleYOffset = `${-Number.parseFloat(handleStyle.height) / 2}px`;
|
|
136
138
|
}
|
|
137
139
|
}
|
|
138
140
|
Object.assign(this.topLeftHandle.style, { left: handleXOffset, top: handleYOffset });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomResizeAction.es.js","sources":["../../../../src/custom-image/actions/CustomResizeAction.ts"],"sourcesContent":["import Action from './Action'\r\nconst MIN_WIDTH = 40\r\n\r\nconst getElementStyle = element => element.currentStyle\r\n ? element.currentStyle\r\n : window.getComputedStyle(element, null)\r\nexport default class CustomResizeAction extends Action {\r\n topLeftHandle: HTMLElement\r\n topRightHandle: HTMLElement\r\n bottomRightHandle: HTMLElement\r\n bottomLeftHandle: HTMLElement\r\n dragHandle: HTMLElement\r\n dragStartX: number\r\n preDragWidth: number\r\n targetRatio: number\r\n maxWidth: number\r\n minWidth: number\r\n\r\n constructor(formatter) {\r\n super(formatter)\r\n this.topLeftHandle = this.createHandle('top-left', 'nwse-resize')\r\n this.topRightHandle = this.createHandle('top-right', 'nesw-resize')\r\n this.bottomRightHandle = this.createHandle('bottom-right', 'nwse-resize')\r\n this.bottomLeftHandle = this.createHandle('bottom-left', 'nesw-resize')\r\n this.dragHandle = null\r\n this.dragStartX = 0\r\n this.preDragWidth = 0\r\n this.targetRatio = 0\r\n this.maxWidth = 0\r\n this.minWidth = MIN_WIDTH\r\n }\r\n\r\n onCreate() {\r\n const target: any = this.formatter.currentSpec.getTargetElement()\r\n this.formatter.overlay.setAttribute('data-image', target.src)\r\n this.formatter.overlay.appendChild(this.topLeftHandle)\r\n this.formatter.overlay.appendChild(this.topRightHandle)\r\n this.formatter.overlay.appendChild(this.bottomRightHandle)\r\n this.formatter.overlay.appendChild(this.bottomLeftHandle)\r\n this.repositionHandles(this.formatter.options.resize.handleStyle)\r\n }\r\n\r\n onDestroy() {\r\n this.setCursor('')\r\n this.formatter.overlay.removeChild(this.topLeftHandle)\r\n this.formatter.overlay.removeChild(this.topRightHandle)\r\n this.formatter.overlay.removeChild(this.bottomRightHandle)\r\n this.formatter.overlay.removeChild(this.bottomLeftHandle)\r\n }\r\n\r\n createHandle(position: string, cursor: string): HTMLElement {\r\n const box = document.createElement('div')\r\n box.classList.add(this.formatter.options.resize.handleClassName)\r\n box.setAttribute('data-position', position)\r\n box.style.cursor = cursor\r\n\r\n if (this.formatter.options.resize.handleStyle) {\r\n Object.assign(box.style, this.formatter.options.resize.handleStyle)\r\n }\r\n\r\n box.addEventListener('mousedown', this.onMouseDown)\r\n return box\r\n }\r\n\r\n repositionHandles(handleStyle: any) {\r\n let handleXOffset = '0px'\r\n let handleYOffset = '0px'\r\n if (handleStyle) {\r\n if (handleStyle.width) {\r\n handleXOffset = `${-parseFloat(handleStyle.width) / 2}px`\r\n }\r\n if (handleStyle.height) {\r\n handleYOffset = `${-parseFloat(handleStyle.height) / 2}px`\r\n }\r\n }\r\n\r\n Object.assign(this.topLeftHandle.style, { left: handleXOffset, top: handleYOffset })\r\n Object.assign(this.topRightHandle.style, { right: handleXOffset, top: handleYOffset })\r\n Object.assign(this.bottomRightHandle.style, { right: handleXOffset, bottom: handleYOffset })\r\n Object.assign(this.bottomLeftHandle.style, { left: handleXOffset, bottom: handleYOffset })\r\n }\r\n\r\n setCursor(value: string) {\r\n if (document.body) {\r\n document.body.style.cursor = value\r\n }\r\n\r\n if (this.formatter.currentSpec) {\r\n const target = this.formatter.currentSpec.getOverlayElement()\r\n if (target) {\r\n target.style.cursor = value\r\n }\r\n }\r\n }\r\n\r\n onMouseDown = (event: MouseEvent) => {\r\n if (!(event.target instanceof HTMLElement)) {\r\n return\r\n }\r\n\r\n this.dragHandle = event.target\r\n this.setCursor(this.dragHandle.style.cursor)\r\n\r\n if (!this.formatter.currentSpec) {\r\n return\r\n }\r\n\r\n const target = this.formatter.currentSpec.getTargetElement()\r\n if (!target) {\r\n return\r\n }\r\n event.preventDefault()\r\n const rect = target.getBoundingClientRect()\r\n\r\n this.dragStartX = event.clientX\r\n this.preDragWidth = rect.width\r\n this.targetRatio = rect.height / rect.width\r\n\r\n let root: HTMLElement\r\n let rootStyle: any\r\n const tdWrap = this.findTd(target, 0)\r\n if (tdWrap) {\r\n root = tdWrap\r\n rootStyle = getElementStyle(tdWrap)\r\n }\r\n else {\r\n root = this.formatter.quill.root\r\n rootStyle = getElementStyle(root)\r\n }\r\n this.maxWidth = root.clientWidth\r\n - parseFloat(rootStyle.paddingRight)\r\n - parseFloat(rootStyle.paddingLeft)\r\n\r\n document.addEventListener('mousemove', this.onDrag)\r\n document.addEventListener('mouseup', this.onMouseUp)\r\n }\r\n\r\n findTd = (node: HTMLElement, level: number) => {\r\n if (level > 3) {\r\n return null\r\n }\r\n\r\n const tagName = node.tagName.toUpperCase()\r\n if (tagName === 'TD') {\r\n return node\r\n }\r\n else {\r\n const parentNode = node.parentElement\r\n if (parentNode) {\r\n // eslint-disable-next-line no-return-assign\r\n return (this.findTd(parentNode, level += 1))\r\n }\r\n else {\r\n return null\r\n }\r\n }\r\n }\r\n\r\n onDrag = (event: MouseEvent) => {\r\n if (!this.formatter.currentSpec) {\r\n return\r\n }\r\n\r\n const target = this.formatter.currentSpec.getTargetElement()\r\n if (!target) {\r\n return\r\n }\r\n\r\n const deltaX = event.clientX - this.dragStartX\r\n let newWidth = 0\r\n\r\n if (this.dragHandle === this.topLeftHandle || this.dragHandle === this.bottomLeftHandle) {\r\n newWidth = Math.round(this.preDragWidth - deltaX)\r\n }\r\n else {\r\n newWidth = Math.round(this.preDragWidth + deltaX)\r\n }\r\n\r\n let minWidth = this.minWidth\r\n\r\n if (this.maxWidth < minWidth) {\r\n minWidth = this.maxWidth\r\n }\r\n\r\n if (newWidth > this.maxWidth) {\r\n newWidth = this.maxWidth\r\n }\r\n else if (newWidth < minWidth) {\r\n newWidth = minWidth\r\n }\r\n\r\n const newHeight = this.targetRatio * newWidth\r\n\r\n target.setAttribute('width', `${newWidth}`)\r\n target.setAttribute('height', `${newHeight}`)\r\n\r\n this.formatter.update()\r\n }\r\n\r\n onMouseUp = () => {\r\n this.setCursor('')\r\n document.removeEventListener('mousemove', this.onDrag)\r\n document.removeEventListener('mouseup', this.onMouseUp)\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CustomResizeAction.es.js","sources":["../../../../src/custom-image/actions/CustomResizeAction.ts"],"sourcesContent":["import Action from './Action'\r\n\r\nconst MIN_WIDTH = 40\r\n\r\nfunction getElementStyle(element) {\r\n return element.currentStyle\r\n ? element.currentStyle\r\n : window.getComputedStyle(element, null)\r\n}\r\nexport default class CustomResizeAction extends Action {\r\n topLeftHandle: HTMLElement\r\n topRightHandle: HTMLElement\r\n bottomRightHandle: HTMLElement\r\n bottomLeftHandle: HTMLElement\r\n dragHandle: HTMLElement\r\n dragStartX: number\r\n preDragWidth: number\r\n targetRatio: number\r\n maxWidth: number\r\n minWidth: number\r\n\r\n constructor(formatter) {\r\n super(formatter)\r\n this.topLeftHandle = this.createHandle('top-left', 'nwse-resize')\r\n this.topRightHandle = this.createHandle('top-right', 'nesw-resize')\r\n this.bottomRightHandle = this.createHandle('bottom-right', 'nwse-resize')\r\n this.bottomLeftHandle = this.createHandle('bottom-left', 'nesw-resize')\r\n this.dragHandle = null\r\n this.dragStartX = 0\r\n this.preDragWidth = 0\r\n this.targetRatio = 0\r\n this.maxWidth = 0\r\n this.minWidth = MIN_WIDTH\r\n }\r\n\r\n onCreate() {\r\n const target: any = this.formatter.currentSpec.getTargetElement()\r\n this.formatter.overlay.setAttribute('data-image', target.src)\r\n this.formatter.overlay.appendChild(this.topLeftHandle)\r\n this.formatter.overlay.appendChild(this.topRightHandle)\r\n this.formatter.overlay.appendChild(this.bottomRightHandle)\r\n this.formatter.overlay.appendChild(this.bottomLeftHandle)\r\n this.repositionHandles(this.formatter.options.resize.handleStyle)\r\n }\r\n\r\n onDestroy() {\r\n this.setCursor('')\r\n this.formatter.overlay.removeChild(this.topLeftHandle)\r\n this.formatter.overlay.removeChild(this.topRightHandle)\r\n this.formatter.overlay.removeChild(this.bottomRightHandle)\r\n this.formatter.overlay.removeChild(this.bottomLeftHandle)\r\n }\r\n\r\n createHandle(position: string, cursor: string): HTMLElement {\r\n const box = document.createElement('div')\r\n box.classList.add(this.formatter.options.resize.handleClassName)\r\n box.setAttribute('data-position', position)\r\n box.style.cursor = cursor\r\n\r\n if (this.formatter.options.resize.handleStyle) {\r\n Object.assign(box.style, this.formatter.options.resize.handleStyle)\r\n }\r\n\r\n box.addEventListener('mousedown', this.onMouseDown)\r\n return box\r\n }\r\n\r\n repositionHandles(handleStyle: any) {\r\n let handleXOffset = '0px'\r\n let handleYOffset = '0px'\r\n if (handleStyle) {\r\n if (handleStyle.width) {\r\n handleXOffset = `${-Number.parseFloat(handleStyle.width) / 2}px`\r\n }\r\n if (handleStyle.height) {\r\n handleYOffset = `${-Number.parseFloat(handleStyle.height) / 2}px`\r\n }\r\n }\r\n\r\n Object.assign(this.topLeftHandle.style, { left: handleXOffset, top: handleYOffset })\r\n Object.assign(this.topRightHandle.style, { right: handleXOffset, top: handleYOffset })\r\n Object.assign(this.bottomRightHandle.style, { right: handleXOffset, bottom: handleYOffset })\r\n Object.assign(this.bottomLeftHandle.style, { left: handleXOffset, bottom: handleYOffset })\r\n }\r\n\r\n setCursor(value: string) {\r\n if (document.body) {\r\n document.body.style.cursor = value\r\n }\r\n\r\n if (this.formatter.currentSpec) {\r\n const target = this.formatter.currentSpec.getOverlayElement()\r\n if (target) {\r\n target.style.cursor = value\r\n }\r\n }\r\n }\r\n\r\n onMouseDown = (event: MouseEvent) => {\r\n if (!(event.target instanceof HTMLElement)) {\r\n return\r\n }\r\n\r\n this.dragHandle = event.target\r\n this.setCursor(this.dragHandle.style.cursor)\r\n\r\n if (!this.formatter.currentSpec) {\r\n return\r\n }\r\n\r\n const target = this.formatter.currentSpec.getTargetElement()\r\n if (!target) {\r\n return\r\n }\r\n event.preventDefault()\r\n const rect = target.getBoundingClientRect()\r\n\r\n this.dragStartX = event.clientX\r\n this.preDragWidth = rect.width\r\n this.targetRatio = rect.height / rect.width\r\n\r\n let root: HTMLElement\r\n let rootStyle: any\r\n const tdWrap = this.findTd(target, 0)\r\n if (tdWrap) {\r\n root = tdWrap\r\n rootStyle = getElementStyle(tdWrap)\r\n }\r\n else {\r\n root = this.formatter.quill.root\r\n rootStyle = getElementStyle(root)\r\n }\r\n this.maxWidth = root.clientWidth\r\n - Number.parseFloat(rootStyle.paddingRight)\r\n - Number.parseFloat(rootStyle.paddingLeft)\r\n\r\n document.addEventListener('mousemove', this.onDrag)\r\n document.addEventListener('mouseup', this.onMouseUp)\r\n }\r\n\r\n findTd = (node: HTMLElement, level: number) => {\r\n if (level > 3) {\r\n return null\r\n }\r\n\r\n const tagName = node.tagName.toUpperCase()\r\n if (tagName === 'TD') {\r\n return node\r\n }\r\n else {\r\n const parentNode = node.parentElement\r\n if (parentNode) {\r\n return (this.findTd(parentNode, level += 1))\r\n }\r\n else {\r\n return null\r\n }\r\n }\r\n }\r\n\r\n onDrag = (event: MouseEvent) => {\r\n if (!this.formatter.currentSpec) {\r\n return\r\n }\r\n\r\n const target = this.formatter.currentSpec.getTargetElement()\r\n if (!target) {\r\n return\r\n }\r\n\r\n const deltaX = event.clientX - this.dragStartX\r\n let newWidth = 0\r\n\r\n if (this.dragHandle === this.topLeftHandle || this.dragHandle === this.bottomLeftHandle) {\r\n newWidth = Math.round(this.preDragWidth - deltaX)\r\n }\r\n else {\r\n newWidth = Math.round(this.preDragWidth + deltaX)\r\n }\r\n\r\n let minWidth = this.minWidth\r\n\r\n if (this.maxWidth < minWidth) {\r\n minWidth = this.maxWidth\r\n }\r\n\r\n if (newWidth > this.maxWidth) {\r\n newWidth = this.maxWidth\r\n }\r\n else if (newWidth < minWidth) {\r\n newWidth = minWidth\r\n }\r\n\r\n const newHeight = this.targetRatio * newWidth\r\n\r\n target.setAttribute('width', `${newWidth}`)\r\n target.setAttribute('height', `${newHeight}`)\r\n\r\n this.formatter.update()\r\n }\r\n\r\n onMouseUp = () => {\r\n this.setCursor('')\r\n document.removeEventListener('mousemove', this.onDrag)\r\n document.removeEventListener('mouseup', this.onMouseUp)\r\n }\r\n}\r\n"],"names":[],"mappings":";AAEA,MAAM,YAAY;AAElB,SAAS,gBAAgB,SAAS;AAChC,SAAO,QAAQ,eACX,QAAQ,eACR,OAAO,iBAAiB,SAAS,IAAI;AAC3C;AACA,MAAqB,2BAA2B,OAAO;AAAA,EAYrD,YAAY,WAAW;AACrB,UAAM,SAAS;AA4EjB,SAAA,cAAc,CAAC,UAAsB;AAC/B,UAAA,EAAE,MAAM,kBAAkB,cAAc;AAC1C;AAAA,MACF;AAEA,WAAK,aAAa,MAAM;AACxB,WAAK,UAAU,KAAK,WAAW,MAAM,MAAM;AAEvC,UAAA,CAAC,KAAK,UAAU,aAAa;AAC/B;AAAA,MACF;AAEA,YAAM,SAAS,KAAK,UAAU,YAAY,iBAAiB;AAC3D,UAAI,CAAC,QAAQ;AACX;AAAA,MACF;AACA,YAAM,eAAe;AACf,YAAA,OAAO,OAAO;AAEpB,WAAK,aAAa,MAAM;AACxB,WAAK,eAAe,KAAK;AACpB,WAAA,cAAc,KAAK,SAAS,KAAK;AAElC,UAAA;AACA,UAAA;AACJ,YAAM,SAAS,KAAK,OAAO,QAAQ,CAAC;AACpC,UAAI,QAAQ;AACH,eAAA;AACP,oBAAY,gBAAgB,MAAM;AAAA,MAAA,OAE/B;AACI,eAAA,KAAK,UAAU,MAAM;AAC5B,oBAAY,gBAAgB,IAAI;AAAA,MAClC;AACK,WAAA,WAAW,KAAK,cACnB,OAAO,WAAW,UAAU,YAAY,IACxC,OAAO,WAAW,UAAU,WAAW;AAEhC,eAAA,iBAAiB,aAAa,KAAK,MAAM;AACzC,eAAA,iBAAiB,WAAW,KAAK,SAAS;AAAA,IAAA;AAG5C,SAAA,SAAA,CAAC,MAAmB,UAAkB;AAC7C,UAAI,QAAQ,GAAG;AACN,eAAA;AAAA,MACT;AAEM,YAAA,UAAU,KAAK,QAAQ,YAAY;AACzC,UAAI,YAAY,MAAM;AACb,eAAA;AAAA,MAAA,OAEJ;AACH,cAAM,aAAa,KAAK;AACxB,YAAI,YAAY;AACd,iBAAQ,KAAK,OAAO,YAAY,SAAS,CAAC;AAAA,QAAA,OAEvC;AACI,iBAAA;AAAA,QACT;AAAA,MACF;AAAA,IAAA;AAGF,SAAA,SAAS,CAAC,UAAsB;AAC1B,UAAA,CAAC,KAAK,UAAU,aAAa;AAC/B;AAAA,MACF;AAEA,YAAM,SAAS,KAAK,UAAU,YAAY,iBAAiB;AAC3D,UAAI,CAAC,QAAQ;AACX;AAAA,MACF;AAEM,YAAA,SAAS,MAAM,UAAU,KAAK;AACpC,UAAI,WAAW;AAEf,UAAI,KAAK,eAAe,KAAK,iBAAiB,KAAK,eAAe,KAAK,kBAAkB;AACvF,mBAAW,KAAK,MAAM,KAAK,eAAe,MAAM;AAAA,MAAA,OAE7C;AACH,mBAAW,KAAK,MAAM,KAAK,eAAe,MAAM;AAAA,MAClD;AAEA,UAAI,WAAW,KAAK;AAEhB,UAAA,KAAK,WAAW,UAAU;AAC5B,mBAAW,KAAK;AAAA,MAClB;AAEI,UAAA,WAAW,KAAK,UAAU;AAC5B,mBAAW,KAAK;AAAA,MAAA,WAET,WAAW,UAAU;AACjB,mBAAA;AAAA,MACb;AAEM,YAAA,YAAY,KAAK,cAAc;AAErC,aAAO,aAAa,SAAS,GAAG,QAAQ,EAAE;AAC1C,aAAO,aAAa,UAAU,GAAG,SAAS,EAAE;AAE5C,WAAK,UAAU;IAAO;AAGxB,SAAA,YAAY,MAAM;AAChB,WAAK,UAAU,EAAE;AACR,eAAA,oBAAoB,aAAa,KAAK,MAAM;AAC5C,eAAA,oBAAoB,WAAW,KAAK,SAAS;AAAA,IAAA;AArLtD,SAAK,gBAAgB,KAAK,aAAa,YAAY,aAAa;AAChE,SAAK,iBAAiB,KAAK,aAAa,aAAa,aAAa;AAClE,SAAK,oBAAoB,KAAK,aAAa,gBAAgB,aAAa;AACxE,SAAK,mBAAmB,KAAK,aAAa,eAAe,aAAa;AACtE,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,WAAW;AAChB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,WAAW;AACT,UAAM,SAAc,KAAK,UAAU,YAAY,iBAAiB;AAChE,SAAK,UAAU,QAAQ,aAAa,cAAc,OAAO,GAAG;AAC5D,SAAK,UAAU,QAAQ,YAAY,KAAK,aAAa;AACrD,SAAK,UAAU,QAAQ,YAAY,KAAK,cAAc;AACtD,SAAK,UAAU,QAAQ,YAAY,KAAK,iBAAiB;AACzD,SAAK,UAAU,QAAQ,YAAY,KAAK,gBAAgB;AACxD,SAAK,kBAAkB,KAAK,UAAU,QAAQ,OAAO,WAAW;AAAA,EAClE;AAAA,EAEA,YAAY;AACV,SAAK,UAAU,EAAE;AACjB,SAAK,UAAU,QAAQ,YAAY,KAAK,aAAa;AACrD,SAAK,UAAU,QAAQ,YAAY,KAAK,cAAc;AACtD,SAAK,UAAU,QAAQ,YAAY,KAAK,iBAAiB;AACzD,SAAK,UAAU,QAAQ,YAAY,KAAK,gBAAgB;AAAA,EAC1D;AAAA,EAEA,aAAa,UAAkB,QAA6B;AACpD,UAAA,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,UAAU,IAAI,KAAK,UAAU,QAAQ,OAAO,eAAe;AAC3D,QAAA,aAAa,iBAAiB,QAAQ;AAC1C,QAAI,MAAM,SAAS;AAEnB,QAAI,KAAK,UAAU,QAAQ,OAAO,aAAa;AAC7C,aAAO,OAAO,IAAI,OAAO,KAAK,UAAU,QAAQ,OAAO,WAAW;AAAA,IACpE;AAEI,QAAA,iBAAiB,aAAa,KAAK,WAAW;AAC3C,WAAA;AAAA,EACT;AAAA,EAEA,kBAAkB,aAAkB;AAClC,QAAI,gBAAgB;AACpB,QAAI,gBAAgB;AACpB,QAAI,aAAa;AACf,UAAI,YAAY,OAAO;AACrB,wBAAgB,GAAG,CAAC,OAAO,WAAW,YAAY,KAAK,IAAI,CAAC;AAAA,MAC9D;AACA,UAAI,YAAY,QAAQ;AACtB,wBAAgB,GAAG,CAAC,OAAO,WAAW,YAAY,MAAM,IAAI,CAAC;AAAA,MAC/D;AAAA,IACF;AAEO,WAAA,OAAO,KAAK,cAAc,OAAO,EAAE,MAAM,eAAe,KAAK,cAAA,CAAe;AAC5E,WAAA,OAAO,KAAK,eAAe,OAAO,EAAE,OAAO,eAAe,KAAK,cAAA,CAAe;AAC9E,WAAA,OAAO,KAAK,kBAAkB,OAAO,EAAE,OAAO,eAAe,QAAQ,cAAA,CAAe;AACpF,WAAA,OAAO,KAAK,iBAAiB,OAAO,EAAE,MAAM,eAAe,QAAQ,cAAA,CAAe;AAAA,EAC3F;AAAA,EAEA,UAAU,OAAe;AACvB,QAAI,SAAS,MAAM;AACR,eAAA,KAAK,MAAM,SAAS;AAAA,IAC/B;AAEI,QAAA,KAAK,UAAU,aAAa;AAC9B,YAAM,SAAS,KAAK,UAAU,YAAY,kBAAkB;AAC5D,UAAI,QAAQ;AACV,eAAO,MAAM,SAAS;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AA8GF;"}
|
|
@@ -14,7 +14,7 @@ const _CustomImage = class _CustomImage extends Embed {
|
|
|
14
14
|
}
|
|
15
15
|
node.setAttribute("src", imgURL);
|
|
16
16
|
}
|
|
17
|
-
node.setAttribute("data-image-id",
|
|
17
|
+
node.setAttribute("data-image-id", `img${_CustomImage.ID_SEED++}`);
|
|
18
18
|
node.setAttribute("devui-editorx-image", true);
|
|
19
19
|
node.style.verticalAlign = "baseline";
|
|
20
20
|
return node;
|
|
@@ -49,7 +49,7 @@ const _CustomImage = class _CustomImage extends Embed {
|
|
|
49
49
|
return formats;
|
|
50
50
|
}
|
|
51
51
|
format(name, value) {
|
|
52
|
-
if (ATTRIBUTES.
|
|
52
|
+
if (ATTRIBUTES.includes(name)) {
|
|
53
53
|
if (value) {
|
|
54
54
|
this.domNode.setAttribute(name, value);
|
|
55
55
|
} else {
|
|
@@ -68,7 +68,7 @@ const _CustomImage = class _CustomImage extends Embed {
|
|
|
68
68
|
this.parent.insertBefore(wrapper, this.next || void 0);
|
|
69
69
|
}
|
|
70
70
|
if (typeof wrapper.appendChild !== "function") {
|
|
71
|
-
throw new
|
|
71
|
+
throw new TypeError(`Cannot wrap ${name}`);
|
|
72
72
|
}
|
|
73
73
|
wrapper.appendChild(this);
|
|
74
74
|
return wrapper;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.es.js","sources":["../../../src/custom-image/image.ts"],"sourcesContent":["import Quill from 'quill'\r\nimport { isNullOrUndefined, sanitize } from '../config/editor.utils'\r\nconst Embed = Quill.imports['blots/embed']\r\nconst Inline = Quill.imports['blots/inline']\r\n\r\nconst ATTRIBUTES = ['alt', 'height', 'width', 'image-id']\r\n\r\n// @dynamic\r\nclass CustomImage extends Embed {\r\n static ID_SEED = 0\r\n static blotName: string\r\n static tagName: string\r\n domNode: any\r\n parent: any\r\n scroll: any\r\n next: any\r\n static create(value) {\r\n const node = super.create(value)\r\n const url = typeof value === 'string' ? value : value.src\r\n if (url) {\r\n const imgURL = this.sanitize(url)\r\n if (!imgURL?.startsWith('data:image')) {\r\n node.dataset.src = imgURL\r\n }\r\n node.setAttribute('src', imgURL)\r\n }\r\n node.setAttribute('data-image-id',
|
|
1
|
+
{"version":3,"file":"image.es.js","sources":["../../../src/custom-image/image.ts"],"sourcesContent":["import Quill from 'quill'\r\nimport { isNullOrUndefined, sanitize } from '../config/editor.utils'\r\n\r\nconst Embed = Quill.imports['blots/embed']\r\nconst Inline = Quill.imports['blots/inline']\r\n\r\nconst ATTRIBUTES = ['alt', 'height', 'width', 'image-id']\r\n\r\n// @dynamic\r\nclass CustomImage extends Embed {\r\n static ID_SEED = 0\r\n static blotName: string\r\n static tagName: string\r\n domNode: any\r\n parent: any\r\n scroll: any\r\n next: any\r\n static create(value) {\r\n const node = super.create(value)\r\n const url = typeof value === 'string' ? value : value.src\r\n if (url) {\r\n const imgURL = this.sanitize(url)\r\n if (!imgURL?.startsWith('data:image')) {\r\n node.dataset.src = imgURL\r\n }\r\n node.setAttribute('src', imgURL)\r\n }\r\n node.setAttribute('data-image-id', `img${CustomImage.ID_SEED++}`)\r\n node.setAttribute('devui-editorx-image', true)\r\n node.style.verticalAlign = 'baseline'\r\n return node\r\n }\r\n\r\n static formats(domNode) {\r\n return ATTRIBUTES.reduce((formats, attribute) => {\r\n if (domNode.hasAttribute(attribute)) {\r\n formats[attribute] = domNode.getAttribute(attribute)\r\n }\r\n return formats\r\n }, {})\r\n }\r\n\r\n static match(url) {\r\n return /\\.(jpe?g|gif|png)$/.test(url) || /^data:image\\/.+;base64/.test(url)\r\n }\r\n\r\n static register() {\r\n if (/Firefox/i.test(navigator.userAgent)) {\r\n setTimeout(() => {\r\n // Disable image resizing in Firefox\r\n document.execCommand('enableObjectResizing', false, null)\r\n }, 1)\r\n }\r\n }\r\n\r\n static sanitize(url) {\r\n return sanitize(url, ['http', 'https', 'data']) ? url : '//:0'\r\n }\r\n\r\n static value(domNode) {\r\n const formats: any = {}\r\n const imageSrc = domNode.getAttribute('src')\r\n formats.src = this.sanitize(imageSrc)\r\n formats.hasExisted = domNode.getAttribute('devui-editorx-image')\r\n formats.imageId = domNode.dataset.imageId\r\n return formats\r\n }\r\n\r\n format(name, value) {\r\n if (ATTRIBUTES.includes(name)) {\r\n if (value) {\r\n this.domNode.setAttribute(name, value)\r\n }\r\n else {\r\n this.domNode.removeAttribute(name)\r\n }\r\n }\r\n else {\r\n super.format(name, value)\r\n }\r\n }\r\n\r\n unWrap() {\r\n this.parent.replaceWith(this)\r\n }\r\n\r\n wrap(name, value) {\r\n const wrapper = typeof name === 'string' ? this.scroll.create(name, value) : name\r\n if (!isNullOrUndefined(this.parent)) {\r\n this.parent.insertBefore(wrapper, this.next || undefined)\r\n }\r\n if (typeof wrapper.appendChild !== 'function') {\r\n throw new TypeError(`Cannot wrap ${name}`)\r\n }\r\n wrapper.appendChild(this)\r\n return wrapper\r\n }\r\n}\r\nCustomImage.blotName = 'image'\r\nCustomImage.tagName = 'IMG'\r\n\r\n// @dynamic\r\nclass CustomImageContainer extends Inline {\r\n static tagName: string\r\n static className: string\r\n static blotName: string\r\n static allowedChildren: typeof CustomImage[]\r\n constructor(scroll, domNode) {\r\n super(scroll, domNode)\r\n domNode.setAttribute('contenteditable', false)\r\n }\r\n}\r\nCustomImageContainer.blotName = 'image-container'\r\nCustomImageContainer.className = 'ql-image-container'\r\nCustomImageContainer.tagName = 'DIV'\r\n\r\nCustomImageContainer.allowedChildren = [CustomImage]\r\nexport { CustomImage as default, CustomImageContainer as ImageContainerBlot }\r\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlotSpec.es.js","sources":["../../../../src/custom-image/specs/BlotSpec.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"BlotSpec.es.js","sources":["../../../../src/custom-image/specs/BlotSpec.ts"],"sourcesContent":["import ResizeAction from '../actions/CustomResizeAction'\r\nimport DeleteAction from '../actions/DeleteAction'\r\n\r\nexport default class BlotSpec {\r\n formatter\r\n\r\n constructor(formatter) {\r\n this.formatter = formatter\r\n }\r\n\r\n init(): void {}\r\n\r\n getActions() {\r\n return [ResizeAction, DeleteAction]\r\n }\r\n\r\n getTargetElement() {\r\n return null\r\n }\r\n\r\n getOverlayElement() {\r\n return this.getTargetElement()\r\n }\r\n\r\n setSelection(): void {\r\n this.formatter.quill.setSelection(null)\r\n }\r\n\r\n onHide() {}\r\n}\r\n"],"names":["ResizeAction"],"mappings":";;AAGA,MAAqB,SAAS;AAAA,EAG5B,YAAY,WAAW;AACrB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,OAAa;AAAA,EAAC;AAAA,EAEd,aAAa;AACJ,WAAA,CAACA,oBAAc,YAAY;AAAA,EACpC;AAAA,EAEA,mBAAmB;AACV,WAAA;AAAA,EACT;AAAA,EAEA,oBAAoB;AAClB,WAAO,KAAK;EACd;AAAA,EAEA,eAAqB;AACd,SAAA,UAAU,MAAM,aAAa,IAAI;AAAA,EACxC;AAAA,EAEA,SAAS;AAAA,EAAC;AACZ;"}
|
package/es/custom-uploader.es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Quill from "quill";
|
|
2
2
|
import { FILE_UPLOADER_MIME_TYPES, IMAGE_UPLOADER_MIME_TYPES } from "./config/editor.config.es.js";
|
|
3
3
|
const Uploader = Quill.imports["modules/uploader"];
|
|
4
|
-
const Delta = Quill.
|
|
4
|
+
const Delta = Quill.import("delta");
|
|
5
5
|
class CustomUploader extends Uploader {
|
|
6
6
|
constructor() {
|
|
7
7
|
super(...arguments);
|
|
@@ -12,10 +12,7 @@ class CustomUploader extends Uploader {
|
|
|
12
12
|
return acceptArr.some((type) => {
|
|
13
13
|
const validType = type.trim();
|
|
14
14
|
if (validType.startsWith(".")) {
|
|
15
|
-
return file.name.toLowerCase().
|
|
16
|
-
validType.toLowerCase(),
|
|
17
|
-
file.name.toLowerCase().length - validType.toLowerCase().length
|
|
18
|
-
) > -1;
|
|
15
|
+
return file.name.toLowerCase().includes(validType.toLowerCase(), file.name.toLowerCase().length - validType.toLowerCase().length);
|
|
19
16
|
} else if (/\/\*$/.test(validType)) {
|
|
20
17
|
return baseMimeType === validType.replace(/\/.*$/, "");
|
|
21
18
|
}
|
|
@@ -99,7 +96,7 @@ class CustomUploader extends Uploader {
|
|
|
99
96
|
handleUploadImage(range, { file, files }, hasRejectedImage) {
|
|
100
97
|
var _a, _b, _c;
|
|
101
98
|
if ((_a = this.quill.options.uploadOption) == null ? void 0 : _a.imageUpload) {
|
|
102
|
-
const imageEnableMultiUpload = this.enableMultiUpload === true || ((_b = this.enableMultiUpload) == null ? void 0 : _b
|
|
99
|
+
const imageEnableMultiUpload = this.enableMultiUpload === true || ((_b = this.enableMultiUpload) == null ? void 0 : _b.image);
|
|
103
100
|
const result = {
|
|
104
101
|
file,
|
|
105
102
|
data: { files: [file] },
|
|
@@ -116,7 +113,7 @@ class CustomUploader extends Uploader {
|
|
|
116
113
|
}
|
|
117
114
|
};
|
|
118
115
|
if (imageEnableMultiUpload) {
|
|
119
|
-
result
|
|
116
|
+
result.data = { files };
|
|
120
117
|
}
|
|
121
118
|
(_c = this.quill.options.uploadOption) == null ? void 0 : _c.imageUpload(result);
|
|
122
119
|
} else {
|