mce 0.15.18 → 0.15.19

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/dist/index.css CHANGED
@@ -694,7 +694,7 @@
694
694
  100% {
695
695
  left: 100%;
696
696
  }
697
- }.mce-statusbar[data-v-a57093aa] {
697
+ }.mce-statusbar[data-v-79192677] {
698
698
  user-select: none;
699
699
  position: relative;
700
700
  display: flex;
@@ -709,28 +709,30 @@
709
709
  color: rgba(var(--mce-theme-on-surface), 1);
710
710
  font-weight: bold;
711
711
  }
712
- .mce-statusbar__main[data-v-a57093aa] {
712
+ .mce-statusbar__main[data-v-79192677] {
713
713
  flex: 1;
714
714
  display: flex;
715
715
  align-items: center;
716
+ gap: 4px;
717
+ height: 100%;
716
718
  }
717
- .mce-statusbar__item[data-v-a57093aa] {
719
+ .mce-statusbar__item[data-v-79192677] {
718
720
  display: flex;
719
721
  align-items: center;
720
722
  gap: 4px;
721
723
  }
722
- .mce-statusbar__item > svg[data-v-a57093aa] {
724
+ .mce-statusbar__item > svg[data-v-79192677] {
723
725
  width: 1em;
724
726
  height: 1em;
725
727
  }
726
- .mce-statusbar__divider[data-v-a57093aa] {
728
+ .mce-statusbar__divider[data-v-79192677] {
727
729
  width: 0;
728
730
  height: 60%;
729
731
  border-right: 1px solid rgba(var(--mce-theme-on-surface), 0.2);
730
732
  margin: 0 8px;
731
733
  }
732
- .mce-statusbar__kbd[data-v-a57093aa] {
733
- outline: 1px solid rgba(var(--mce-theme-on-surface), 0.4);
734
+ .mce-statusbar__kbd[data-v-79192677] {
735
+ outline: 1px solid rgba(var(--mce-theme-on-surface), 0.1);
734
736
  border-radius: 4px;
735
737
  display: flex;
736
738
  align-items: center;
@@ -1035,7 +1037,6 @@
1035
1037
  font-size: 24px;
1036
1038
  width: 100%;
1037
1039
  height: 100%;
1038
- border-radius: 8px;
1039
1040
  }
1040
1041
  .mce-toolbelt__icon {
1041
1042
  font-size: 1rem;
package/dist/index.js CHANGED
@@ -1076,6 +1076,7 @@ const en = {
1076
1076
  "goBackSelectedArea": "Go back selected area",
1077
1077
  "selectArea": "Select area",
1078
1078
  "dragSelected": "Drag selected",
1079
+ "startTyping": "Start typing",
1079
1080
  "move": "Move",
1080
1081
  "hand": "Hand",
1081
1082
  "frame": "Frame",
@@ -1184,6 +1185,7 @@ const zhHans = {
1184
1185
  "goBackSelectedArea": "返回选中区域",
1185
1186
  "selectArea": "选择区域",
1186
1187
  "dragSelected": "拖拽选择的",
1188
+ "startTyping": "编辑文字",
1187
1189
  "move": "移动",
1188
1190
  "hand": "抓手",
1189
1191
  "frame": "画板",
@@ -2671,10 +2673,11 @@ class TextEditor extends HTMLElement {
2671
2673
  _timer;
2672
2674
  _onKeydown(e) {
2673
2675
  e.stopPropagation();
2674
- switch (e.key) {
2675
- case "Escape":
2676
- this.selection = void 0;
2677
- return this._textarea.blur();
2676
+ if (e.key === "Escape" || (e.ctrlKey || e.metaKey) && e.key === "Enter") {
2677
+ this.selection = void 0;
2678
+ this._textarea.blur();
2679
+ this._emit("submit");
2680
+ return;
2678
2681
  }
2679
2682
  this._updateSelectionByDom();
2680
2683
  setTimeout(() => this._updateSelectionByDom(), 0);
@@ -3372,6 +3375,7 @@ const _4_3_element = defineMixin((editor) => {
3372
3375
  textToFit,
3373
3376
  log,
3374
3377
  root,
3378
+ isElement,
3375
3379
  isFrame,
3376
3380
  isLock,
3377
3381
  getObb,
@@ -3557,12 +3561,14 @@ const _4_3_element = defineMixin((editor) => {
3557
3561
  element2?.requestRender?.();
3558
3562
  }
3559
3563
  handle(element);
3560
- function deepHandle(element2) {
3561
- element2.children?.forEach((child) => {
3562
- deepHandle(child);
3564
+ if (options.deep) {
3565
+ element.findOne((node) => {
3566
+ if (isElement(node)) {
3567
+ handle(node);
3568
+ }
3569
+ return false;
3563
3570
  });
3564
3571
  }
3565
- options.deep && deepHandle(element);
3566
3572
  options.textToFit && textToFit(element);
3567
3573
  options.textFontSizeToFit && textFontSizeToFit(element, scaleX);
3568
3574
  }
@@ -3850,16 +3856,17 @@ const _snapshot = defineMixin((editor) => {
3850
3856
  data
3851
3857
  });
3852
3858
  }
3853
- async function captureFrameScreenshot(pageIndex) {
3854
- const frame = frames.value[pageIndex];
3859
+ async function captureFrameScreenshot(index) {
3860
+ const frame = frames.value[index];
3855
3861
  if (frame) {
3856
3862
  const canvas = await captureElementScreenshot(frame);
3857
- frameThumbs.value[pageIndex] = {
3863
+ frameThumbs.value[index] = {
3864
+ instanceId: frame.instanceId,
3858
3865
  width: canvas.width,
3859
3866
  height: canvas.height,
3860
3867
  url: canvas.toDataURL()
3861
3868
  };
3862
- log("captureFrameScreenshot", pageIndex);
3869
+ log("captureFrameScreenshot", index);
3863
3870
  }
3864
3871
  }
3865
3872
  function renderFrameThumb(target) {
@@ -3899,16 +3906,18 @@ const _snapshot = defineMixin((editor) => {
3899
3906
  return () => {
3900
3907
  const {
3901
3908
  on,
3902
- config
3909
+ config,
3910
+ isFrame
3903
3911
  } = editor;
3904
3912
  on("setDoc", (doc) => {
3905
3913
  if (config.value.frameScreenshot) {
3906
3914
  snapshot();
3907
3915
  }
3908
- function onAppendChild(node) {
3909
- if (config.value.frameScreenshot) {
3910
- const index = node.getIndex();
3916
+ function onAddChild(node, _newIndex) {
3917
+ if (config.value.frameScreenshot && isFrame(node)) {
3918
+ const index = frames.value.findIndex((f) => f.equal(node));
3911
3919
  frameThumbs.value.splice(index, 0, {
3920
+ instanceId: -1,
3912
3921
  width: 0,
3913
3922
  height: 0,
3914
3923
  url: ""
@@ -3916,7 +3925,16 @@ const _snapshot = defineMixin((editor) => {
3916
3925
  captureFrameScreenshot(index);
3917
3926
  }
3918
3927
  }
3919
- doc.root.on("appendChild", onAppendChild);
3928
+ function onRemoveChild(node, _oldIndex) {
3929
+ if (config.value.frameScreenshot && isFrame(node)) {
3930
+ frameThumbs.value.splice(
3931
+ frameThumbs.value.findIndex((v) => v.instanceId === node.instanceId),
3932
+ 1
3933
+ );
3934
+ }
3935
+ }
3936
+ doc.root.on("addChild", onAddChild);
3937
+ doc.root.on("removeChild", onRemoveChild);
3920
3938
  });
3921
3939
  on("setCurrentFrame", (_index, oldIndex) => {
3922
3940
  if (config.value.frameScreenshot) {
@@ -4106,6 +4124,18 @@ const _clipboard = definePlugin((editor, options) => {
4106
4124
  })
4107
4125
  ]);
4108
4126
  }
4127
+ } else if (Array.isArray(source) && source.some((v) => v instanceof Blob)) {
4128
+ if (useClipboard) {
4129
+ const items = {};
4130
+ source.forEach((blob) => {
4131
+ if (blob instanceof Blob) {
4132
+ items[blob.type] = blob;
4133
+ }
4134
+ });
4135
+ await navigator.clipboard.write([
4136
+ new ClipboardItem(items)
4137
+ ]);
4138
+ }
4109
4139
  } else {
4110
4140
  if (useClipboard) {
4111
4141
  const textItems = [];
@@ -4176,11 +4206,13 @@ const _clipboard = definePlugin((editor, options) => {
4176
4206
  const elements = [];
4177
4207
  for (const item of items) {
4178
4208
  const types = [...item.types];
4179
- const index = types.indexOf("text/html");
4180
- if (index > -1) {
4181
- types.splice(index, 1);
4182
- types.unshift("text/html");
4183
- }
4209
+ ["image/svg+xml", "text/html"].forEach((type) => {
4210
+ const index = types.indexOf(type);
4211
+ if (index > -1) {
4212
+ types.splice(index, 1);
4213
+ types.unshift(type);
4214
+ }
4215
+ });
4184
4216
  for (const type of types) {
4185
4217
  const blob = await item.getType(type);
4186
4218
  if (await canLoad(blob)) {
@@ -4403,6 +4435,33 @@ const _drawingTool = definePlugin((editor) => {
4403
4435
  ]
4404
4436
  };
4405
4437
  });
4438
+ const _enter = definePlugin((editor) => {
4439
+ const {
4440
+ selection,
4441
+ isElement,
4442
+ exec
4443
+ } = editor;
4444
+ async function _enter2() {
4445
+ if (selection.value.length === 1) {
4446
+ const node = selection.value[0];
4447
+ if (isElement(node)) {
4448
+ if (node.text.isValid()) {
4449
+ await exec("startTyping");
4450
+ }
4451
+ }
4452
+ }
4453
+ }
4454
+ const when = () => Boolean(selection.value.length > 0);
4455
+ return {
4456
+ name: "mce:enter",
4457
+ commands: [
4458
+ { command: "enter", handle: _enter2 }
4459
+ ],
4460
+ hotkeys: [
4461
+ { command: "enter", key: ["Enter"], when }
4462
+ ]
4463
+ };
4464
+ });
4406
4465
  const _flip = definePlugin((editor) => {
4407
4466
  const {
4408
4467
  elementSelection
@@ -13568,7 +13627,8 @@ const _hoisted_17 = { class: "mce-statusbar__item" };
13568
13627
  const _hoisted_18 = { class: "mce-statusbar__item" };
13569
13628
  const _hoisted_19 = { class: "mce-statusbar__kbd" };
13570
13629
  const _hoisted_20 = { class: "mce-statusbar__item" };
13571
- const _hoisted_21 = { class: "mce-statusbar__progress" };
13630
+ const _hoisted_21 = { class: "mce-statusbar__item" };
13631
+ const _hoisted_22 = { class: "mce-statusbar__progress" };
13572
13632
  const _sfc_main$i = /* @__PURE__ */ defineComponent({
13573
13633
  __name: "Statusbar",
13574
13634
  setup(__props) {
@@ -13577,7 +13637,9 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
13577
13637
  t,
13578
13638
  getKbd,
13579
13639
  exporting,
13580
- exportProgress
13640
+ exportProgress,
13641
+ selection,
13642
+ isElement
13581
13643
  } = useEditor();
13582
13644
  return (_ctx, _cache) => {
13583
13645
  return openBlock(), createElementBlock("div", _hoisted_1$a, [
@@ -13611,29 +13673,36 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
13611
13673
  createVNode(unref(_sfc_main$C), { icon: "$mouseLeftClick" }),
13612
13674
  createElementVNode("span", null, toDisplayString(unref(t)("selectObject")), 1)
13613
13675
  ]),
13614
- _cache[4] || (_cache[4] = createElementVNode("span", null, " + ", -1)),
13676
+ _cache[5] || (_cache[5] = createElementVNode("span", null, " + ", -1)),
13615
13677
  createElementVNode("div", _hoisted_15, [
13616
13678
  createElementVNode("span", _hoisted_16, toDisplayString(unref(getKbd)("Shift")), 1),
13617
13679
  createElementVNode("span", null, toDisplayString(unref(t)("extend")), 1)
13618
13680
  ]),
13619
- _cache[5] || (_cache[5] = createElementVNode("div", { class: "mce-statusbar__divider" }, null, -1)),
13681
+ _cache[6] || (_cache[6] = createElementVNode("div", { class: "mce-statusbar__divider" }, null, -1)),
13620
13682
  createElementVNode("div", _hoisted_17, [
13621
13683
  createVNode(unref(_sfc_main$C), { icon: "$mouseLeftClick" }),
13622
13684
  createElementVNode("span", null, toDisplayString(unref(t)("selectArea")), 1)
13623
13685
  ]),
13624
- _cache[6] || (_cache[6] = createElementVNode("span", null, " + ", -1)),
13686
+ _cache[7] || (_cache[7] = createElementVNode("span", null, " + ", -1)),
13625
13687
  createElementVNode("div", _hoisted_18, [
13626
13688
  createElementVNode("span", _hoisted_19, toDisplayString(unref(getKbd)("Shift")), 1),
13627
13689
  createElementVNode("span", null, toDisplayString(unref(t)("extend")), 1)
13628
13690
  ]),
13629
- _cache[7] || (_cache[7] = createElementVNode("div", { class: "mce-statusbar__divider" }, null, -1)),
13691
+ _cache[8] || (_cache[8] = createElementVNode("div", { class: "mce-statusbar__divider" }, null, -1)),
13630
13692
  createElementVNode("div", _hoisted_20, [
13631
13693
  createVNode(unref(_sfc_main$C), { icon: "$mouseLeftClick" }),
13632
13694
  createElementVNode("span", null, toDisplayString(unref(t)("dragSelected")), 1)
13633
- ])
13695
+ ]),
13696
+ unref(selection).length === 1 && unref(isElement)(unref(selection)[0]) && unref(selection)[0].text.isValid() ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
13697
+ _cache[4] || (_cache[4] = createElementVNode("div", { class: "mce-statusbar__divider" }, null, -1)),
13698
+ createElementVNode("div", _hoisted_21, [
13699
+ createElementVNode("span", null, toDisplayString(unref(getKbd)("Enter")), 1),
13700
+ createElementVNode("span", null, toDisplayString(unref(t)("startTyping")), 1)
13701
+ ])
13702
+ ], 64)) : createCommentVNode("", true)
13634
13703
  ], 64))
13635
13704
  ]),
13636
- createElementVNode("div", _hoisted_21, [
13705
+ createElementVNode("div", _hoisted_22, [
13637
13706
  unref(exporting) ? (openBlock(), createBlock(ProgressIndicator, {
13638
13707
  key: 0,
13639
13708
  modelValue: unref(exportProgress),
@@ -13645,7 +13714,7 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
13645
13714
  };
13646
13715
  }
13647
13716
  });
13648
- const Statusbar = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-a57093aa"]]);
13717
+ const Statusbar = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-79192677"]]);
13649
13718
  const _statusbar = definePlugin((editor) => {
13650
13719
  const {
13651
13720
  registerConfig
@@ -14399,6 +14468,7 @@ const plugins = [
14399
14468
  _copyAs,
14400
14469
  _delete,
14401
14470
  _drawingTool,
14471
+ _enter,
14402
14472
  _flip,
14403
14473
  _frame,
14404
14474
  _gif,
@@ -15583,7 +15653,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
15583
15653
  element,
15584
15654
  newStyle.width / element.style.width,
15585
15655
  newStyle.height / element.style.height,
15586
- isFrame(element) ? void 0 : !shape.isValid() ? handle.split("-").length > 2 ? { deep: true, textFontSizeToFit: true } : { deep: true, textToFit: true } : void 0
15656
+ isFrame(element) ? void 0 : shape.isValid() ? { deep: true } : handle.split("-").length > 2 ? { deep: true, textFontSizeToFit: true } : { deep: true, textToFit: true }
15587
15657
  );
15588
15658
  newStyle.width = element.style.width;
15589
15659
  newStyle.height = element.style.height;
@@ -15661,9 +15731,9 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
15661
15731
  ref: "transformableTpl",
15662
15732
  modelValue: transform.value,
15663
15733
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => transform.value = $event),
15664
- movable: movable.value,
15665
- resizable: resizable.value,
15666
- rotatable: rotatable.value,
15734
+ movable: unref(state) !== "typing" && movable.value,
15735
+ resizable: unref(state) !== "typing" && resizable.value,
15736
+ rotatable: unref(state) !== "typing" && rotatable.value,
15667
15737
  "adjustable-border-radius": adjustableBorderRadius.value,
15668
15738
  "resize-strategy": props.resizeStrategy,
15669
15739
  "handle-shape": unref(config).handleShape,
@@ -15902,6 +15972,9 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
15902
15972
  textToFit(element);
15903
15973
  }
15904
15974
  }
15975
+ function onSubmit() {
15976
+ state.value = void 0;
15977
+ }
15905
15978
  async function startTyping(e) {
15906
15979
  const element = elementSelection.value[0];
15907
15980
  if (!element) {
@@ -15953,7 +16026,8 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
15953
16026
  },
15954
16027
  "data-pointerdown_to_drawboard": "",
15955
16028
  onSelected: onUpdateTextSelection,
15956
- onUpdate
16029
+ onUpdate,
16030
+ onSubmit
15957
16031
  }, null, 544)
15958
16032
  ], 4)
15959
16033
  ], 4)), [
@@ -11,6 +11,7 @@ declare const _default: {
11
11
  goBackSelectedArea: string;
12
12
  selectArea: string;
13
13
  dragSelected: string;
14
+ startTyping: string;
14
15
  move: string;
15
16
  hand: string;
16
17
  frame: string;
@@ -12,6 +12,7 @@ declare const _default: {
12
12
  goBackSelectedArea: string;
13
13
  selectArea: string;
14
14
  dragSelected: string;
15
+ startTyping: string;
15
16
  move: string;
16
17
  hand: string;
17
18
  frame: string;
@@ -4,6 +4,7 @@ import type { AxisAlignedBoundingBox } from '../types';
4
4
  declare global {
5
5
  namespace Mce {
6
6
  interface FrameThumb {
7
+ instanceId: number;
7
8
  width: number;
8
9
  height: number;
9
10
  url: string;
@@ -11,7 +11,7 @@ declare global {
11
11
  type ExporterHandle = (options: ExportOptions) => any | Promise<any>;
12
12
  interface Exporter {
13
13
  name: string;
14
- copyAs?: boolean | ((exported: any) => string);
14
+ copyAs?: boolean | ((exported: any) => CopySource);
15
15
  saveAs?: boolean | ((exported: any) => Blob);
16
16
  handle: ExporterHandle;
17
17
  }
@@ -7,7 +7,7 @@ declare global {
7
7
  paste: [event: KeyboardEvent];
8
8
  duplicate: [event: KeyboardEvent];
9
9
  }
10
- type CopySource = string | Blob | Record<string, any>[];
10
+ type CopySource = string | Blob | Blob[] | Record<string, any>[];
11
11
  type PasteSource = DataTransfer | ClipboardItem[];
12
12
  interface Commands {
13
13
  copy: (source?: CopySource) => Promise<void>;
@@ -0,0 +1,12 @@
1
+ declare global {
2
+ namespace Mce {
3
+ interface Commands {
4
+ enter: () => void;
5
+ }
6
+ interface Hotkeys {
7
+ enter: [event: KeyboardEvent];
8
+ }
9
+ }
10
+ }
11
+ declare const _default: import("..").Plugin;
12
+ export default _default;
@@ -31,6 +31,7 @@ import './plugins/clipboard'
31
31
  import './plugins/copyAs'
32
32
  import './plugins/delete'
33
33
  import './plugins/drawingTool'
34
+ import './plugins/enter'
34
35
  import './plugins/flip'
35
36
  import './plugins/frame'
36
37
  import './plugins/gif'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mce",
3
3
  "type": "module",
4
- "version": "0.15.18",
4
+ "version": "0.15.19",
5
5
  "description": "The headless canvas editor framework. only the ESM.",
6
6
  "author": "wxm",
7
7
  "license": "MIT",
@@ -63,7 +63,7 @@
63
63
  "lodash-es": "^4.17.22",
64
64
  "modern-canvas": "^0.14.35",
65
65
  "modern-font": "^0.4.4",
66
- "modern-idoc": "^0.10.8",
66
+ "modern-idoc": "^0.10.9",
67
67
  "modern-text": "^1.10.15",
68
68
  "yjs": "^13.6.29"
69
69
  },