mce 0.15.7 → 0.15.9

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.
@@ -8,7 +8,6 @@ export interface LayerItem {
8
8
  }
9
9
  export interface LayerProvide {
10
10
  selecting: Ref<boolean>;
11
- sortedSelection: Ref<Node[]>;
12
11
  register: (vm: ComponentInternalInstance, item: LayerItem) => void;
13
12
  unregister: (id: string) => void;
14
13
  onMousedown?: (event: MouseEvent, id: string) => void;
@@ -19,7 +18,7 @@ export declare const MceLayerKey: InjectionKey<LayerProvide>;
19
18
  export declare const MceLayerItemKey: InjectionKey<{
20
19
  id: string;
21
20
  }>;
22
- export declare function createLayer(options: Pick<LayerProvide, 'sortedSelection'>): {
21
+ export declare function createLayer(): {
23
22
  selecting: Ref<boolean, boolean>;
24
23
  openedItems: import("vue").Reactive<Map<string, Ref<boolean, boolean>>>;
25
24
  domItems: import("vue").Reactive<Map<string, Ref<HTMLElement | undefined, HTMLElement | undefined>>>;
@@ -30,7 +29,6 @@ export declare function useLayerItem(options: Omit<LayerItem, 'id'>): {
30
29
  dropping: import("vue").ComputedRef<boolean>;
31
30
  onMousedown: (e: MouseEvent) => void | undefined;
32
31
  selecting: Ref<boolean>;
33
- sortedSelection: Ref<Node[]>;
34
32
  register: (vm: ComponentInternalInstance, item: LayerItem) => void;
35
33
  unregister: (id: string) => void;
36
34
  dragging: Ref<boolean>;
@@ -41,7 +41,7 @@ export declare class Doc extends Model {
41
41
  set(source: Document): this;
42
42
  protected _proxyProps(obj: CoreObject, yMap: Y.Map<any>, isMeta?: boolean): void;
43
43
  protected _proxyChildren(node: Node, childrenIds: Y.Array<string>): void;
44
- protected _proxyNode(node: Node, yNode?: YNode, yChildrenIds?: Y.Array<string>): YNode;
44
+ protected _proxyNode(node: Node, yNode?: YNode, yChildrenIds?: Y.Array<string>): void;
45
45
  protected _initYNode(yNode: YNode): Node;
46
46
  toJSON(): Record<string, any>;
47
47
  }
package/dist/index.css CHANGED
@@ -134,7 +134,6 @@
134
134
  border-radius: inherit;
135
135
  }
136
136
  .mce-layer--root {
137
- margin-bottom: 4px;
138
137
  font-weight: bold;
139
138
  }
140
139
  .mce-layer--root .mce-layer__thumbnail {
@@ -148,12 +147,12 @@
148
147
  bottom: 0;
149
148
  border-radius: 0;
150
149
  }
151
- .mce-layer--first .mce-layer__underlay {
150
+ .mce-layer--active:not(.mce-layer--active + .mce-layer--active) .mce-layer__underlay {
152
151
  border-top-left-radius: 4px;
153
152
  border-top-right-radius: 4px;
154
153
  top: 4px;
155
154
  }
156
- .mce-layer--last .mce-layer__underlay {
155
+ .mce-layer--active:not(:has(+ .mce-layer--active)) .mce-layer__underlay {
157
156
  border-bottom-left-radius: 4px;
158
157
  border-bottom-right-radius: 4px;
159
158
  bottom: 4px;
@@ -225,17 +224,23 @@
225
224
  flex: none;
226
225
  display: flex;
227
226
  align-items: center;
228
- background-color: var(--overlay-color, transparent);
229
- backdrop-filter: blur(8px);
230
227
  border-radius: 4px;
231
- }
232
- .mce-layer__action--hide {
233
228
  background-color: transparent;
234
229
  backdrop-filter: none;
235
230
  }
236
- .mce-layer__action--hide .mce-layer__btn {
231
+ .mce-layer__action .mce-layer__btn {
237
232
  opacity: 0;
238
233
  }
234
+ .mce-layer__action--hover .mce-layer__btn {
235
+ opacity: 1;
236
+ }
237
+ .mce-layer__action--show {
238
+ background-color: var(--overlay-color, transparent);
239
+ backdrop-filter: blur(8px);
240
+ }
241
+ .mce-layer__btn--show {
242
+ opacity: 1 !important;
243
+ }
239
244
  .mce-layer__btn + .mce-layer__btn {
240
245
  margin-left: -4px;
241
246
  }.mce-layers {
@@ -259,6 +264,9 @@
259
264
  }
260
265
  .mce-layers:hover .mce-layer:not(.mce-layer--root) .mce-layer__prepend {
261
266
  opacity: 1;
267
+ }
268
+ .mce-layers .mce-layer {
269
+ scroll-margin: 8px;
262
270
  }.mce-made-with {
263
271
  pointer-events: auto !important;
264
272
  position: absolute;
package/dist/index.js CHANGED
@@ -688,7 +688,7 @@ class Doc extends Model {
688
688
  }
689
689
  _proxyChildren(node, childrenIds) {
690
690
  node.on("addChild", (child, newIndex) => {
691
- if (this._transacting === false) {
691
+ if (this._transacting === false || child.internalMode !== "default") {
692
692
  return;
693
693
  }
694
694
  this.transact(() => {
@@ -698,7 +698,7 @@ class Doc extends Model {
698
698
  });
699
699
  });
700
700
  node.on("removeChild", (child, oldIndex) => {
701
- if (this._transacting === false) {
701
+ if (this._transacting === false || child.internalMode !== "default") {
702
702
  return;
703
703
  }
704
704
  this.transact(() => {
@@ -715,7 +715,7 @@ class Doc extends Model {
715
715
  const cachedChildrenIds = childrenIds.toArray();
716
716
  const observeFn = (event, transaction) => {
717
717
  const skip = this._isSelfTransaction(transaction);
718
- this._debug(`yChildren ${node.id} changes`, event.changes.delta);
718
+ this._debug(`yChildren ${node.id} changes skip:${skip}`, event.changes.delta);
719
719
  let retain = 0;
720
720
  event.changes.delta.forEach((action) => {
721
721
  if (action.retain !== void 0) {
@@ -771,6 +771,9 @@ class Doc extends Model {
771
771
  childrenIds.observe(observeFn);
772
772
  }
773
773
  _proxyNode(node, yNode, yChildrenIds) {
774
+ if (node.internalMode !== "default") {
775
+ return;
776
+ }
774
777
  const id = node.id;
775
778
  if (!yNode) {
776
779
  yNode = this._yChildren.get(id);
@@ -839,7 +842,6 @@ class Doc extends Model {
839
842
  }
840
843
  this._proxyChildren(node, yChildrenIds);
841
844
  }
842
- return yNode;
843
845
  }
844
846
  _initYNode(yNode) {
845
847
  const id = yNode.get("id");
@@ -2245,6 +2247,13 @@ const _4_1_text = defineMixin((editor) => {
2245
2247
  elementSelection,
2246
2248
  textSelection
2247
2249
  } = editor;
2250
+ const element = computed(() => elementSelection.value[0]);
2251
+ const hasTextSelectionRange = computed(() => {
2252
+ return (textSelection.value?.length ?? 0) > 1 && textSelection.value[0] !== textSelection.value[1];
2253
+ });
2254
+ const isTextAllSelected = computed(() => {
2255
+ return textSelection.value?.[0].isFirst && textSelection.value?.[1].isLast && textSelection.value?.[1].isLastSelected;
2256
+ });
2248
2257
  function textFontSizeToFit(element2, scale) {
2249
2258
  function _handle(element3) {
2250
2259
  if (!scale) {
@@ -2320,13 +2329,22 @@ const _4_1_text = defineMixin((editor) => {
2320
2329
  if (!element3.text?.isValid?.() || typeof element3.text?.content !== "object") {
2321
2330
  return;
2322
2331
  }
2332
+ const isVertical = element3.text.base.isVertical;
2323
2333
  const style = element3.style.toJSON();
2324
2334
  switch (strategy) {
2325
2335
  case "autoWidth":
2326
- style.width = "auto";
2336
+ if (isVertical) {
2337
+ style.height = "auto";
2338
+ } else {
2339
+ style.width = "auto";
2340
+ }
2327
2341
  break;
2328
2342
  case "autoHeight":
2329
- style.height = "auto";
2343
+ if (isVertical) {
2344
+ style.width = "auto";
2345
+ } else {
2346
+ style.height = "auto";
2347
+ }
2330
2348
  break;
2331
2349
  }
2332
2350
  const { boundingBox } = measureText({
@@ -2347,10 +2365,6 @@ const _4_1_text = defineMixin((editor) => {
2347
2365
  return false;
2348
2366
  });
2349
2367
  }
2350
- const element = computed(() => elementSelection.value[0]);
2351
- const hasSelectionRange = computed(() => {
2352
- return (textSelection.value?.length ?? 0) > 1 && textSelection.value[0] !== textSelection.value[1];
2353
- });
2354
2368
  function handleSelection([start, end], cb) {
2355
2369
  let flag = true;
2356
2370
  element.value?.text?.content.forEach((p, pIndex, pItems) => {
@@ -2379,12 +2393,13 @@ const _4_1_text = defineMixin((editor) => {
2379
2393
  });
2380
2394
  }
2381
2395
  function getTextStyle(key) {
2382
- if (!element.value) {
2396
+ const el = element.value;
2397
+ if (!el) {
2383
2398
  return void 0;
2384
2399
  }
2385
- let value = element.value.style[key];
2386
- const content = element.value.text.content;
2387
- if (hasSelectionRange.value) {
2400
+ let value = el.style[key];
2401
+ const content = el.text.content;
2402
+ if (hasTextSelectionRange.value) {
2388
2403
  const selection = textSelection.value;
2389
2404
  if (selection && selection[0] && selection[1]) {
2390
2405
  handleSelection(selection, ({ selected, fStyle }) => {
@@ -2411,109 +2426,121 @@ const _4_1_text = defineMixin((editor) => {
2411
2426
  }
2412
2427
  return value;
2413
2428
  }
2414
- function setTextStyle(key, value) {
2415
- if (!element.value) {
2429
+ function setTextContentByEachFragment(handler) {
2430
+ const el = element.value;
2431
+ if (!el) {
2416
2432
  return;
2417
2433
  }
2418
- let isAllSelected = false;
2419
- if (hasSelectionRange.value) {
2420
- const selection = textSelection.value;
2421
- if (selection && selection[0] && selection[1]) {
2422
- if (selection[0].isFirst && selection[1].isLast && selection[1].isLastSelected) {
2423
- isAllSelected = true;
2434
+ const newContent = [];
2435
+ let newParagraph = { fragments: [] };
2436
+ let newFragment;
2437
+ handleSelection(textSelection.value, ({ selected, fIndex, fStyle, fLength, c, cIndex, cLength }) => {
2438
+ if (fIndex === 0 && cIndex === 0) {
2439
+ newParagraph = { fragments: [] };
2440
+ newFragment = void 0;
2441
+ }
2442
+ const style = { ...fStyle };
2443
+ if (selected) {
2444
+ handler(style);
2445
+ }
2446
+ if (newFragment) {
2447
+ const { content: _, ..._style } = newFragment;
2448
+ if (isEqualObject(style, _style)) {
2449
+ newFragment.content += c;
2424
2450
  } else {
2425
- const newContent = [];
2426
- let newParagraph = { fragments: [] };
2427
- let newFragment;
2428
- handleSelection(selection, ({ selected, fIndex, fStyle, fLength, c, cIndex, cLength }) => {
2429
- if (fIndex === 0 && cIndex === 0) {
2430
- newParagraph = { fragments: [] };
2431
- newFragment = void 0;
2432
- }
2433
- const style = { ...fStyle };
2434
- if (selected) {
2435
- style[key] = value;
2436
- }
2437
- if (newFragment) {
2438
- const { content: _, ..._style } = newFragment;
2439
- if (isEqualObject(style, _style)) {
2440
- newFragment.content += c;
2441
- } else {
2442
- newParagraph.fragments.push(newFragment);
2443
- newFragment = { ...style, content: c };
2444
- }
2445
- } else {
2446
- newFragment = { ...style, content: c };
2447
- }
2448
- if (fIndex === fLength - 1 && cIndex === cLength - 1) {
2449
- if (newFragment) {
2450
- newParagraph.fragments.push(newFragment);
2451
- }
2452
- if (newParagraph.fragments.length) {
2453
- newContent.push(newParagraph);
2454
- newParagraph = { fragments: [] };
2455
- }
2456
- }
2457
- return true;
2458
- });
2459
- if (newContent.length) {
2460
- element.value.text.content = newContent;
2461
- }
2451
+ newParagraph.fragments.push(newFragment);
2452
+ newFragment = { ...style, content: c };
2453
+ }
2454
+ } else {
2455
+ newFragment = { ...style, content: c };
2456
+ }
2457
+ if (fIndex === fLength - 1 && cIndex === cLength - 1) {
2458
+ if (newFragment) {
2459
+ newParagraph.fragments.push(newFragment);
2460
+ }
2461
+ if (newParagraph.fragments.length) {
2462
+ newContent.push(newParagraph);
2463
+ newParagraph = { fragments: [] };
2462
2464
  }
2463
2465
  }
2464
- } else {
2465
- isAllSelected = true;
2466
+ return true;
2467
+ });
2468
+ if (newContent.length) {
2469
+ el.text = { ...el.text.toJSON(), content: newContent };
2466
2470
  }
2467
- if (isAllSelected) {
2468
- const el = element.value;
2469
- switch (key) {
2470
- case "fill":
2471
- case "outline":
2472
- el.text[key] = value;
2473
- break;
2474
- default:
2471
+ }
2472
+ function setTextStyle(key, value) {
2473
+ const el = element.value;
2474
+ if (!el) {
2475
+ return;
2476
+ }
2477
+ switch (key) {
2478
+ case "writingMode": {
2479
+ if (el.style[key] !== value) {
2480
+ const { width, height } = el.style;
2481
+ el.style.width = height;
2482
+ el.style.height = width;
2475
2483
  el.style[key] = value;
2476
- break;
2484
+ }
2485
+ break;
2486
+ }
2487
+ default: {
2488
+ if (hasTextSelectionRange.value && !isTextAllSelected.value) {
2489
+ setTextContentByEachFragment((fragment) => {
2490
+ fragment[key] = value;
2491
+ });
2492
+ } else {
2493
+ switch (key) {
2494
+ case "fill":
2495
+ case "outline":
2496
+ el.text[key] = value;
2497
+ break;
2498
+ default:
2499
+ el.style[key] = value;
2500
+ break;
2501
+ }
2502
+ el.text.content.forEach((p) => {
2503
+ delete p[key];
2504
+ p.fragments.forEach((f) => {
2505
+ delete f[key];
2506
+ });
2507
+ });
2508
+ el.text = el.text.toJSON();
2509
+ }
2510
+ el.requestDraw();
2511
+ textToFit(el);
2512
+ break;
2477
2513
  }
2478
- const content = element.value.text.content;
2479
- content.forEach((p) => {
2480
- delete p[key];
2481
- p.fragments.forEach((f) => {
2482
- delete f[key];
2483
- });
2484
- });
2485
- el.text.content = content;
2486
2514
  }
2487
- element.value.requestRender();
2488
- textToFit(element.value);
2489
2515
  }
2490
2516
  function getTextFill() {
2491
- if (!element.value) {
2517
+ const el = element.value;
2518
+ if (!el) {
2492
2519
  return void 0;
2493
2520
  }
2494
2521
  let fill;
2495
- if (hasSelectionRange.value) {
2522
+ if (hasTextSelectionRange.value) {
2496
2523
  fill = getTextStyle("fill");
2497
2524
  if (!fill) {
2498
- const color = getTextStyle("color");
2499
- fill = { color };
2525
+ fill = { color: getTextStyle("color") };
2500
2526
  }
2501
2527
  }
2502
- fill = fill ?? element.value.text.fill ?? { color: element.value.style.color };
2528
+ fill = fill ?? el.text.fill ?? { color: el.style.color };
2503
2529
  return fill;
2504
2530
  }
2505
2531
  function setTextFill(value) {
2506
- if (!element.value) {
2507
- return;
2532
+ const el = element.value;
2533
+ if (!el) {
2534
+ return void 0;
2508
2535
  }
2509
- if (hasSelectionRange.value && value?.color) {
2536
+ if (hasTextSelectionRange.value && value?.color) {
2510
2537
  setTextStyle("fill", value);
2511
2538
  } else {
2512
- element.value.text.fill = value;
2539
+ el.text.fill = value;
2513
2540
  if (value?.color) {
2514
- element.value.style.color = value.color;
2541
+ el.style.color = value.color;
2515
2542
  }
2516
- element.value.text.content.forEach((p) => {
2543
+ el.text.content.forEach((p) => {
2517
2544
  delete p.fill;
2518
2545
  delete p.color;
2519
2546
  p.fragments.forEach((f) => {
@@ -2521,15 +2548,23 @@ const _4_1_text = defineMixin((editor) => {
2521
2548
  delete f.color;
2522
2549
  });
2523
2550
  });
2551
+ el.text = {
2552
+ ...el.text.toJSON(),
2553
+ fill: value
2554
+ };
2555
+ el.requestDraw();
2524
2556
  }
2525
2557
  }
2526
2558
  Object.assign(editor, {
2559
+ hasTextSelectionRange,
2560
+ isTextAllSelected,
2527
2561
  textFontSizeToFit,
2528
2562
  textToFit,
2529
2563
  setTextStyle,
2530
2564
  getTextStyle,
2531
2565
  getTextFill,
2532
- setTextFill
2566
+ setTextFill,
2567
+ setTextContentByEachFragment
2533
2568
  });
2534
2569
  return () => {
2535
2570
  TextEditor.register();
@@ -3800,7 +3835,7 @@ function useIcon(props) {
3800
3835
  }
3801
3836
  const MceLayerKey = /* @__PURE__ */ Symbol.for("mce:layer");
3802
3837
  const MceLayerItemKey = /* @__PURE__ */ Symbol.for("mce:layer-item");
3803
- function createLayer(options) {
3838
+ function createLayer() {
3804
3839
  const registered = ref([]);
3805
3840
  const nodeItems = /* @__PURE__ */ new Map();
3806
3841
  const openedItems = reactive(/* @__PURE__ */ new Map());
@@ -3819,7 +3854,6 @@ function createLayer(options) {
3819
3854
  return id;
3820
3855
  }
3821
3856
  provide(MceLayerKey, {
3822
- ...options,
3823
3857
  selecting,
3824
3858
  dragging,
3825
3859
  droppingItemId,
@@ -5093,7 +5127,6 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5093
5127
  const dom = ref();
5094
5128
  const {
5095
5129
  selecting,
5096
- sortedSelection,
5097
5130
  dragging,
5098
5131
  dropping,
5099
5132
  onMousedown,
@@ -5103,17 +5136,6 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5103
5136
  node: computed(() => props.node),
5104
5137
  dom: computed(() => dom.value)
5105
5138
  });
5106
- const isFrist = computed(() => sortedSelection.value[0]?.equal(props.node));
5107
- const isLast = computed(() => {
5108
- const last = sortedSelection.value[sortedSelection.value.length - 1];
5109
- if (last) {
5110
- if (last.equal(props.node)) {
5111
- if (!opened.value || !props.node?.children.length)
5112
- return true;
5113
- } else if (last.equal(props.node?.parent)) ;
5114
- }
5115
- return false;
5116
- });
5117
5139
  const isActive = computed(() => selection.value.some((v) => v.equal(props.node)));
5118
5140
  const children = computed(() => props.node.children);
5119
5141
  const childrenLength = computed(() => children.value.length);
@@ -5160,6 +5182,9 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5160
5182
  opened.value = !opened.value;
5161
5183
  }
5162
5184
  function onMousedownContent(e) {
5185
+ if (e.button === 2) {
5186
+ return;
5187
+ }
5163
5188
  selecting.value = true;
5164
5189
  if (e.shiftKey) {
5165
5190
  const _nodes = [
@@ -5257,8 +5282,6 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5257
5282
  class: normalizeClass(["mce-layer", [
5258
5283
  props.root && "mce-layer--root",
5259
5284
  (__props.active || isActive.value) && "mce-layer--active",
5260
- isFrist.value && "mce-layer--first",
5261
- isLast.value && "mce-layer--last",
5262
5285
  opened.value && "mce-layer--open",
5263
5286
  isHoverElement.value && "mce-layer--hover",
5264
5287
  unref(dropping) && "mce-layer--dropping"
@@ -5272,8 +5295,8 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5272
5295
  onMouseleave,
5273
5296
  onContextmenu
5274
5297
  }, [
5275
- _cache[5] || (_cache[5] = createElementVNode("span", { class: "mce-layer__underlay" }, null, -1)),
5276
- _cache[6] || (_cache[6] = createElementVNode("span", { class: "mce-layer__overlay" }, null, -1)),
5298
+ _cache[4] || (_cache[4] = createElementVNode("span", { class: "mce-layer__underlay" }, null, -1)),
5299
+ _cache[5] || (_cache[5] = createElementVNode("span", { class: "mce-layer__overlay" }, null, -1)),
5277
5300
  createElementVNode("div", _hoisted_2$c, [
5278
5301
  createElementVNode("div", _hoisted_3$b, [
5279
5302
  childrenLength.value ? (openBlock(), createBlock(unref(_sfc_main$C), {
@@ -5300,6 +5323,9 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5300
5323
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => editValue.value = $event),
5301
5324
  type: "text",
5302
5325
  class: "mce-layer__input",
5326
+ spellcheck: "false",
5327
+ autocapitalize: "off",
5328
+ autocorrect: "off",
5303
5329
  autofocus: "",
5304
5330
  onBlur: onInputBlur
5305
5331
  }, null, 544), [
@@ -5312,26 +5338,17 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5312
5338
  ], 32),
5313
5339
  createElementVNode("div", {
5314
5340
  class: normalizeClass(["mce-layer__action", {
5315
- "mce-layer__action--hide": !hovering.value && !unref(isLock)(props.node) && unref(isVisible)(props.node)
5341
+ "mce-layer__action--hover": hovering.value,
5342
+ "mce-layer__action--show": hovering.value || unref(isLock)(props.node) || !unref(isVisible)(props.node)
5316
5343
  }])
5317
5344
  }, [
5318
- props.root ? (openBlock(), createBlock(_sfc_main$y, {
5319
- key: 0,
5320
- icon: "",
5321
- class: "mce-layer__btn",
5322
- onClick: _cache[2] || (_cache[2] = ($event) => unref(setLock)(props.node, !unref(isLock)(props.node)))
5323
- }, {
5324
- default: withCtx(() => [
5325
- createVNode(unref(_sfc_main$C), {
5326
- icon: unref(isLock)(props.node) ? "$lock" : "$unlock"
5327
- }, null, 8, ["icon"])
5328
- ]),
5329
- _: 1
5330
- })) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
5345
+ props.root ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
5331
5346
  createVNode(_sfc_main$y, {
5332
5347
  icon: "",
5333
- class: "mce-layer__btn",
5334
- onClick: _cache[3] || (_cache[3] = withModifiers(($event) => unref(setLock)(props.node, !unref(isLock)(props.node)), ["prevent", "stop"]))
5348
+ class: normalizeClass(["mce-layer__btn", {
5349
+ "mce-layer__btn--show": unref(isLock)(props.node)
5350
+ }]),
5351
+ onClick: _cache[2] || (_cache[2] = withModifiers(($event) => unref(setLock)(props.node, !unref(isLock)(props.node)), ["prevent", "stop"]))
5335
5352
  }, {
5336
5353
  default: withCtx(() => [
5337
5354
  createVNode(unref(_sfc_main$C), {
@@ -5339,11 +5356,13 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5339
5356
  }, null, 8, ["icon"])
5340
5357
  ]),
5341
5358
  _: 1
5342
- }),
5359
+ }, 8, ["class"]),
5343
5360
  createVNode(_sfc_main$y, {
5344
5361
  icon: "",
5345
- class: "mce-layer__btn",
5346
- onClick: _cache[4] || (_cache[4] = withModifiers(($event) => unref(setVisible)(props.node, !unref(isVisible)(props.node)), ["prevent", "stop"]))
5362
+ class: normalizeClass(["mce-layer__btn", {
5363
+ "mce-layer__btn--show": !unref(isVisible)(props.node)
5364
+ }]),
5365
+ onClick: _cache[3] || (_cache[3] = withModifiers(($event) => unref(setVisible)(props.node, !unref(isVisible)(props.node)), ["prevent", "stop"]))
5347
5366
  }, {
5348
5367
  default: withCtx(() => [
5349
5368
  createVNode(unref(_sfc_main$C), {
@@ -5351,7 +5370,7 @@ const _sfc_main$x = /* @__PURE__ */ defineComponent({
5351
5370
  }, null, 8, ["icon"])
5352
5371
  ]),
5353
5372
  _: 1
5354
- })
5373
+ }, 8, ["class"])
5355
5374
  ], 64))
5356
5375
  ], 2)
5357
5376
  ])
@@ -5376,25 +5395,14 @@ const _sfc_main$w = /* @__PURE__ */ defineComponent({
5376
5395
  const {
5377
5396
  root,
5378
5397
  selection,
5379
- state,
5380
- nodeIndexMap
5398
+ state
5381
5399
  } = useEditor();
5382
- const sortedSelection = computed(() => {
5383
- return selection.value.map((node) => {
5384
- return {
5385
- node,
5386
- index: nodeIndexMap.get(node.id) ?? 0
5387
- };
5388
- }).sort((a, b) => a.index - b.index).map((v) => v.node);
5389
- });
5390
5400
  const {
5391
5401
  selecting,
5392
5402
  openedItems,
5393
5403
  domItems,
5394
5404
  getIdByNode
5395
- } = createLayer({
5396
- sortedSelection
5397
- });
5405
+ } = createLayer();
5398
5406
  watch(selection, (selection2) => {
5399
5407
  if (state.value === "selecting" || selecting.value) {
5400
5408
  return;
@@ -10485,6 +10493,23 @@ const _pen = definePlugin((editor) => {
10485
10493
  ]
10486
10494
  };
10487
10495
  });
10496
+ const _rotate = definePlugin((editor) => {
10497
+ const {
10498
+ elementSelection
10499
+ } = editor;
10500
+ function rotate(deg) {
10501
+ elementSelection.value.forEach((el) => {
10502
+ el.style.rotate += deg;
10503
+ });
10504
+ }
10505
+ return {
10506
+ name: "mce:rotate",
10507
+ commands: [
10508
+ { command: "rotate", handle: rotate },
10509
+ { command: "rotate90", handle: () => rotate(90) }
10510
+ ]
10511
+ };
10512
+ });
10488
10513
  const _hoisted_1$g = {
10489
10514
  key: 0,
10490
10515
  class: "mce-tooltip__arrow"
@@ -13588,6 +13613,7 @@ const plugins = [
13588
13613
  _open,
13589
13614
  _panels,
13590
13615
  _pen,
13616
+ _rotate,
13591
13617
  _ruler,
13592
13618
  _saveAs,
13593
13619
  _scroll,
@@ -1,5 +1,5 @@
1
1
  import type { Cursor, Vector2, Vector2Like } from 'modern-canvas';
2
- import type { IndexCharacter } from 'modern-text/web-components';
2
+ import type { IndexCharacter as _IndexCharacter } from 'modern-text/web-components';
3
3
  import type { ComputedRef, Ref } from 'vue';
4
4
  import { Aabb2D, Camera2D, DrawboardEffect, Element2D, Engine, Node, Timeline } from 'modern-canvas';
5
5
  import { Fonts } from 'modern-font';
@@ -19,6 +19,7 @@ declare global {
19
19
  side: 'left' | 'right';
20
20
  align: Tblock | 'center';
21
21
  };
22
+ type IndexCharacter = _IndexCharacter;
22
23
  interface Editor {
23
24
  fonts: Fonts;
24
25
  renderEngine: Ref<Engine>;
@@ -1,14 +1,18 @@
1
1
  import type { Element2D } from 'modern-canvas';
2
- import type { NormalizedFill } from 'modern-idoc';
2
+ import type { NormalizedFill, NormalizedFragment } from 'modern-idoc';
3
+ import type { Ref } from 'vue';
3
4
  declare global {
4
5
  namespace Mce {
5
6
  interface Editor {
7
+ hasTextSelectionRange: Ref<boolean>;
8
+ isTextAllSelected: Ref<boolean>;
6
9
  textFontSizeToFit: (element: Element2D, scale?: number) => void;
7
10
  textToFit: (element: Element2D, typography?: Mce.TypographyStrategy) => void;
8
11
  getTextStyle: (key: string) => any;
9
12
  setTextStyle: (key: string, value: any) => void;
10
13
  getTextFill: () => NormalizedFill | undefined;
11
14
  setTextFill: (value: NormalizedFill | undefined) => void;
15
+ setTextContentByEachFragment: (handler: (fragment: NormalizedFragment) => void) => void;
12
16
  }
13
17
  }
14
18
  }
@@ -0,0 +1,10 @@
1
+ declare global {
2
+ namespace Mce {
3
+ interface Commands {
4
+ rotate: (deg: number) => void;
5
+ rotate90: () => void;
6
+ }
7
+ }
8
+ }
9
+ declare const _default: import("..").Plugin;
10
+ export default _default;
@@ -53,6 +53,7 @@ import './plugins/node'
53
53
  import './plugins/open'
54
54
  import './plugins/panels'
55
55
  import './plugins/pen'
56
+ import './plugins/rotate'
56
57
  import './plugins/ruler'
57
58
  import './plugins/saveAs'
58
59
  import './plugins/scroll'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mce",
3
3
  "type": "module",
4
- "version": "0.15.7",
4
+ "version": "0.15.9",
5
5
  "description": "The headless canvas editor framework. only the ESM.",
6
6
  "author": "wxm",
7
7
  "license": "MIT",
@@ -61,10 +61,10 @@
61
61
  "diff": "^8.0.2",
62
62
  "file-saver": "^2.0.5",
63
63
  "lodash-es": "^4.17.22",
64
- "modern-canvas": "^0.14.22",
64
+ "modern-canvas": "^0.14.24",
65
65
  "modern-font": "^0.4.4",
66
66
  "modern-idoc": "^0.10.8",
67
- "modern-text": "^1.10.6",
67
+ "modern-text": "^1.10.7",
68
68
  "yjs": "^13.6.28"
69
69
  },
70
70
  "peerDependencies": {