@jvs-milkdown/components 1.2.0 → 1.2.1

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.
Files changed (139) hide show
  1. package/lib/code-block/index.js +37 -2
  2. package/lib/code-block/index.js.map +1 -1
  3. package/lib/image-block/index.js +628 -107
  4. package/lib/image-block/index.js.map +1 -1
  5. package/lib/table-block/index.js +67 -44
  6. package/lib/table-block/index.js.map +1 -1
  7. package/lib/tsconfig.tsbuildinfo +1 -1
  8. package/package.json +10 -10
  9. package/src/code-block/config.ts +4 -0
  10. package/src/code-block/view/components/code-block.tsx +24 -0
  11. package/src/code-block/view/node-view.ts +15 -0
  12. package/src/image-block/config.ts +10 -0
  13. package/src/image-block/schema.ts +16 -0
  14. package/src/image-block/view/components/__tests__/image-viewer.onImageLoadError.spec.tsx +14 -0
  15. package/src/image-block/view/components/image-block.tsx +40 -0
  16. package/src/image-block/view/components/image-viewer.tsx +548 -65
  17. package/src/image-block/view/index.ts +42 -0
  18. package/src/table-block/view/component.tsx +31 -14
  19. package/src/table-block/view/operation.ts +49 -30
  20. package/lib/__internal__/components/icon.d.ts +0 -24
  21. package/lib/__internal__/components/icon.d.ts.map +0 -1
  22. package/lib/__internal__/components/image-input.d.ts +0 -17
  23. package/lib/__internal__/components/image-input.d.ts.map +0 -1
  24. package/lib/__internal__/keep-alive.d.ts +0 -2
  25. package/lib/__internal__/keep-alive.d.ts.map +0 -1
  26. package/lib/__internal__/meta.d.ts +0 -3
  27. package/lib/__internal__/meta.d.ts.map +0 -1
  28. package/lib/__tests__/setup.d.ts +0 -2
  29. package/lib/__tests__/setup.d.ts.map +0 -1
  30. package/lib/code-block/config.d.ts +0 -23
  31. package/lib/code-block/config.d.ts.map +0 -1
  32. package/lib/code-block/index.d.ts +0 -5
  33. package/lib/code-block/index.d.ts.map +0 -1
  34. package/lib/code-block/view/components/code-block.d.ts +0 -16
  35. package/lib/code-block/view/components/code-block.d.ts.map +0 -1
  36. package/lib/code-block/view/components/copy-button.d.ts +0 -9
  37. package/lib/code-block/view/components/copy-button.d.ts.map +0 -1
  38. package/lib/code-block/view/components/language-picker.d.ts +0 -5
  39. package/lib/code-block/view/components/language-picker.d.ts.map +0 -1
  40. package/lib/code-block/view/components/preview-panel.d.ts +0 -9
  41. package/lib/code-block/view/components/preview-panel.d.ts.map +0 -1
  42. package/lib/code-block/view/index.d.ts +0 -3
  43. package/lib/code-block/view/index.d.ts.map +0 -1
  44. package/lib/code-block/view/loader.d.ts +0 -13
  45. package/lib/code-block/view/loader.d.ts.map +0 -1
  46. package/lib/code-block/view/node-view.d.ts +0 -40
  47. package/lib/code-block/view/node-view.d.ts.map +0 -1
  48. package/lib/image-block/config.d.ts +0 -16
  49. package/lib/image-block/config.d.ts.map +0 -1
  50. package/lib/image-block/convert-plugin.d.ts +0 -2
  51. package/lib/image-block/convert-plugin.d.ts.map +0 -1
  52. package/lib/image-block/index.d.ts +0 -9
  53. package/lib/image-block/index.d.ts.map +0 -1
  54. package/lib/image-block/paste-rule.d.ts +0 -2
  55. package/lib/image-block/paste-rule.d.ts.map +0 -1
  56. package/lib/image-block/remark-plugin.d.ts +0 -2
  57. package/lib/image-block/remark-plugin.d.ts.map +0 -1
  58. package/lib/image-block/schema.d.ts +0 -3
  59. package/lib/image-block/schema.d.ts.map +0 -1
  60. package/lib/image-block/view/components/__tests__/image-viewer.onImageLoadError.spec.d.ts +0 -2
  61. package/lib/image-block/view/components/__tests__/image-viewer.onImageLoadError.spec.d.ts.map +0 -1
  62. package/lib/image-block/view/components/image-block.d.ts +0 -19
  63. package/lib/image-block/view/components/image-block.d.ts.map +0 -1
  64. package/lib/image-block/view/components/image-viewer.d.ts +0 -3
  65. package/lib/image-block/view/components/image-viewer.d.ts.map +0 -1
  66. package/lib/image-block/view/index.d.ts +0 -3
  67. package/lib/image-block/view/index.d.ts.map +0 -1
  68. package/lib/image-inline/components/image-inline.d.ts +0 -18
  69. package/lib/image-inline/components/image-inline.d.ts.map +0 -1
  70. package/lib/image-inline/config.d.ts +0 -11
  71. package/lib/image-inline/config.d.ts.map +0 -1
  72. package/lib/image-inline/index.d.ts +0 -5
  73. package/lib/image-inline/index.d.ts.map +0 -1
  74. package/lib/image-inline/view.d.ts +0 -3
  75. package/lib/image-inline/view.d.ts.map +0 -1
  76. package/lib/index.d.ts +0 -2
  77. package/lib/index.d.ts.map +0 -1
  78. package/lib/link-tooltip/command.d.ts +0 -2
  79. package/lib/link-tooltip/command.d.ts.map +0 -1
  80. package/lib/link-tooltip/configure.d.ts +0 -3
  81. package/lib/link-tooltip/configure.d.ts.map +0 -1
  82. package/lib/link-tooltip/edit/component.d.ts +0 -11
  83. package/lib/link-tooltip/edit/component.d.ts.map +0 -1
  84. package/lib/link-tooltip/edit/edit-configure.d.ts +0 -3
  85. package/lib/link-tooltip/edit/edit-configure.d.ts.map +0 -1
  86. package/lib/link-tooltip/edit/edit-view.d.ts +0 -15
  87. package/lib/link-tooltip/edit/edit-view.d.ts.map +0 -1
  88. package/lib/link-tooltip/index.d.ts +0 -7
  89. package/lib/link-tooltip/index.d.ts.map +0 -1
  90. package/lib/link-tooltip/preview/component.d.ts +0 -11
  91. package/lib/link-tooltip/preview/component.d.ts.map +0 -1
  92. package/lib/link-tooltip/preview/preview-configure.d.ts +0 -3
  93. package/lib/link-tooltip/preview/preview-configure.d.ts.map +0 -1
  94. package/lib/link-tooltip/preview/preview-view.d.ts +0 -14
  95. package/lib/link-tooltip/preview/preview-view.d.ts.map +0 -1
  96. package/lib/link-tooltip/slices.d.ts +0 -34
  97. package/lib/link-tooltip/slices.d.ts.map +0 -1
  98. package/lib/link-tooltip/tooltips.d.ts +0 -3
  99. package/lib/link-tooltip/tooltips.d.ts.map +0 -1
  100. package/lib/link-tooltip/utils.d.ts +0 -14
  101. package/lib/link-tooltip/utils.d.ts.map +0 -1
  102. package/lib/list-item-block/component.d.ts +0 -19
  103. package/lib/list-item-block/component.d.ts.map +0 -1
  104. package/lib/list-item-block/config.d.ts +0 -13
  105. package/lib/list-item-block/config.d.ts.map +0 -1
  106. package/lib/list-item-block/index.d.ts +0 -6
  107. package/lib/list-item-block/index.d.ts.map +0 -1
  108. package/lib/list-item-block/view.d.ts +0 -3
  109. package/lib/list-item-block/view.d.ts.map +0 -1
  110. package/lib/table-block/config.d.ts +0 -8
  111. package/lib/table-block/config.d.ts.map +0 -1
  112. package/lib/table-block/dnd/calc-drag-over.d.ts +0 -3
  113. package/lib/table-block/dnd/calc-drag-over.d.ts.map +0 -1
  114. package/lib/table-block/dnd/create-drag-handler.d.ts +0 -5
  115. package/lib/table-block/dnd/create-drag-handler.d.ts.map +0 -1
  116. package/lib/table-block/dnd/drag-over-handler.d.ts +0 -3
  117. package/lib/table-block/dnd/drag-over-handler.d.ts.map +0 -1
  118. package/lib/table-block/dnd/prepare-dnd-context.d.ts +0 -3
  119. package/lib/table-block/dnd/prepare-dnd-context.d.ts.map +0 -1
  120. package/lib/table-block/dnd/preview.d.ts +0 -3
  121. package/lib/table-block/dnd/preview.d.ts.map +0 -1
  122. package/lib/table-block/index.d.ts +0 -5
  123. package/lib/table-block/index.d.ts.map +0 -1
  124. package/lib/table-block/view/component.d.ts +0 -16
  125. package/lib/table-block/view/component.d.ts.map +0 -1
  126. package/lib/table-block/view/drag.d.ts +0 -10
  127. package/lib/table-block/view/drag.d.ts.map +0 -1
  128. package/lib/table-block/view/index.d.ts +0 -2
  129. package/lib/table-block/view/index.d.ts.map +0 -1
  130. package/lib/table-block/view/operation.d.ts +0 -13
  131. package/lib/table-block/view/operation.d.ts.map +0 -1
  132. package/lib/table-block/view/pointer.d.ts +0 -7
  133. package/lib/table-block/view/pointer.d.ts.map +0 -1
  134. package/lib/table-block/view/types.d.ts +0 -28
  135. package/lib/table-block/view/types.d.ts.map +0 -1
  136. package/lib/table-block/view/utils.d.ts +0 -12
  137. package/lib/table-block/view/utils.d.ts.map +0 -1
  138. package/lib/table-block/view/view.d.ts +0 -22
  139. package/lib/table-block/view/view.d.ts.map +0 -1
