@jvs-milkdown/components 1.1.5 → 1.1.6
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/LICENSE +21 -0
- package/lib/__internal__/components/image-input.d.ts.map +1 -1
- package/lib/image-block/convert-plugin.d.ts +2 -0
- package/lib/image-block/convert-plugin.d.ts.map +1 -0
- package/lib/image-block/index.d.ts +2 -0
- package/lib/image-block/index.d.ts.map +1 -1
- package/lib/image-block/index.js +345 -75
- package/lib/image-block/index.js.map +1 -1
- package/lib/image-block/paste-rule.d.ts +2 -0
- package/lib/image-block/paste-rule.d.ts.map +1 -0
- package/lib/image-block/schema.d.ts.map +1 -1
- package/lib/image-block/view/components/image-block.d.ts +1 -0
- package/lib/image-block/view/components/image-block.d.ts.map +1 -1
- package/lib/image-block/view/components/image-viewer.d.ts.map +1 -1
- package/lib/image-block/view/index.d.ts.map +1 -1
- package/lib/image-inline/index.js +27 -6
- package/lib/image-inline/index.js.map +1 -1
- package/lib/link-tooltip/edit/component.d.ts.map +1 -1
- package/lib/link-tooltip/index.js +18 -4
- package/lib/link-tooltip/index.js.map +1 -1
- package/lib/table-block/dnd/drag-over-handler.d.ts.map +1 -1
- package/lib/table-block/index.js +139 -53
- package/lib/table-block/index.js.map +1 -1
- package/lib/table-block/view/component.d.ts.map +1 -1
- package/lib/table-block/view/drag.d.ts +3 -0
- package/lib/table-block/view/drag.d.ts.map +1 -1
- package/lib/table-block/view/utils.d.ts.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +53 -79
- package/src/__internal__/components/image-input.tsx +45 -12
- package/src/image-block/__tests__/paste-rule.spec.ts +20 -0
- package/src/image-block/convert-plugin.ts +147 -0
- package/src/image-block/index.ts +6 -0
- package/src/image-block/paste-rule.ts +138 -0
- package/src/image-block/schema.ts +15 -0
- package/src/image-block/view/components/image-block.tsx +5 -0
- package/src/image-block/view/components/image-viewer.tsx +4 -0
- package/src/image-block/view/index.ts +8 -0
- package/src/link-tooltip/edit/component.tsx +27 -3
- package/src/table-block/dnd/create-drag-handler.ts +5 -1
- package/src/table-block/dnd/drag-over-handler.ts +29 -1
- package/src/table-block/dnd/preview.ts +3 -3
- package/src/table-block/view/component.tsx +121 -39
- package/src/table-block/view/drag.ts +29 -16
- package/src/table-block/view/utils.ts +6 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020-present Mirone
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-input.d.ts","sourceRoot":"","sources":["../../../src/__internal__/components/image-input.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AASvD,KAAK,eAAe,GAAG;IACrB,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5B,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAE/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAE9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACzC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1D,CAAA;AAED,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"image-input.d.ts","sourceRoot":"","sources":["../../../src/__internal__/components/image-input.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AASvD,KAAK,eAAe,GAAG;IACrB,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC5B,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAE/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAE9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACzC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1D,CAAA;AAED,eAAO,MAAM,UAAU,0SA0LrB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert-plugin.d.ts","sourceRoot":"","sources":["../../src/image-block/convert-plugin.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,uBAAuB,sCAmIlC,CAAA"}
|
|
@@ -3,5 +3,7 @@ export * from './schema';
|
|
|
3
3
|
export * from './remark-plugin';
|
|
4
4
|
export * from './config';
|
|
5
5
|
export * from './view';
|
|
6
|
+
export * from './paste-rule';
|
|
7
|
+
export * from './convert-plugin';
|
|
6
8
|
export declare const imageBlockComponent: MilkdownPlugin[];
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/image-block/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/image-block/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AASvD,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,UAAU,CAAA;AACxB,cAAc,QAAQ,CAAA;AACtB,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAEhC,eAAO,MAAM,mBAAmB,EAAE,cAAc,EAOxC,CAAA"}
|
package/lib/image-block/index.js
CHANGED
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
import { $ctx, $
|
|
2
|
-
import {
|
|
1
|
+
import { $ctx, $nodeSchema, $prose, $pasteRule, $remark, $view } from '@jvs-milkdown/utils';
|
|
2
|
+
import { imageSchema, paragraphSchema } from '@jvs-milkdown/preset-commonmark';
|
|
3
|
+
import { PluginKey, Plugin } from '@jvs-milkdown/prose/state';
|
|
3
4
|
import { expectDomTypeError } from '@jvs-milkdown/exception';
|
|
5
|
+
import { Slice, Fragment as Fragment$1 } from '@jvs-milkdown/prose/model';
|
|
6
|
+
import { visit } from 'unist-util-visit';
|
|
4
7
|
import DOMPurify from 'dompurify';
|
|
5
|
-
import { h, defineComponent, ref, Fragment as Fragment$
|
|
8
|
+
import { h, defineComponent, ref, Fragment as Fragment$2, createApp, watchEffect } from 'vue';
|
|
6
9
|
import clsx from 'clsx';
|
|
7
10
|
import { customAlphabet } from 'nanoid';
|
|
8
11
|
|
|
9
|
-
var __defProp$
|
|
10
|
-
var __getOwnPropSymbols$
|
|
11
|
-
var __hasOwnProp$
|
|
12
|
-
var __propIsEnum$
|
|
13
|
-
var __defNormalProp$
|
|
14
|
-
var __spreadValues$
|
|
12
|
+
var __defProp$3 = Object.defineProperty;
|
|
13
|
+
var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
|
|
14
|
+
var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
|
|
15
|
+
var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
|
|
16
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
17
|
+
var __spreadValues$3 = (a, b) => {
|
|
15
18
|
for (var prop in b || (b = {}))
|
|
16
|
-
if (__hasOwnProp$
|
|
17
|
-
__defNormalProp$
|
|
18
|
-
if (__getOwnPropSymbols$
|
|
19
|
-
for (var prop of __getOwnPropSymbols$
|
|
20
|
-
if (__propIsEnum$
|
|
21
|
-
__defNormalProp$
|
|
19
|
+
if (__hasOwnProp$3.call(b, prop))
|
|
20
|
+
__defNormalProp$3(a, prop, b[prop]);
|
|
21
|
+
if (__getOwnPropSymbols$3)
|
|
22
|
+
for (var prop of __getOwnPropSymbols$3(b)) {
|
|
23
|
+
if (__propIsEnum$3.call(b, prop))
|
|
24
|
+
__defNormalProp$3(a, prop, b[prop]);
|
|
22
25
|
}
|
|
23
26
|
return a;
|
|
24
27
|
};
|
|
25
28
|
function withMeta(plugin, meta) {
|
|
26
29
|
Object.assign(plugin, {
|
|
27
|
-
meta: __spreadValues$
|
|
30
|
+
meta: __spreadValues$3({
|
|
28
31
|
package: "@jvs-milkdown/components"
|
|
29
32
|
}, meta)
|
|
30
33
|
});
|
|
@@ -49,52 +52,19 @@ withMeta(imageBlockConfig, {
|
|
|
49
52
|
group: "ImageBlock"
|
|
50
53
|
});
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (((_a = node.children) == null ? void 0 : _a.length) !== 1) return;
|
|
59
|
-
const firstChild = (_b = node.children) == null ? void 0 : _b[0];
|
|
60
|
-
if (!firstChild || firstChild.type !== "image") return;
|
|
61
|
-
const { url, alt, title } = firstChild;
|
|
62
|
-
const newNode = {
|
|
63
|
-
type: "image-block",
|
|
64
|
-
url,
|
|
65
|
-
alt,
|
|
66
|
-
title
|
|
67
|
-
};
|
|
68
|
-
parent.children.splice(index, 1, newNode);
|
|
69
|
-
}
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
const remarkImageBlockPlugin = $remark(
|
|
73
|
-
"remark-image-block",
|
|
74
|
-
() => () => visitImage
|
|
75
|
-
);
|
|
76
|
-
withMeta(remarkImageBlockPlugin.plugin, {
|
|
77
|
-
displayName: "Remark<remarkImageBlock>",
|
|
78
|
-
group: "ImageBlock"
|
|
79
|
-
});
|
|
80
|
-
withMeta(remarkImageBlockPlugin.options, {
|
|
81
|
-
displayName: "RemarkConfig<remarkImageBlock>",
|
|
82
|
-
group: "ImageBlock"
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
var __defProp$1 = Object.defineProperty;
|
|
86
|
-
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
87
|
-
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
88
|
-
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
89
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
90
|
-
var __spreadValues$1 = (a, b) => {
|
|
55
|
+
var __defProp$2 = Object.defineProperty;
|
|
56
|
+
var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
|
|
57
|
+
var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
|
|
58
|
+
var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
|
|
59
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
60
|
+
var __spreadValues$2 = (a, b) => {
|
|
91
61
|
for (var prop in b || (b = {}))
|
|
92
|
-
if (__hasOwnProp$
|
|
93
|
-
__defNormalProp$
|
|
94
|
-
if (__getOwnPropSymbols$
|
|
95
|
-
for (var prop of __getOwnPropSymbols$
|
|
96
|
-
if (__propIsEnum$
|
|
97
|
-
__defNormalProp$
|
|
62
|
+
if (__hasOwnProp$2.call(b, prop))
|
|
63
|
+
__defNormalProp$2(a, prop, b[prop]);
|
|
64
|
+
if (__getOwnPropSymbols$2)
|
|
65
|
+
for (var prop of __getOwnPropSymbols$2(b)) {
|
|
66
|
+
if (__propIsEnum$2.call(b, prop))
|
|
67
|
+
__defNormalProp$2(a, prop, b[prop]);
|
|
98
68
|
}
|
|
99
69
|
return a;
|
|
100
70
|
};
|
|
@@ -112,7 +82,8 @@ const imageBlockSchema = $nodeSchema("image-block", () => {
|
|
|
112
82
|
attrs: {
|
|
113
83
|
src: { default: "", validate: "string" },
|
|
114
84
|
caption: { default: "", validate: "string" },
|
|
115
|
-
ratio: { default: 1, validate: "number" }
|
|
85
|
+
ratio: { default: 1, validate: "number" },
|
|
86
|
+
align: { default: null }
|
|
116
87
|
},
|
|
117
88
|
parseDOM: [
|
|
118
89
|
{
|
|
@@ -123,12 +94,25 @@ const imageBlockSchema = $nodeSchema("image-block", () => {
|
|
|
123
94
|
return {
|
|
124
95
|
src: dom.getAttribute("src") || "",
|
|
125
96
|
caption: dom.getAttribute("caption") || "",
|
|
126
|
-
ratio: Number((_a = dom.getAttribute("ratio")) != null ? _a : 1)
|
|
97
|
+
ratio: Number((_a = dom.getAttribute("ratio")) != null ? _a : 1),
|
|
98
|
+
align: dom.getAttribute("align") || null
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
tag: "img[src]",
|
|
104
|
+
getAttrs: (dom) => {
|
|
105
|
+
if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom);
|
|
106
|
+
if (dom.getAttribute("data-type") === IMAGE_DATA_TYPE) return false;
|
|
107
|
+
return {
|
|
108
|
+
src: dom.getAttribute("src") || "",
|
|
109
|
+
caption: dom.getAttribute("alt") || dom.getAttribute("title") || "",
|
|
110
|
+
ratio: 1
|
|
127
111
|
};
|
|
128
112
|
}
|
|
129
113
|
}
|
|
130
114
|
],
|
|
131
|
-
toDOM: (node) => ["img", __spreadValues$
|
|
115
|
+
toDOM: (node) => ["img", __spreadValues$2({ "data-type": IMAGE_DATA_TYPE }, node.attrs)],
|
|
132
116
|
parseMarkdown: {
|
|
133
117
|
match: ({ type }) => type === "image-block",
|
|
134
118
|
runner: (state, node, type) => {
|
|
@@ -162,6 +146,253 @@ withMeta(imageBlockSchema.node, {
|
|
|
162
146
|
group: "ImageBlock"
|
|
163
147
|
});
|
|
164
148
|
|
|
149
|
+
var __defProp$1 = Object.defineProperty;
|
|
150
|
+
var __defProps = Object.defineProperties;
|
|
151
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
152
|
+
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
153
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
154
|
+
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
155
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
156
|
+
var __spreadValues$1 = (a, b) => {
|
|
157
|
+
for (var prop in b || (b = {}))
|
|
158
|
+
if (__hasOwnProp$1.call(b, prop))
|
|
159
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
160
|
+
if (__getOwnPropSymbols$1)
|
|
161
|
+
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
162
|
+
if (__propIsEnum$1.call(b, prop))
|
|
163
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
164
|
+
}
|
|
165
|
+
return a;
|
|
166
|
+
};
|
|
167
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
168
|
+
var __async = (__this, __arguments, generator) => {
|
|
169
|
+
return new Promise((resolve, reject) => {
|
|
170
|
+
var fulfilled = (value) => {
|
|
171
|
+
try {
|
|
172
|
+
step(generator.next(value));
|
|
173
|
+
} catch (e) {
|
|
174
|
+
reject(e);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
var rejected = (value) => {
|
|
178
|
+
try {
|
|
179
|
+
step(generator.throw(value));
|
|
180
|
+
} catch (e) {
|
|
181
|
+
reject(e);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
185
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
const imageBlockConvertPlugin = $prose((ctx) => {
|
|
189
|
+
const imageType = imageSchema.type(ctx);
|
|
190
|
+
const imageBlockType = imageBlockSchema.type(ctx);
|
|
191
|
+
const paragraphType = paragraphSchema.type(ctx);
|
|
192
|
+
const pluginKey = new PluginKey("MILKDOWN_IMAGE_BLOCK_CONVERT");
|
|
193
|
+
let uploading = false;
|
|
194
|
+
return new Plugin({
|
|
195
|
+
key: pluginKey,
|
|
196
|
+
appendTransaction(transactions, _oldState, newState) {
|
|
197
|
+
if (!transactions.some((tr2) => tr2.docChanged)) return null;
|
|
198
|
+
const replacements = [];
|
|
199
|
+
newState.doc.descendants((node, pos) => {
|
|
200
|
+
if (node.type === imageType) ;
|
|
201
|
+
});
|
|
202
|
+
newState.doc.descendants((node, pos) => {
|
|
203
|
+
var _a;
|
|
204
|
+
if (node.type !== paragraphType) return;
|
|
205
|
+
const images = [];
|
|
206
|
+
let hasOtherContent = false;
|
|
207
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
208
|
+
const child = node.child(i);
|
|
209
|
+
if (child.type === imageType) {
|
|
210
|
+
images.push(child);
|
|
211
|
+
} else if (child.type.name === "hardbreak") {
|
|
212
|
+
continue;
|
|
213
|
+
} else if (child.isText && ((_a = child.text) == null ? void 0 : _a.trim()) === "") {
|
|
214
|
+
continue;
|
|
215
|
+
} else {
|
|
216
|
+
hasOtherContent = true;
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (hasOtherContent || images.length === 0) return;
|
|
221
|
+
const blocks = images.map(
|
|
222
|
+
(img) => imageBlockType.create({
|
|
223
|
+
src: img.attrs.src,
|
|
224
|
+
caption: img.attrs.alt || img.attrs.title || "",
|
|
225
|
+
ratio: 1
|
|
226
|
+
})
|
|
227
|
+
).filter(Boolean);
|
|
228
|
+
if (blocks.length > 0) {
|
|
229
|
+
replacements.push({ from: pos, to: pos + node.nodeSize, blocks });
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
if (replacements.length === 0) return null;
|
|
233
|
+
const { tr } = newState;
|
|
234
|
+
for (let i = replacements.length - 1; i >= 0; i--) {
|
|
235
|
+
const r = replacements[i];
|
|
236
|
+
tr.replaceWith(r.from, r.to, r.blocks);
|
|
237
|
+
}
|
|
238
|
+
return tr;
|
|
239
|
+
},
|
|
240
|
+
view() {
|
|
241
|
+
return {
|
|
242
|
+
update(view) {
|
|
243
|
+
if (uploading) return;
|
|
244
|
+
const config = ctx.get(imageBlockConfig.key);
|
|
245
|
+
const imagesToUpload = [];
|
|
246
|
+
view.state.doc.descendants((node, pos) => {
|
|
247
|
+
if (node.type.name !== "image-block") return;
|
|
248
|
+
const src = node.attrs.src;
|
|
249
|
+
if (!src || src.startsWith("data:") || src.startsWith("blob:"))
|
|
250
|
+
return;
|
|
251
|
+
if (!/^https?:\/\//i.test(src)) return;
|
|
252
|
+
imagesToUpload.push({ pos, src });
|
|
253
|
+
});
|
|
254
|
+
if (imagesToUpload.length === 0) return;
|
|
255
|
+
uploading = true;
|
|
256
|
+
void Promise.allSettled(
|
|
257
|
+
imagesToUpload.map((_0) => __async(null, [_0], function* ({ pos, src }) {
|
|
258
|
+
const resp = yield fetch(src);
|
|
259
|
+
const blob = yield resp.blob();
|
|
260
|
+
const ext = blob.type.split("/")[1] || "png";
|
|
261
|
+
const file = new File([blob], `pasted-image.${ext}`, {
|
|
262
|
+
type: blob.type
|
|
263
|
+
});
|
|
264
|
+
const uploadedUrl = yield config.onUpload(file);
|
|
265
|
+
const $pos = view.state.doc.resolve(pos);
|
|
266
|
+
const nodeAtPos = $pos.nodeAfter;
|
|
267
|
+
if (nodeAtPos && nodeAtPos.type.name === "image-block" && nodeAtPos.attrs.src === src) {
|
|
268
|
+
view.dispatch(
|
|
269
|
+
view.state.tr.setNodeMarkup(pos, void 0, __spreadProps(__spreadValues$1({}, nodeAtPos.attrs), {
|
|
270
|
+
src: uploadedUrl
|
|
271
|
+
})).setMeta(pluginKey, { uploaded: true })
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
}))
|
|
275
|
+
).finally(() => {
|
|
276
|
+
uploading = false;
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
withMeta(imageBlockConvertPlugin, {
|
|
284
|
+
displayName: "Prose<image-block-convert>",
|
|
285
|
+
group: "ImageBlock"
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
function toImageBlock(imageNode, imageBlockType) {
|
|
289
|
+
return imageBlockType.create({
|
|
290
|
+
src: imageNode.attrs.src,
|
|
291
|
+
caption: imageNode.attrs.alt || imageNode.attrs.title || "",
|
|
292
|
+
ratio: 1
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
const imageBlockPasteRule = $pasteRule((ctx) => ({
|
|
296
|
+
priority: 90,
|
|
297
|
+
run: (slice, _view, isPlainText) => {
|
|
298
|
+
if (isPlainText) return slice;
|
|
299
|
+
const paragraphType = paragraphSchema.type(ctx);
|
|
300
|
+
const imageType = imageSchema.type(ctx);
|
|
301
|
+
const imageBlockType = imageBlockSchema.type(ctx);
|
|
302
|
+
function convertFragment(fragment2) {
|
|
303
|
+
const nodes = [];
|
|
304
|
+
let changed = false;
|
|
305
|
+
fragment2.forEach((node) => {
|
|
306
|
+
if (node.type === imageType) {
|
|
307
|
+
const imageBlock = toImageBlock(node, imageBlockType);
|
|
308
|
+
if (imageBlock) {
|
|
309
|
+
nodes.push(imageBlock);
|
|
310
|
+
changed = true;
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (node.type === paragraphType) {
|
|
315
|
+
let hasImage = false;
|
|
316
|
+
node.content.forEach((child) => {
|
|
317
|
+
if (child.type === imageType) hasImage = true;
|
|
318
|
+
});
|
|
319
|
+
if (hasImage) {
|
|
320
|
+
let currentParaNodes = [];
|
|
321
|
+
let isFirstInsideParent = nodes.length === 0;
|
|
322
|
+
node.content.forEach((child) => {
|
|
323
|
+
if (child.type === imageType) {
|
|
324
|
+
if (currentParaNodes.length > 0 || isFirstInsideParent) {
|
|
325
|
+
nodes.push(node.copy(Fragment$1.from(currentParaNodes)));
|
|
326
|
+
currentParaNodes = [];
|
|
327
|
+
}
|
|
328
|
+
const imageBlock = toImageBlock(child, imageBlockType);
|
|
329
|
+
if (imageBlock) {
|
|
330
|
+
nodes.push(imageBlock);
|
|
331
|
+
}
|
|
332
|
+
isFirstInsideParent = false;
|
|
333
|
+
} else {
|
|
334
|
+
currentParaNodes.push(child);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
nodes.push(node.copy(Fragment$1.from(currentParaNodes)));
|
|
338
|
+
changed = true;
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (node.content.size > 0) {
|
|
343
|
+
const fixedContent = convertFragment(node.content);
|
|
344
|
+
if (fixedContent !== node.content) {
|
|
345
|
+
changed = true;
|
|
346
|
+
nodes.push(node.copy(fixedContent));
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
nodes.push(node);
|
|
351
|
+
});
|
|
352
|
+
return changed ? Fragment$1.from(nodes) : fragment2;
|
|
353
|
+
}
|
|
354
|
+
const fragment = convertFragment(slice.content);
|
|
355
|
+
return new Slice(fragment, slice.openStart, slice.openEnd);
|
|
356
|
+
}
|
|
357
|
+
}));
|
|
358
|
+
withMeta(imageBlockPasteRule, {
|
|
359
|
+
displayName: "PasteRule<image-block>",
|
|
360
|
+
group: "ImageBlock"
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
function visitImage(ast) {
|
|
364
|
+
return visit(
|
|
365
|
+
ast,
|
|
366
|
+
"paragraph",
|
|
367
|
+
(node, index, parent) => {
|
|
368
|
+
var _a, _b;
|
|
369
|
+
if (((_a = node.children) == null ? void 0 : _a.length) !== 1) return;
|
|
370
|
+
const firstChild = (_b = node.children) == null ? void 0 : _b[0];
|
|
371
|
+
if (!firstChild || firstChild.type !== "image") return;
|
|
372
|
+
const { url, alt, title } = firstChild;
|
|
373
|
+
const newNode = {
|
|
374
|
+
type: "image-block",
|
|
375
|
+
url,
|
|
376
|
+
alt,
|
|
377
|
+
title
|
|
378
|
+
};
|
|
379
|
+
parent.children.splice(index, 1, newNode);
|
|
380
|
+
}
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
const remarkImageBlockPlugin = $remark(
|
|
384
|
+
"remark-image-block",
|
|
385
|
+
() => () => visitImage
|
|
386
|
+
);
|
|
387
|
+
withMeta(remarkImageBlockPlugin.plugin, {
|
|
388
|
+
displayName: "Remark<remarkImageBlock>",
|
|
389
|
+
group: "ImageBlock"
|
|
390
|
+
});
|
|
391
|
+
withMeta(remarkImageBlockPlugin.options, {
|
|
392
|
+
displayName: "RemarkConfig<remarkImageBlock>",
|
|
393
|
+
group: "ImageBlock"
|
|
394
|
+
});
|
|
395
|
+
|
|
165
396
|
function keepAlive(..._args) {
|
|
166
397
|
}
|
|
167
398
|
|
|
@@ -260,15 +491,28 @@ const ImageInput = defineComponent({
|
|
|
260
491
|
hidePlaceholder.value = value.length !== 0;
|
|
261
492
|
currentLink.value = value;
|
|
262
493
|
};
|
|
494
|
+
const isValidUrl = (url) => {
|
|
495
|
+
if (!url) return false;
|
|
496
|
+
const trimmedUrl = url.trim();
|
|
497
|
+
return /^(https?:\/\/|\/|\.\.?\/|data:image\/|blob:|[a-zA-Z0-9-]+\.[a-zA-Z]+)/i.test(trimmedUrl);
|
|
498
|
+
};
|
|
263
499
|
const onKeydown = (e) => {
|
|
264
|
-
var _a2, _b2;
|
|
500
|
+
var _a2, _b2, _c;
|
|
265
501
|
if (e.key === "Enter") {
|
|
266
|
-
|
|
502
|
+
const val = (_c = (_b2 = (_a2 = linkInputRef.value) == null ? void 0 : _a2.value) == null ? void 0 : _b2.trim()) != null ? _c : "";
|
|
503
|
+
e.preventDefault();
|
|
504
|
+
e.stopPropagation();
|
|
505
|
+
if (isValidUrl(val)) {
|
|
506
|
+
setLink(val);
|
|
507
|
+
}
|
|
267
508
|
}
|
|
268
509
|
};
|
|
269
510
|
const onConfirmLinkInput = () => {
|
|
270
|
-
var _a2, _b2;
|
|
271
|
-
|
|
511
|
+
var _a2, _b2, _c;
|
|
512
|
+
const val = (_c = (_b2 = (_a2 = linkInputRef.value) == null ? void 0 : _a2.value) == null ? void 0 : _b2.trim()) != null ? _c : "";
|
|
513
|
+
if (isValidUrl(val)) {
|
|
514
|
+
setLink(val);
|
|
515
|
+
}
|
|
272
516
|
};
|
|
273
517
|
const onUploadFile = (e) => {
|
|
274
518
|
var _a2;
|
|
@@ -314,7 +558,7 @@ const ImageInput = defineComponent({
|
|
|
314
558
|
), /* @__PURE__ */ h("label", { class: "uploader", for: uuid.value }, /* @__PURE__ */ h(Icon, { icon: uploadButton })), /* @__PURE__ */ h("span", { class: "text", onClick: () => {
|
|
315
559
|
var _a2;
|
|
316
560
|
return (_a2 = linkInputRef.value) == null ? void 0 : _a2.focus();
|
|
317
|
-
} }, uploadPlaceholderText))), currentLink.value && /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h("div", { class: "image-preview" }, /* @__PURE__ */ h(
|
|
561
|
+
} }, uploadPlaceholderText))), currentLink.value && /* @__PURE__ */ h(Fragment, null, isValidUrl(currentLink.value) && /* @__PURE__ */ h("div", { class: "image-preview" }, /* @__PURE__ */ h(
|
|
318
562
|
"img",
|
|
319
563
|
{
|
|
320
564
|
src: currentLink.value,
|
|
@@ -322,12 +566,20 @@ const ImageInput = defineComponent({
|
|
|
322
566
|
onError: (e) => Promise.resolve(onImageLoadError == null ? void 0 : onImageLoadError(e)).catch(() => {
|
|
323
567
|
})
|
|
324
568
|
}
|
|
325
|
-
)), /* @__PURE__ */ h(
|
|
569
|
+
)), /* @__PURE__ */ h(
|
|
570
|
+
"div",
|
|
571
|
+
{
|
|
572
|
+
class: clsx("confirm", !isValidUrl(currentLink.value) && "disabled"),
|
|
573
|
+
onClick: () => onConfirmLinkInput(),
|
|
574
|
+
style: !isValidUrl(currentLink.value) ? { opacity: 0.5, cursor: "not-allowed" } : void 0
|
|
575
|
+
},
|
|
576
|
+
/* @__PURE__ */ h(Icon, { icon: confirmButton })
|
|
577
|
+
)));
|
|
326
578
|
};
|
|
327
579
|
}
|
|
328
580
|
});
|
|
329
581
|
|
|
330
|
-
keepAlive(h, Fragment$
|
|
582
|
+
keepAlive(h, Fragment$2);
|
|
331
583
|
const ImageViewer = defineComponent({
|
|
332
584
|
props: {
|
|
333
585
|
src: {
|
|
@@ -342,6 +594,10 @@ const ImageViewer = defineComponent({
|
|
|
342
594
|
type: Object,
|
|
343
595
|
required: true
|
|
344
596
|
},
|
|
597
|
+
align: {
|
|
598
|
+
type: Object,
|
|
599
|
+
required: true
|
|
600
|
+
},
|
|
345
601
|
selected: {
|
|
346
602
|
type: Object,
|
|
347
603
|
required: true
|
|
@@ -465,7 +721,7 @@ const ImageViewer = defineComponent({
|
|
|
465
721
|
window.addEventListener("pointerup", onResizeHandlePointerUp);
|
|
466
722
|
};
|
|
467
723
|
return () => {
|
|
468
|
-
return /* @__PURE__ */ h(Fragment$
|
|
724
|
+
return /* @__PURE__ */ h(Fragment$2, null, /* @__PURE__ */ h("div", { class: "image-wrapper" }, /* @__PURE__ */ h("div", { class: "operation" }, /* @__PURE__ */ h("div", { class: "operation-item", onPointerdown: onToggleCaption }, /* @__PURE__ */ h(Icon, { icon: config.captionIcon }))), /* @__PURE__ */ h(
|
|
469
725
|
"img",
|
|
470
726
|
{
|
|
471
727
|
ref: imageRef,
|
|
@@ -538,7 +794,7 @@ var __spreadValues = (a, b) => {
|
|
|
538
794
|
}
|
|
539
795
|
return a;
|
|
540
796
|
};
|
|
541
|
-
keepAlive(h, Fragment$
|
|
797
|
+
keepAlive(h, Fragment$2);
|
|
542
798
|
const MilkdownImageBlock = defineComponent({
|
|
543
799
|
props: {
|
|
544
800
|
src: {
|
|
@@ -553,6 +809,10 @@ const MilkdownImageBlock = defineComponent({
|
|
|
553
809
|
type: Object,
|
|
554
810
|
required: true
|
|
555
811
|
},
|
|
812
|
+
align: {
|
|
813
|
+
type: Object,
|
|
814
|
+
required: true
|
|
815
|
+
},
|
|
556
816
|
selected: {
|
|
557
817
|
type: Object,
|
|
558
818
|
required: true
|
|
@@ -603,6 +863,7 @@ const imageBlockView = $view(
|
|
|
603
863
|
const src = ref(initialNode.attrs.src);
|
|
604
864
|
const caption = ref(initialNode.attrs.caption);
|
|
605
865
|
const ratio = ref(initialNode.attrs.ratio);
|
|
866
|
+
const align = ref(initialNode.attrs.align);
|
|
606
867
|
const selected = ref(false);
|
|
607
868
|
const readonly = ref(!view.editable);
|
|
608
869
|
const setAttr = (attr, value) => {
|
|
@@ -622,6 +883,7 @@ const imageBlockView = $view(
|
|
|
622
883
|
src,
|
|
623
884
|
caption,
|
|
624
885
|
ratio,
|
|
886
|
+
align,
|
|
625
887
|
selected,
|
|
626
888
|
readonly,
|
|
627
889
|
setAttr,
|
|
@@ -629,6 +891,7 @@ const imageBlockView = $view(
|
|
|
629
891
|
});
|
|
630
892
|
const dom = document.createElement("div");
|
|
631
893
|
dom.className = "milkdown-image-block";
|
|
894
|
+
dom.dataset.align = initialNode.attrs.align || "center";
|
|
632
895
|
const disposeSelectedWatcher = watchEffect(() => {
|
|
633
896
|
const isSelected = selected.value;
|
|
634
897
|
if (isSelected) {
|
|
@@ -637,6 +900,9 @@ const imageBlockView = $view(
|
|
|
637
900
|
dom.classList.remove("selected");
|
|
638
901
|
}
|
|
639
902
|
});
|
|
903
|
+
const disposeAlignWatcher = watchEffect(() => {
|
|
904
|
+
dom.dataset.align = align.value || "center";
|
|
905
|
+
});
|
|
640
906
|
const proxyDomURL = config.proxyDomURL;
|
|
641
907
|
const bindAttrs = (node) => {
|
|
642
908
|
if (!proxyDomURL) {
|
|
@@ -653,6 +919,7 @@ const imageBlockView = $view(
|
|
|
653
919
|
}
|
|
654
920
|
ratio.value = node.attrs.ratio;
|
|
655
921
|
caption.value = node.attrs.caption;
|
|
922
|
+
align.value = node.attrs.align;
|
|
656
923
|
readonly.value = !view.editable;
|
|
657
924
|
};
|
|
658
925
|
bindAttrs(initialNode);
|
|
@@ -676,6 +943,7 @@ const imageBlockView = $view(
|
|
|
676
943
|
},
|
|
677
944
|
destroy: () => {
|
|
678
945
|
disposeSelectedWatcher();
|
|
946
|
+
disposeAlignWatcher();
|
|
679
947
|
app.unmount();
|
|
680
948
|
dom.remove();
|
|
681
949
|
}
|
|
@@ -692,8 +960,10 @@ const imageBlockComponent = [
|
|
|
692
960
|
remarkImageBlockPlugin,
|
|
693
961
|
imageBlockSchema,
|
|
694
962
|
imageBlockView,
|
|
695
|
-
imageBlockConfig
|
|
963
|
+
imageBlockConfig,
|
|
964
|
+
imageBlockPasteRule,
|
|
965
|
+
imageBlockConvertPlugin
|
|
696
966
|
].flat();
|
|
697
967
|
|
|
698
|
-
export { IMAGE_DATA_TYPE, defaultImageBlockConfig, imageBlockComponent, imageBlockConfig, imageBlockSchema, imageBlockView, remarkImageBlockPlugin };
|
|
968
|
+
export { IMAGE_DATA_TYPE, defaultImageBlockConfig, imageBlockComponent, imageBlockConfig, imageBlockConvertPlugin, imageBlockPasteRule, imageBlockSchema, imageBlockView, remarkImageBlockPlugin };
|
|
699
969
|
//# sourceMappingURL=index.js.map
|