@@ -9,25 +9,25 @@ import { h, defineComponent, ref, Fragment as Fragment$2, createApp, watchEffect
9
9
  import clsx from 'clsx';
10
10
  import { customAlphabet } from 'nanoid';
11
11
 
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) => {
12
+ var __defProp$4 = Object.defineProperty;
13
+ var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
14
+ var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
15
+ var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
16
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
17
+ var __spreadValues$4 = (a, b) => {
18
18
  for (var prop in b || (b = {}))
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]);
19
+ if (__hasOwnProp$4.call(b, prop))
20
+ __defNormalProp$4(a, prop, b[prop]);
21
+ if (__getOwnPropSymbols$4)
22
+ for (var prop of __getOwnPropSymbols$4(b)) {
23
+ if (__propIsEnum$4.call(b, prop))
24
+ __defNormalProp$4(a, prop, b[prop]);
25
25
  }
26
26
  return a;
27
27
  };
28
28
  function withMeta(plugin, meta) {
29
29
  Object.assign(plugin, {
30
- meta: __spreadValues$3({
30
+ meta: __spreadValues$4({
31
31
  package: "@jvs-milkdown/components"
32
32
  }, meta)
33
33
  });
@@ -37,6 +37,11 @@ function withMeta(plugin, meta) {
37
37
  const defaultImageBlockConfig = {
38
38
  imageIcon: "\u{1F30C}",
39
39
  captionIcon: "\u{1F4AC}",
40
+ cropIcon: "\u2702\uFE0F",
41
+ borderIcon: "\u{1F532}",
42
+ confirmIcon: "\u2713",
43
+ cancelIcon: "\u2715",
44
+ resetCropIcon: "\u21A9",
40
45
  uploadButton: "Upload file",
41
46
  confirmButton: "Confirm \u23CE",
42
47
  uploadPlaceholderText: "or paste the image link ...",
@@ -52,19 +57,19 @@ withMeta(imageBlockConfig, {
52
57
  group: "ImageBlock"
53
58
  });
54
59
 
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) => {
60
+ var __defProp$3 = Object.defineProperty;
61
+ var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
62
+ var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
63
+ var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
64
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
65
+ var __spreadValues$3 = (a, b) => {
61
66
  for (var prop in b || (b = {}))
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]);
67
+ if (__hasOwnProp$3.call(b, prop))
68
+ __defNormalProp$3(a, prop, b[prop]);
69
+ if (__getOwnPropSymbols$3)
70
+ for (var prop of __getOwnPropSymbols$3(b)) {
71
+ if (__propIsEnum$3.call(b, prop))
72
+ __defNormalProp$3(a, prop, b[prop]);
68
73
  }
69
74
  return a;
70
75
  };
@@ -83,19 +88,35 @@ const imageBlockSchema = $nodeSchema("image-block", () => {
83
88
  src: { default: "", validate: "string" },
84
89
  caption: { default: "", validate: "string" },
85
90
  ratio: { default: 1, validate: "number" },
86
- align: { default: null }
91
+ align: { default: null },
92
+ cropRatio: { default: "free", validate: "string" },
93
+ cropTop: { default: 0, validate: "number" },
94
+ cropLeft: { default: 0, validate: "number" },
95
+ cropWidth: { default: 1, validate: "number" },
96
+ cropHeight: { default: 1, validate: "number" },
97
+ borderWidth: { default: 0, validate: "number" },
98
+ borderColor: { default: "#000000", validate: "string" },
99
+ borderStyle: { default: "none", validate: "string" }
87
100
  },
88
101
  parseDOM: [
89
102
  {
90
103
  tag: `img[data-type="${IMAGE_DATA_TYPE}"]`,
91
104
  getAttrs: (dom) => {
92
- var _a;
105
+ var _a, _b, _c, _d, _e, _f;
93
106
  if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom);
94
107
  return {
95
108
  src: dom.getAttribute("src") || "",
96
109
  caption: dom.getAttribute("caption") || "",
97
110
  ratio: Number((_a = dom.getAttribute("ratio")) != null ? _a : 1),
98
- align: dom.getAttribute("align") || null
111
+ align: dom.getAttribute("align") || null,
112
+ cropRatio: dom.getAttribute("cropRatio") || "free",
113
+ cropTop: Number((_b = dom.getAttribute("cropTop")) != null ? _b : 0),
114
+ cropLeft: Number((_c = dom.getAttribute("cropLeft")) != null ? _c : 0),
115
+ cropWidth: Number((_d = dom.getAttribute("cropWidth")) != null ? _d : 1),
116
+ cropHeight: Number((_e = dom.getAttribute("cropHeight")) != null ? _e : 1),
117
+ borderWidth: Number((_f = dom.getAttribute("borderWidth")) != null ? _f : 0),
118
+ borderColor: dom.getAttribute("borderColor") || "#000000",
119
+ borderStyle: dom.getAttribute("borderStyle") || "none"
99
120
  };
100
121
  }
101
122
  },
@@ -112,7 +133,7 @@ const imageBlockSchema = $nodeSchema("image-block", () => {
112
133
  }
113
134
  }
114
135
  ],
115
- toDOM: (node) => ["img", __spreadValues$2({ "data-type": IMAGE_DATA_TYPE }, node.attrs)],
136
+ toDOM: (node) => ["img", __spreadValues$3({ "data-type": IMAGE_DATA_TYPE }, node.attrs)],
116
137
  parseMarkdown: {
117
138
  match: ({ type }) => type === "image-block",
118
139
  runner: (state, node, type) => {
@@ -146,21 +167,21 @@ withMeta(imageBlockSchema.node, {
146
167
  group: "ImageBlock"
147
168
  });
148
169
 
149
- var __defProp$1 = Object.defineProperty;
170
+ var __defProp$2 = Object.defineProperty;
150
171
  var __defProps = Object.defineProperties;
151
172
  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) => {
173
+ var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
174
+ var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
175
+ var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
176
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
177
+ var __spreadValues$2 = (a, b) => {
157
178
  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]);
179
+ if (__hasOwnProp$2.call(b, prop))
180
+ __defNormalProp$2(a, prop, b[prop]);
181
+ if (__getOwnPropSymbols$2)
182
+ for (var prop of __getOwnPropSymbols$2(b)) {
183
+ if (__propIsEnum$2.call(b, prop))
184
+ __defNormalProp$2(a, prop, b[prop]);
164
185
  }
165
186
  return a;
166
187
  };
@@ -266,7 +287,7 @@ const imageBlockConvertPlugin = $prose((ctx) => {
266
287
  const nodeAtPos = $pos.nodeAfter;
267
288
  if (nodeAtPos && nodeAtPos.type.name === "image-block" && nodeAtPos.attrs.src === src) {
268
289
  view.dispatch(
269
- view.state.tr.setNodeMarkup(pos, void 0, __spreadProps(__spreadValues$1({}, nodeAtPos.attrs), {
290
+ view.state.tr.setNodeMarkup(pos, void 0, __spreadProps(__spreadValues$2({}, nodeAtPos.attrs), {
270
291
  src: uploadedUrl
271
292
  })).setMeta(pluginKey, { uploaded: true })
272
293
  );
@@ -579,52 +600,87 @@ const ImageInput = defineComponent({
579
600
  }
580
601
  });
581
602
 
603
+ var __defProp$1 = Object.defineProperty;
604
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
605
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
606
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
607
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
608
+ var __spreadValues$1 = (a, b) => {
609
+ for (var prop in b || (b = {}))
610
+ if (__hasOwnProp$1.call(b, prop))
611
+ __defNormalProp$1(a, prop, b[prop]);
612
+ if (__getOwnPropSymbols$1)
613
+ for (var prop of __getOwnPropSymbols$1(b)) {
614
+ if (__propIsEnum$1.call(b, prop))
615
+ __defNormalProp$1(a, prop, b[prop]);
616
+ }
617
+ return a;
618
+ };
582
619
  keepAlive(h, Fragment$2);
620
+ const ratioMap = {
621
+ "1:1": 1,
622
+ "4:3": 4 / 3,
623
+ "3:2": 3 / 2,
624
+ "16:9": 16 / 9
625
+ };
583
626
  const ImageViewer = defineComponent({
584
627
  props: {
585
- src: {
586
- type: Object,
587
- required: true
588
- },
589
- caption: {
590
- type: Object,
591
- required: true
592
- },
593
- ratio: {
594
- type: Object,
595
- required: true
596
- },
597
- align: {
598
- type: Object,
599
- required: true
600
- },
601
- selected: {
602
- type: Object,
603
- required: true
604
- },
605
- readonly: {
606
- type: Object,
607
- required: true
608
- },
609
- setAttr: {
610
- type: Function,
611
- required: true
612
- },
613
- config: {
614
- type: Object,
615
- required: true
616
- }
628
+ src: { type: Object, required: true },
629
+ caption: { type: Object, required: true },
630
+ ratio: { type: Object, required: true },
631
+ align: { type: Object, required: true },
632
+ cropRatio: { type: Object, required: true },
633
+ cropTop: { type: Object, required: true },
634
+ cropLeft: { type: Object, required: true },
635
+ cropWidth: { type: Object, required: true },
636
+ cropHeight: { type: Object, required: true },
637
+ borderWidth: { type: Object, required: true },
638
+ borderColor: { type: Object, required: true },
639
+ borderStyle: { type: Object, required: true },
640
+ selected: { type: Object, required: true },
641
+ readonly: { type: Object, required: true },
642
+ setAttr: { type: Function, required: true },
643
+ config: { type: Object, required: true }
617
644
  },
618
- setup({ src, caption, ratio, readonly, setAttr, config }) {
645
+ setup({
646
+ src,
647
+ caption,
648
+ ratio,
649
+ readonly,
650
+ setAttr,
651
+ config,
652
+ cropRatio,
653
+ cropTop,
654
+ cropLeft,
655
+ cropWidth,
656
+ cropHeight,
657
+ borderWidth,
658
+ borderColor,
659
+ borderStyle
660
+ }) {
619
661
  var _a;
620
662
  const imageRef = ref();
663
+ const wrapperRef = ref();
621
664
  const showCaption = ref(Boolean((_a = caption.value) == null ? void 0 : _a.length));
622
665
  const timer = ref(0);
666
+ const showBorderPanel = ref(false);
667
+ const isCropping = ref(false);
668
+ const displayW = ref(0);
669
+ const displayH = ref(0);
670
+ const localCrop = ref({ top: 0, left: 0, width: 1, height: 1 });
623
671
  let resizeDir = "";
624
672
  let startY = 0;
625
673
  let startX = 0;
626
674
  let startHeight = 0;
627
675
  let startWidth = 0;
676
+ const isCropped = () => {
677
+ var _a2, _b, _c, _d;
678
+ const t = (_a2 = cropTop.value) != null ? _a2 : 0;
679
+ const l = (_b = cropLeft.value) != null ? _b : 0;
680
+ const w = (_c = cropWidth.value) != null ? _c : 1;
681
+ const h2 = (_d = cropHeight.value) != null ? _d : 1;
682
+ return t > 1e-3 || l > 1e-3 || w < 0.999 || h2 < 0.999;
683
+ };
628
684
  const onImageLoad = () => {
629
685
  var _a2;
630
686
  const image = imageRef.value;
@@ -645,6 +701,9 @@ const ImageViewer = defineComponent({
645
701
  image.dataset.height = h2;
646
702
  image.style.height = `${h2}px`;
647
703
  if (config.maxWidth) image.style.maxWidth = `${config.maxWidth}px`;
704
+ const dw = width < maxWidth ? width : maxWidth;
705
+ displayW.value = dw;
706
+ displayH.value = parseFloat(h2);
648
707
  };
649
708
  const onToggleCaption = (e) => {
650
709
  e.preventDefault();
@@ -720,46 +779,432 @@ const ImageViewer = defineComponent({
720
779
  window.addEventListener("pointermove", onResizeHandlePointerMove);
721
780
  window.addEventListener("pointerup", onResizeHandlePointerUp);
722
781
  };
723
- return () => {
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(
725
- "img",
726
- {
727
- ref: imageRef,
728
- "data-type": IMAGE_DATA_TYPE,
729
- onLoad: onImageLoad,
730
- src: src.value,
731
- alt: caption.value,
732
- onError: (e) => {
733
- var _a2;
734
- return Promise.resolve((_a2 = config.onImageLoadError) == null ? void 0 : _a2.call(config, e)).catch(() => {
735
- });
782
+ const borderStyleOptions = [
783
+ { label: "none", value: "none" },
784
+ { label: "solid", value: "solid" },
785
+ { label: "dashed", value: "dashed" },
786
+ { label: "dotted", value: "dotted" }
787
+ ];
788
+ const onToggleCropPanel = (e) => {
789
+ e.preventDefault();
790
+ e.stopPropagation();
791
+ if (readonly.value) return;
792
+ showBorderPanel.value = false;
793
+ if (isCropping.value) {
794
+ isCropping.value = false;
795
+ } else {
796
+ startCropping();
797
+ }
798
+ };
799
+ const onToggleBorderPanel = (e) => {
800
+ e.preventDefault();
801
+ e.stopPropagation();
802
+ if (readonly.value) return;
803
+ showBorderPanel.value = !showBorderPanel.value;
804
+ };
805
+ const closePanels = () => {
806
+ showBorderPanel.value = false;
807
+ };
808
+ const startCropping = () => {
809
+ var _a2, _b, _c, _d;
810
+ localCrop.value = {
811
+ top: (_a2 = cropTop.value) != null ? _a2 : 0,
812
+ left: (_b = cropLeft.value) != null ? _b : 0,
813
+ width: (_c = cropWidth.value) != null ? _c : 1,
814
+ height: (_d = cropHeight.value) != null ? _d : 1
815
+ };
816
+ isCropping.value = true;
817
+ };
818
+ const applyCrop = () => {
819
+ setAttr("cropTop", localCrop.value.top);
820
+ setAttr("cropLeft", localCrop.value.left);
821
+ setAttr("cropWidth", localCrop.value.width);
822
+ setAttr("cropHeight", localCrop.value.height);
823
+ isCropping.value = false;
824
+ };
825
+ const cancelCrop = () => {
826
+ isCropping.value = false;
827
+ };
828
+ const resetCrop = () => {
829
+ setAttr("cropTop", 0);
830
+ setAttr("cropLeft", 0);
831
+ setAttr("cropWidth", 1);
832
+ setAttr("cropHeight", 1);
833
+ };
834
+ let cropDragType = "";
835
+ let cropStartX = 0;
836
+ let cropStartY = 0;
837
+ let cropStartBox = { top: 0, left: 0, width: 1, height: 1 };
838
+ const onCropBoxPointerDown = (e, type) => {
839
+ e.preventDefault();
840
+ e.stopPropagation();
841
+ cropDragType = type;
842
+ cropStartX = e.clientX;
843
+ cropStartY = e.clientY;
844
+ cropStartBox = __spreadValues$1({}, localCrop.value);
845
+ window.addEventListener("pointermove", onCropBoxPointerMove);
846
+ window.addEventListener("pointerup", onCropBoxPointerUp);
847
+ };
848
+ const onCropBoxPointerMove = (e) => {
849
+ var _a2;
850
+ const wrapper = wrapperRef.value;
851
+ if (!wrapper) return;
852
+ const rect = wrapper.getBoundingClientRect();
853
+ if (!rect.width || !rect.height) return;
854
+ const dx = (e.clientX - cropStartX) / rect.width;
855
+ const dy = (e.clientY - cropStartY) / rect.height;
856
+ const ar = ratioMap[(_a2 = cropRatio.value) != null ? _a2 : "free"];
857
+ let box = __spreadValues$1({}, cropStartBox);
858
+ if (cropDragType === "move") {
859
+ box.left = Math.max(0, Math.min(1 - box.width, cropStartBox.left + dx));
860
+ box.top = Math.max(0, Math.min(1 - box.height, cropStartBox.top + dy));
861
+ } else {
862
+ const isLeft = cropDragType === "nw" || cropDragType === "sw" || cropDragType === "w";
863
+ const isTop = cropDragType === "nw" || cropDragType === "ne" || cropDragType === "n";
864
+ const isRight = cropDragType === "ne" || cropDragType === "se" || cropDragType === "e";
865
+ const isBottom = cropDragType === "sw" || cropDragType === "se" || cropDragType === "s";
866
+ const isHorizontal = cropDragType === "n" || cropDragType === "s";
867
+ const isVertical = cropDragType === "e" || cropDragType === "w";
868
+ let newLeft = cropStartBox.left;
869
+ let newTop = cropStartBox.top;
870
+ let newWidth = cropStartBox.width;
871
+ let newHeight = cropStartBox.height;
872
+ if (isLeft) {
873
+ newWidth = cropStartBox.width - dx;
874
+ newLeft = cropStartBox.left + dx;
875
+ } else if (isRight) {
876
+ newWidth = cropStartBox.width + dx;
877
+ }
878
+ if (isTop) {
879
+ newHeight = cropStartBox.height - dy;
880
+ newTop = cropStartBox.top + dy;
881
+ } else if (isBottom) {
882
+ newHeight = cropStartBox.height + dy;
883
+ }
884
+ if (ar && !isHorizontal && !isVertical) {
885
+ const cropPixelW = newWidth * rect.width;
886
+ const desiredH = cropPixelW / ar / rect.height;
887
+ if (isTop) {
888
+ newTop = newTop + newHeight - desiredH;
736
889
  }
890
+ newHeight = desiredH;
737
891
  }
738
- ), /* @__PURE__ */ h(
739
- "div",
740
- {
741
- class: "image-resize-handle top-left",
742
- onPointerdown: (e) => onResizeHandlePointerDown(e, "top-left")
892
+ if (newWidth < 0.05) newWidth = 0.05;
893
+ if (newHeight < 0.05) newHeight = 0.05;
894
+ if (newLeft < 0) {
895
+ newWidth += newLeft;
896
+ newLeft = 0;
743
897
  }
744
- ), /* @__PURE__ */ h(
745
- "div",
746
- {
747
- class: "image-resize-handle top-right",
748
- onPointerdown: (e) => onResizeHandlePointerDown(e, "top-right")
898
+ if (newTop < 0) {
899
+ newHeight += newTop;
900
+ newTop = 0;
749
901
  }
750
- ), /* @__PURE__ */ h(
902
+ if (newLeft + newWidth > 1) newWidth = 1 - newLeft;
903
+ if (newTop + newHeight > 1) newHeight = 1 - newTop;
904
+ box = { left: newLeft, top: newTop, width: newWidth, height: newHeight };
905
+ }
906
+ localCrop.value = box;
907
+ };
908
+ const onCropBoxPointerUp = () => {
909
+ window.removeEventListener("pointermove", onCropBoxPointerMove);
910
+ window.removeEventListener("pointerup", onCropBoxPointerUp);
911
+ cropDragType = "";
912
+ };
913
+ return () => {
914
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
915
+ const currentBorderStyle = (_a2 = borderStyle.value) != null ? _a2 : "none";
916
+ const currentBorderWidth = (_b = borderWidth.value) != null ? _b : 0;
917
+ const currentBorderColor = (_c = borderColor.value) != null ? _c : "#000000";
918
+ const cTop = (_d = cropTop.value) != null ? _d : 0;
919
+ const cLeft = (_e = cropLeft.value) != null ? _e : 0;
920
+ const cWidth = (_f = cropWidth.value) != null ? _f : 1;
921
+ const cHeight = (_g = cropHeight.value) != null ? _g : 1;
922
+ const cropped = isCropped();
923
+ const borderStyleStr = currentBorderStyle !== "none" && currentBorderWidth > 0 ? `${currentBorderWidth}px ${currentBorderStyle} ${currentBorderColor}` : void 0;
924
+ const dw = displayW.value;
925
+ const dh = displayH.value;
926
+ const imgEl = imageRef.value;
927
+ const actualW = imgEl ? imgEl.getBoundingClientRect().width : dw;
928
+ const actualH = imgEl ? imgEl.getBoundingClientRect().height : dh;
929
+ const baseW = cropped && !isCropping.value && imgEl ? actualW : dw;
930
+ const baseH = cropped && !isCropping.value && imgEl ? actualH : dh;
931
+ const cropPxW = baseW * cWidth;
932
+ const cropPxH = baseH * cHeight;
933
+ const cropPxL = baseW * cLeft;
934
+ const cropPxT = baseH * cTop;
935
+ const wrapperStyle = {};
936
+ const cropClipStyle = cropped && !isCropping.value && baseW > 0 && baseH > 0 ? {
937
+ width: `${cropPxW}px`,
938
+ height: `${cropPxH}px`,
939
+ overflow: "hidden"
940
+ } : null;
941
+ const imgStyle = {};
942
+ if (cropped && !isCropping.value && baseW > 0 && baseH > 0) {
943
+ imgStyle.width = `${baseW}px`;
944
+ imgStyle.height = `${baseH}px`;
945
+ imgStyle.maxWidth = "none";
946
+ imgStyle.marginLeft = `${-cropPxL}px`;
947
+ imgStyle.marginTop = `${-cropPxT}px`;
948
+ imgStyle.border = borderStyleStr != null ? borderStyleStr : "";
949
+ } else {
950
+ imgStyle.border = borderStyleStr != null ? borderStyleStr : "";
951
+ }
952
+ return /* @__PURE__ */ h(Fragment$2, null, !isCropping.value ? /* @__PURE__ */ h(
751
953
  "div",
752
954
  {
753
- class: "image-resize-handle bottom-left",
754
- onPointerdown: (e) => onResizeHandlePointerDown(e, "bottom-left")
755
- }
756
- ), /* @__PURE__ */ h(
955
+ class: "image-toolbar",
956
+ onClick: (e) => e.stopPropagation(),
957
+ onMousedown: (e) => e.stopPropagation(),
958
+ onDragstart: (e) => {
959
+ e.preventDefault();
960
+ e.stopPropagation();
961
+ }
962
+ },
963
+ /* @__PURE__ */ h(
964
+ "div",
965
+ {
966
+ class: "image-toolbar-item",
967
+ title: "\u6807\u9898",
968
+ onClick: onToggleCaption
969
+ },
970
+ /* @__PURE__ */ h(Icon, { icon: config.captionIcon })
971
+ ),
972
+ config.cropIcon ? /* @__PURE__ */ h(
973
+ "div",
974
+ {
975
+ class: "image-toolbar-item",
976
+ title: "\u88C1\u526A",
977
+ onClick: onToggleCropPanel
978
+ },
979
+ /* @__PURE__ */ h(Icon, { icon: config.cropIcon })
980
+ ) : null,
981
+ cropped ? /* @__PURE__ */ h(
982
+ "div",
983
+ {
984
+ class: "image-toolbar-item",
985
+ title: "\u6062\u590D\u88C1\u526A",
986
+ onClick: (e) => {
987
+ e.stopPropagation();
988
+ resetCrop();
989
+ }
990
+ },
991
+ /* @__PURE__ */ h(Icon, { icon: (_h = config.resetCropIcon) != null ? _h : "\u21A9" })
992
+ ) : null,
993
+ config.borderIcon ? /* @__PURE__ */ h(
994
+ "div",
995
+ {
996
+ class: "image-toolbar-item",
997
+ title: "\u8FB9\u6846",
998
+ onClick: onToggleBorderPanel
999
+ },
1000
+ /* @__PURE__ */ h(Icon, { icon: config.borderIcon })
1001
+ ) : null,
1002
+ showBorderPanel.value ? /* @__PURE__ */ h(
1003
+ "div",
1004
+ {
1005
+ class: "setting-panel border-panel",
1006
+ onClick: (e) => e.stopPropagation()
1007
+ },
1008
+ /* @__PURE__ */ h("div", { class: "setting-panel-title" }, "\u8FB9\u6846\u8BBE\u7F6E"),
1009
+ /* @__PURE__ */ h("div", { class: "setting-row" }, /* @__PURE__ */ h("span", { class: "setting-label" }, "\u6837\u5F0F"), /* @__PURE__ */ h("div", { class: "border-style-options" }, borderStyleOptions.map((opt) => /* @__PURE__ */ h(
1010
+ "div",
1011
+ {
1012
+ class: `border-style-option ${currentBorderStyle === opt.value ? "active" : ""}`,
1013
+ onClick: (e) => {
1014
+ e.stopPropagation();
1015
+ setAttr("borderStyle", opt.value);
1016
+ }
1017
+ },
1018
+ opt.label === "none" ? "\u65E0" : opt.label === "solid" ? "\u5B9E\u7EBF" : opt.label === "dashed" ? "\u865A\u7EBF" : "\u70B9\u7EBF"
1019
+ )))),
1020
+ currentBorderStyle !== "none" ? /* @__PURE__ */ h("div", { class: "setting-row" }, /* @__PURE__ */ h("span", { class: "setting-label" }, "\u5BBD\u5EA6"), /* @__PURE__ */ h(
1021
+ "input",
1022
+ {
1023
+ type: "range",
1024
+ min: "1",
1025
+ max: "10",
1026
+ value: currentBorderWidth,
1027
+ onInput: (e) => {
1028
+ const target = e.target;
1029
+ setAttr("borderWidth", Number(target.value));
1030
+ },
1031
+ onClick: (e) => e.stopPropagation(),
1032
+ onPointerdown: (e) => e.stopPropagation()
1033
+ }
1034
+ ), /* @__PURE__ */ h("span", { class: "setting-value" }, currentBorderWidth, "px")) : null,
1035
+ currentBorderStyle !== "none" ? /* @__PURE__ */ h("div", { class: "setting-row" }, /* @__PURE__ */ h("span", { class: "setting-label" }, "\u989C\u8272"), /* @__PURE__ */ h(
1036
+ "input",
1037
+ {
1038
+ type: "color",
1039
+ value: currentBorderColor,
1040
+ onInput: (e) => {
1041
+ const target = e.target;
1042
+ setAttr("borderColor", target.value);
1043
+ },
1044
+ onClick: (e) => e.stopPropagation(),
1045
+ onPointerdown: (e) => e.stopPropagation()
1046
+ }
1047
+ )) : null
1048
+ ) : null
1049
+ ) : null, /* @__PURE__ */ h(
757
1050
  "div",
758
1051
  {
759
- class: "image-resize-handle bottom-right",
760
- onPointerdown: (e) => onResizeHandlePointerDown(e, "bottom-right")
761
- }
762
- )), showCaption.value && /* @__PURE__ */ h(
1052
+ class: `image-wrapper${isCropping.value ? " cropping" : ""}`,
1053
+ ref: wrapperRef,
1054
+ style: wrapperStyle,
1055
+ onClick: closePanels
1056
+ },
1057
+ cropClipStyle ? /* @__PURE__ */ h("div", { class: "crop-clip", style: cropClipStyle }, /* @__PURE__ */ h(
1058
+ "img",
1059
+ {
1060
+ draggable: "false",
1061
+ ref: imageRef,
1062
+ "data-type": IMAGE_DATA_TYPE,
1063
+ onLoad: onImageLoad,
1064
+ src: src.value,
1065
+ alt: caption.value,
1066
+ style: imgStyle,
1067
+ onError: (e) => {
1068
+ var _a3;
1069
+ return Promise.resolve((_a3 = config.onImageLoadError) == null ? void 0 : _a3.call(config, e)).catch(
1070
+ () => {
1071
+ }
1072
+ );
1073
+ }
1074
+ }
1075
+ )) : /* @__PURE__ */ h(
1076
+ "img",
1077
+ {
1078
+ draggable: "false",
1079
+ ref: imageRef,
1080
+ "data-type": IMAGE_DATA_TYPE,
1081
+ onLoad: onImageLoad,
1082
+ src: src.value,
1083
+ alt: caption.value,
1084
+ style: imgStyle,
1085
+ onError: (e) => {
1086
+ var _a3;
1087
+ return Promise.resolve((_a3 = config.onImageLoadError) == null ? void 0 : _a3.call(config, e)).catch(() => {
1088
+ });
1089
+ }
1090
+ }
1091
+ ),
1092
+ isCropping.value ? /* @__PURE__ */ h("div", { class: "crop-overlay", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ h(
1093
+ "div",
1094
+ {
1095
+ class: "crop-box",
1096
+ style: {
1097
+ top: `${(localCrop.value.top * 100).toFixed(2)}%`,
1098
+ left: `${(localCrop.value.left * 100).toFixed(2)}%`,
1099
+ width: `${(localCrop.value.width * 100).toFixed(2)}%`,
1100
+ height: `${(localCrop.value.height * 100).toFixed(2)}%`
1101
+ },
1102
+ onPointerdown: (e) => onCropBoxPointerDown(e, "move")
1103
+ },
1104
+ /* @__PURE__ */ h("div", { class: "crop-grid" }, /* @__PURE__ */ h("div", { class: "crop-grid-line horizontal first" }), /* @__PURE__ */ h("div", { class: "crop-grid-line horizontal second" }), /* @__PURE__ */ h("div", { class: "crop-grid-line vertical first" }), /* @__PURE__ */ h("div", { class: "crop-grid-line vertical second" })),
1105
+ /* @__PURE__ */ h(
1106
+ "div",
1107
+ {
1108
+ class: "crop-handle nw",
1109
+ onPointerdown: (e) => onCropBoxPointerDown(e, "nw")
1110
+ }
1111
+ ),
1112
+ /* @__PURE__ */ h(
1113
+ "div",
1114
+ {
1115
+ class: "crop-handle ne",
1116
+ onPointerdown: (e) => onCropBoxPointerDown(e, "ne")
1117
+ }
1118
+ ),
1119
+ /* @__PURE__ */ h(
1120
+ "div",
1121
+ {
1122
+ class: "crop-handle sw",
1123
+ onPointerdown: (e) => onCropBoxPointerDown(e, "sw")
1124
+ }
1125
+ ),
1126
+ /* @__PURE__ */ h(
1127
+ "div",
1128
+ {
1129
+ class: "crop-handle se",
1130
+ onPointerdown: (e) => onCropBoxPointerDown(e, "se")
1131
+ }
1132
+ ),
1133
+ /* @__PURE__ */ h(
1134
+ "div",
1135
+ {
1136
+ class: "crop-handle n",
1137
+ onPointerdown: (e) => onCropBoxPointerDown(e, "n")
1138
+ }
1139
+ ),
1140
+ /* @__PURE__ */ h(
1141
+ "div",
1142
+ {
1143
+ class: "crop-handle s",
1144
+ onPointerdown: (e) => onCropBoxPointerDown(e, "s")
1145
+ }
1146
+ ),
1147
+ /* @__PURE__ */ h(
1148
+ "div",
1149
+ {
1150
+ class: "crop-handle e",
1151
+ onPointerdown: (e) => onCropBoxPointerDown(e, "e")
1152
+ }
1153
+ ),
1154
+ /* @__PURE__ */ h(
1155
+ "div",
1156
+ {
1157
+ class: "crop-handle w",
1158
+ onPointerdown: (e) => onCropBoxPointerDown(e, "w")
1159
+ }
1160
+ )
1161
+ ), /* @__PURE__ */ h("div", { class: "crop-toolbar" }, /* @__PURE__ */ h(
1162
+ "div",
1163
+ {
1164
+ class: "crop-toolbar-btn",
1165
+ onClick: (e) => {
1166
+ e.stopPropagation();
1167
+ applyCrop();
1168
+ }
1169
+ },
1170
+ /* @__PURE__ */ h(Icon, { icon: (_i = config.confirmIcon) != null ? _i : "\u2713" })
1171
+ ), /* @__PURE__ */ h(
1172
+ "div",
1173
+ {
1174
+ class: "crop-toolbar-btn",
1175
+ onClick: (e) => {
1176
+ e.stopPropagation();
1177
+ cancelCrop();
1178
+ }
1179
+ },
1180
+ /* @__PURE__ */ h(Icon, { icon: (_j = config.cancelIcon) != null ? _j : "\u2715" })
1181
+ ))) : null,
1182
+ !isCropping.value ? /* @__PURE__ */ h(Fragment$2, null, /* @__PURE__ */ h(
1183
+ "div",
1184
+ {
1185
+ class: "image-resize-handle top-left",
1186
+ onPointerdown: (e) => onResizeHandlePointerDown(e, "top-left")
1187
+ }
1188
+ ), /* @__PURE__ */ h(
1189
+ "div",
1190
+ {
1191
+ class: "image-resize-handle top-right",
1192
+ onPointerdown: (e) => onResizeHandlePointerDown(e, "top-right")
1193
+ }
1194
+ ), /* @__PURE__ */ h(
1195
+ "div",
1196
+ {
1197
+ class: "image-resize-handle bottom-left",
1198
+ onPointerdown: (e) => onResizeHandlePointerDown(e, "bottom-left")
1199
+ }
1200
+ ), /* @__PURE__ */ h(
1201
+ "div",
1202
+ {
1203
+ class: "image-resize-handle bottom-right",
1204
+ onPointerdown: (e) => onResizeHandlePointerDown(e, "bottom-right")
1205
+ }
1206
+ )) : null
1207
+ ), showCaption.value && /* @__PURE__ */ h(
763
1208
  "input",
764
1209
  {
765
1210
  draggable: "true",
@@ -813,6 +1258,38 @@ const MilkdownImageBlock = defineComponent({
813
1258
  type: Object,
814
1259
  required: true
815
1260
  },
1261
+ cropRatio: {
1262
+ type: Object,
1263
+ required: true
1264
+ },
1265
+ cropTop: {
1266
+ type: Object,
1267
+ required: true
1268
+ },
1269
+ cropLeft: {
1270
+ type: Object,
1271
+ required: true
1272
+ },
1273
+ cropWidth: {
1274
+ type: Object,
1275
+ required: true
1276
+ },
1277
+ cropHeight: {
1278
+ type: Object,
1279
+ required: true
1280
+ },
1281
+ borderWidth: {
1282
+ type: Object,
1283
+ required: true
1284
+ },
1285
+ borderColor: {
1286
+ type: Object,
1287
+ required: true
1288
+ },
1289
+ borderStyle: {
1290
+ type: Object,
1291
+ required: true
1292
+ },
816
1293
  selected: {
817
1294
  type: Object,
818
1295
  required: true
@@ -864,6 +1341,14 @@ const imageBlockView = $view(
864
1341
  const caption = ref(initialNode.attrs.caption);
865
1342
  const ratio = ref(initialNode.attrs.ratio);
866
1343
  const align = ref(initialNode.attrs.align);
1344
+ const cropRatio = ref(initialNode.attrs.cropRatio);
1345
+ const cropTop = ref(initialNode.attrs.cropTop);
1346
+ const cropLeft = ref(initialNode.attrs.cropLeft);
1347
+ const cropWidth = ref(initialNode.attrs.cropWidth);
1348
+ const cropHeight = ref(initialNode.attrs.cropHeight);
1349
+ const borderWidth = ref(initialNode.attrs.borderWidth);
1350
+ const borderColor = ref(initialNode.attrs.borderColor);
1351
+ const borderStyle = ref(initialNode.attrs.borderStyle);
867
1352
  const selected = ref(false);
868
1353
  const readonly = ref(!view.editable);
869
1354
  const setAttr = (attr, value) => {
@@ -884,6 +1369,14 @@ const imageBlockView = $view(
884
1369
  caption,
885
1370
  ratio,
886
1371
  align,
1372
+ cropRatio,
1373
+ cropTop,
1374
+ cropLeft,
1375
+ cropWidth,
1376
+ cropHeight,
1377
+ borderWidth,
1378
+ borderColor,
1379
+ borderStyle,
887
1380
  selected,
888
1381
  readonly,
889
1382
  setAttr,
@@ -903,6 +1396,18 @@ const imageBlockView = $view(
903
1396
  const disposeAlignWatcher = watchEffect(() => {
904
1397
  dom.dataset.align = align.value || "center";
905
1398
  });
1399
+ const disposeCropWatcher = watchEffect(() => {
1400
+ dom.dataset.cropRatio = cropRatio.value || "free";
1401
+ });
1402
+ const disposeBorderWatcher = watchEffect(() => {
1403
+ var _a, _b, _c;
1404
+ const w = (_a = borderWidth.value) != null ? _a : 0;
1405
+ const c = (_b = borderColor.value) != null ? _b : "#000000";
1406
+ const s = (_c = borderStyle.value) != null ? _c : "none";
1407
+ dom.dataset.borderWidth = String(w);
1408
+ dom.dataset.borderColor = c;
1409
+ dom.dataset.borderStyle = s;
1410
+ });
906
1411
  const proxyDomURL = config.proxyDomURL;
907
1412
  const bindAttrs = (node) => {
908
1413
  if (!proxyDomURL) {
@@ -920,6 +1425,14 @@ const imageBlockView = $view(
920
1425
  ratio.value = node.attrs.ratio;
921
1426
  caption.value = node.attrs.caption;
922
1427
  align.value = node.attrs.align;
1428
+ cropRatio.value = node.attrs.cropRatio;
1429
+ cropTop.value = node.attrs.cropTop;
1430
+ cropLeft.value = node.attrs.cropLeft;
1431
+ cropWidth.value = node.attrs.cropWidth;
1432
+ cropHeight.value = node.attrs.cropHeight;
1433
+ borderWidth.value = node.attrs.borderWidth;
1434
+ borderColor.value = node.attrs.borderColor;
1435
+ borderStyle.value = node.attrs.borderStyle;
923
1436
  readonly.value = !view.editable;
924
1437
  };
925
1438
  bindAttrs(initialNode);
@@ -932,7 +1445,13 @@ const imageBlockView = $view(
932
1445
  return true;
933
1446
  },
934
1447
  stopEvent: (e) => {
1448
+ var _a;
935
1449
  if (e.target instanceof HTMLInputElement) return true;
1450
+ if (e.target instanceof HTMLElement && e.target.tagName === "INPUT")
1451
+ return true;
1452
+ const target = e.target;
1453
+ if ((_a = target.closest) == null ? void 0 : _a.call(target, ".setting-panel, .image-toolbar, .crop-overlay"))
1454
+ return true;
936
1455
  return false;
937
1456
  },
938
1457
  selectNode: () => {
@@ -944,6 +1463,8 @@ const imageBlockView = $view(
944
1463
  destroy: () => {
945
1464
  disposeSelectedWatcher();
946
1465
  disposeAlignWatcher();
1466
+ disposeCropWatcher();
1467
+ disposeBorderWatcher();
947
1468
  app.unmount();
948
1469
  dom.remove();
949
1470
  }