mce 0.15.37 → 0.15.38

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
@@ -55,9 +55,9 @@
55
55
  transform-origin: left bottom;
56
56
  font-size: 0.75rem;
57
57
  line-height: 1.5;
58
- white-space: nowrap;
59
58
  pointer-events: auto;
60
59
  user-select: none;
60
+ max-width: 100%;
61
61
  }
62
62
  .mce-frame__name > div {
63
63
  position: relative;
@@ -65,6 +65,10 @@
65
65
  box-sizing: content-box;
66
66
  color: rgb(var(--mce-theme-on-surface));
67
67
  opacity: 0.5;
68
+ max-width: 100%;
69
+ white-space: nowrap;
70
+ overflow: hidden;
71
+ text-overflow: ellipsis;
68
72
  }
69
73
  .mce-frame__name > input {
70
74
  position: absolute;
@@ -755,13 +759,15 @@
755
759
  border-style: dashed;
756
760
  color: rgba(var(--mce-theme-primary), 1);
757
761
  opacity: 0.5;
762
+ border-color: currentColor;
758
763
  }
759
- .mce-selection__area {
764
+ .mce-selection__marquee {
760
765
  position: absolute;
761
766
  border-width: 1px;
762
767
  border-style: solid;
763
768
  color: rgba(var(--mce-theme-primary), 1);
764
769
  background-color: rgba(var(--mce-theme-primary), 0.1);
770
+ border-color: currentcolor;
765
771
  }
766
772
  .mce-selection__transform {
767
773
  position: absolute;
@@ -772,6 +778,7 @@
772
778
  border-width: 1px;
773
779
  border-style: solid;
774
780
  color: rgba(var(--mce-theme-primary), 1);
781
+ border-color: currentcolor;
775
782
  }.mce-smart-guides {
776
783
  position: absolute;
777
784
  overflow: hidden;
package/dist/index.js CHANGED
@@ -895,7 +895,7 @@ const _0_context = defineMixin((editor) => {
895
895
  const nodes = ref([]);
896
896
  const nodeIndexMap = reactive(/* @__PURE__ */ new Map());
897
897
  const selection = ref([]);
898
- const selectionArea = ref(new Aabb2D());
898
+ const selectionMarquee = ref(new Aabb2D());
899
899
  const elementSelection = computed({
900
900
  get: () => selection.value.filter((v) => isElement(v)),
901
901
  set: (val) => selection.value = val
@@ -973,7 +973,7 @@ const _0_context = defineMixin((editor) => {
973
973
  nodes,
974
974
  nodeIndexMap,
975
975
  selection,
976
- selectionArea,
976
+ selectionMarquee,
977
977
  elementSelection,
978
978
  textSelection,
979
979
  hoverElement,
@@ -1725,7 +1725,7 @@ function parseKey(key) {
1725
1725
  default:
1726
1726
  return String.fromCharCode(getCharCode(v));
1727
1727
  }
1728
- }).filter(Boolean).map((v) => v.toLowerCase()).sort().join("+");
1728
+ }).filter(Boolean).sort().join("+");
1729
1729
  }
1730
1730
  function parseKeyboardEvent(event) {
1731
1731
  if (event.key.toLowerCase() === "capslock") {
@@ -1741,7 +1741,7 @@ function parseKeyboardEvent(event) {
1741
1741
  event.altKey && "Alt",
1742
1742
  event.shiftKey && "Shift",
1743
1743
  !["Meta", "Control", "Alt", "Shift"].includes(event.key) && String.fromCharCode(key)
1744
- ].filter(Boolean).map((v) => v.toLowerCase()).sort().join("+");
1744
+ ].filter(Boolean).sort().join("+");
1745
1745
  }
1746
1746
  const _1_hotkey = defineMixin((editor) => {
1747
1747
  const {
@@ -3167,17 +3167,16 @@ const _4_1_text = defineMixin((editor) => {
3167
3167
  textSelection,
3168
3168
  fonts
3169
3169
  } = editor;
3170
- const element = computed(() => elementSelection.value[0]);
3171
3170
  const hasTextSelectionRange = computed(() => {
3172
3171
  return (textSelection.value?.length ?? 0) > 1 && textSelection.value[0] !== textSelection.value[1];
3173
3172
  });
3174
3173
  const isTextAllSelected = computed(() => {
3175
3174
  return textSelection.value?.[0].isFirst && textSelection.value?.[1].isLast && textSelection.value?.[1].isLastSelected;
3176
3175
  });
3177
- function textFontSizeToFit(element2, scale) {
3178
- function _handle(element3) {
3176
+ function textFontSizeToFit(element, scale) {
3177
+ function _handle(element2) {
3179
3178
  if (!scale) {
3180
- const chars = element3.text.base.characters;
3179
+ const chars = element2.text.base.characters;
3181
3180
  let pos = 0;
3182
3181
  let char;
3183
3182
  chars.forEach((_char) => {
@@ -3199,7 +3198,7 @@ const _4_1_text = defineMixin((editor) => {
3199
3198
  const { boundingBox } = measureText({
3200
3199
  fonts,
3201
3200
  style: {
3202
- ...element3.style.toJSON(),
3201
+ ...element2.style.toJSON(),
3203
3202
  width: "auto"
3204
3203
  },
3205
3204
  content: [
@@ -3210,8 +3209,8 @@ const _4_1_text = defineMixin((editor) => {
3210
3209
  }
3211
3210
  ]
3212
3211
  });
3213
- const fontSize = (element3.style.fontSize || 12) / 2;
3214
- scale = (element3.style.width ?? 0) / (boundingBox.width + fontSize);
3212
+ const fontSize = (element2.style.fontSize || 12) / 2;
3213
+ scale = (element2.style.width ?? 0) / (boundingBox.width + fontSize);
3215
3214
  }
3216
3215
  function _scaleStyle(style) {
3217
3216
  if (style.fontSize)
@@ -3219,39 +3218,39 @@ const _4_1_text = defineMixin((editor) => {
3219
3218
  if (style.letterSpacing)
3220
3219
  style.letterSpacing = style.letterSpacing * scale;
3221
3220
  }
3222
- _scaleStyle(element3.style);
3223
- if (element3.text?.isValid?.() && Array.isArray(element3.text?.content)) {
3224
- element3.text.content.forEach((p) => {
3221
+ _scaleStyle(element2.style);
3222
+ if (element2.text?.isValid?.() && Array.isArray(element2.text?.content)) {
3223
+ element2.text.content.forEach((p) => {
3225
3224
  _scaleStyle(p);
3226
3225
  p.fragments.forEach((f) => {
3227
3226
  _scaleStyle(f);
3228
3227
  });
3229
3228
  });
3230
3229
  }
3231
- element3.requestRender();
3230
+ element2.requestRender();
3232
3231
  }
3233
- _handle(element2);
3234
- element2.findOne((descendant) => {
3232
+ _handle(element);
3233
+ element.findOne((descendant) => {
3235
3234
  if (isElement(descendant)) {
3236
3235
  _handle(descendant);
3237
3236
  }
3238
3237
  return false;
3239
3238
  });
3240
3239
  }
3241
- function textToFit(element2, typography) {
3240
+ function textToFit(element, typography) {
3242
3241
  const strategy = typography ?? config.value.typographyStrategy;
3243
3242
  if (strategy === "fixedWidthHeight") {
3244
3243
  return;
3245
3244
  } else if (strategy === "autoFontSize") {
3246
- textFontSizeToFit(element2);
3245
+ textFontSizeToFit(element);
3247
3246
  return;
3248
3247
  }
3249
- function _handle(element3) {
3250
- if (!element3.text?.isValid?.() || typeof element3.text?.content !== "object") {
3248
+ function _handle(element2) {
3249
+ if (!element2.text?.isValid?.() || typeof element2.text?.content !== "object") {
3251
3250
  return;
3252
3251
  }
3253
- const isVertical = element3.text.base.isVertical;
3254
- const style = element3.style.toJSON();
3252
+ const isVertical = element2.text.base.isVertical;
3253
+ const style = element2.style.toJSON();
3255
3254
  switch (strategy) {
3256
3255
  case "autoWidth":
3257
3256
  if (isVertical) {
@@ -3271,16 +3270,16 @@ const _4_1_text = defineMixin((editor) => {
3271
3270
  const { boundingBox } = measureText({
3272
3271
  fonts,
3273
3272
  style,
3274
- content: element3.text.content
3273
+ content: element2.text.content
3275
3274
  });
3276
- if (element3.style.width !== boundingBox.width || element3.style.height !== boundingBox.height) {
3277
- element3.style.width = boundingBox.width;
3278
- element3.style.height = boundingBox.height;
3279
- element3.requestRender();
3275
+ if (element2.style.width !== boundingBox.width || element2.style.height !== boundingBox.height) {
3276
+ element2.style.width = boundingBox.width;
3277
+ element2.style.height = boundingBox.height;
3278
+ element2.requestRender();
3280
3279
  }
3281
3280
  }
3282
- _handle(element2);
3283
- element2.findOne((descendant) => {
3281
+ _handle(element);
3282
+ element.findOne((descendant) => {
3284
3283
  if (isElement(descendant)) {
3285
3284
  _handle(descendant);
3286
3285
  }
@@ -3289,7 +3288,7 @@ const _4_1_text = defineMixin((editor) => {
3289
3288
  }
3290
3289
  function handleTextSelection([start, end], cb) {
3291
3290
  let flag = true;
3292
- element.value?.text?.content.forEach((p, pIndex, pItems) => {
3291
+ elementSelection.value[0]?.text?.content.forEach((p, pIndex, pItems) => {
3293
3292
  if (!flag)
3294
3293
  return;
3295
3294
  p.fragments.forEach((f, fIndex, fItems) => {
@@ -3315,13 +3314,21 @@ const _4_1_text = defineMixin((editor) => {
3315
3314
  });
3316
3315
  }
3317
3316
  function getTextStyle(key) {
3318
- const el = element.value;
3317
+ const el = elementSelection.value[0];
3319
3318
  if (!el) {
3320
3319
  return void 0;
3321
3320
  }
3322
- let value = el.style[key];
3323
- const content = el.text.content;
3324
- if (hasTextSelectionRange.value) {
3321
+ let value;
3322
+ switch (key) {
3323
+ case "fill":
3324
+ case "outline":
3325
+ value = el.text[key];
3326
+ break;
3327
+ default:
3328
+ value = el.style[key];
3329
+ break;
3330
+ }
3331
+ if (hasTextSelectionRange.value && !isTextAllSelected.value) {
3325
3332
  const selection = textSelection.value;
3326
3333
  if (selection && selection[0] && selection[1]) {
3327
3334
  handleTextSelection(selection, ({ selected, fStyle }) => {
@@ -3333,6 +3340,7 @@ const _4_1_text = defineMixin((editor) => {
3333
3340
  });
3334
3341
  }
3335
3342
  } else {
3343
+ const content = el.text.content;
3336
3344
  switch (key) {
3337
3345
  case "fontSize":
3338
3346
  return content?.reduce((prev, p) => {
@@ -3349,7 +3357,7 @@ const _4_1_text = defineMixin((editor) => {
3349
3357
  return value;
3350
3358
  }
3351
3359
  function setTextContentByEachFragment(handler) {
3352
- const el = element.value;
3360
+ const el = elementSelection.value[0];
3353
3361
  if (!el) {
3354
3362
  return;
3355
3363
  }
@@ -3392,7 +3400,7 @@ const _4_1_text = defineMixin((editor) => {
3392
3400
  }
3393
3401
  }
3394
3402
  function setTextStyle(key, value) {
3395
- const el = element.value;
3403
+ const el = elementSelection.value[0];
3396
3404
  if (!el) {
3397
3405
  return;
3398
3406
  }
@@ -3436,7 +3444,7 @@ const _4_1_text = defineMixin((editor) => {
3436
3444
  }
3437
3445
  }
3438
3446
  function getTextFill() {
3439
- const el = element.value;
3447
+ const el = elementSelection.value[0];
3440
3448
  if (!el) {
3441
3449
  return void 0;
3442
3450
  }
@@ -3451,7 +3459,7 @@ const _4_1_text = defineMixin((editor) => {
3451
3459
  return fill;
3452
3460
  }
3453
3461
  function setTextFill(value) {
3454
- const el = element.value;
3462
+ const el = elementSelection.value[0];
3455
3463
  if (!el) {
3456
3464
  return void 0;
3457
3465
  }
@@ -3536,11 +3544,7 @@ const _4_3_element = defineMixin((editor) => {
3536
3544
  textFontSizeToFit,
3537
3545
  textToFit,
3538
3546
  log,
3539
- root,
3540
3547
  isElement,
3541
- inEditorIs,
3542
- isLock,
3543
- getObb,
3544
3548
  config,
3545
3549
  getAabb,
3546
3550
  getGlobalPointer,
@@ -3735,24 +3739,10 @@ const _4_3_element = defineMixin((editor) => {
3735
3739
  options.textToFit && textToFit(el);
3736
3740
  options.textFontSizeToFit && textFontSizeToFit(el, scaleX);
3737
3741
  }
3738
- function selectArea(areaInDrawboard) {
3739
- const area2 = new Obb2D(areaInDrawboard);
3740
- const selected = root.value?.children.flatMap((node) => {
3741
- if (inEditorIs(node, "Frame") && node.parent?.equal(root.value)) {
3742
- return node.children;
3743
- }
3744
- return [node];
3745
- }).filter((node) => {
3746
- return "isVisibleInTree" in node && node.isVisibleInTree() && getObb(node, "drawboard").overlap(area2) && !isLock(node) && !node.findAncestor((ancestor) => isLock(ancestor));
3747
- }) ?? [];
3748
- selection.value = selected;
3749
- return selected;
3750
- }
3751
3742
  Object.assign(editor, {
3752
3743
  addElement,
3753
3744
  addElements: addElement,
3754
- resizeElement,
3755
- selectArea
3745
+ resizeElement
3756
3746
  });
3757
3747
  });
3758
3748
  const _4_4_doc = defineMixin((editor, options) => {
@@ -13067,7 +13057,7 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
13067
13057
  state,
13068
13058
  resizeElement,
13069
13059
  selection,
13070
- selectionArea,
13060
+ selectionMarquee,
13071
13061
  elementSelection,
13072
13062
  selectionObb,
13073
13063
  selectionObbInDrawboard,
@@ -13296,29 +13286,20 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
13296
13286
  return openBlock(), createElementBlock("div", {
13297
13287
  key: index,
13298
13288
  class: "mce-selection__parent",
13299
- style: normalizeStyle$1({
13300
- borderColor: "currentColor",
13301
- ...style
13302
- })
13289
+ style: normalizeStyle$1(style)
13303
13290
  }, null, 4);
13304
13291
  }), 128)),
13305
13292
  unref(state) !== "transforming" ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(selectionObbStyles.value, (style, index) => {
13306
13293
  return openBlock(), createElementBlock("div", {
13307
13294
  key: index,
13308
13295
  class: "mce-selection__node",
13309
- style: normalizeStyle$1({
13310
- borderColor: "currentcolor",
13311
- ...style
13312
- })
13296
+ style: normalizeStyle$1(style)
13313
13297
  }, null, 4);
13314
13298
  }), 128)) : createCommentVNode("", true),
13315
13299
  unref(state) === "selecting" ? (openBlock(), createElementBlock("div", {
13316
13300
  key: 1,
13317
- class: "mce-selection__area",
13318
- style: normalizeStyle$1({
13319
- borderColor: "currentcolor",
13320
- ...unref(selectionArea).toCssStyle()
13321
- })
13301
+ class: "mce-selection__marquee",
13302
+ style: normalizeStyle$1(unref(selectionMarquee).toCssStyle())
13322
13303
  }, null, 4)) : createCommentVNode("", true),
13323
13304
  transform.value.width && transform.value.height ? (openBlock(), createBlock(_sfc_main$l, mergeProps({
13324
13305
  key: 2,
@@ -13363,6 +13344,7 @@ const _selection = definePlugin((editor) => {
13363
13344
  const {
13364
13345
  isElement,
13365
13346
  selection,
13347
+ selectionMarquee,
13366
13348
  elementSelection,
13367
13349
  getObb,
13368
13350
  getAabb,
@@ -13370,6 +13352,7 @@ const _selection = definePlugin((editor) => {
13370
13352
  root,
13371
13353
  findSibling,
13372
13354
  inEditorIs,
13355
+ isTopFrame,
13373
13356
  addElement,
13374
13357
  addElements,
13375
13358
  obbToFit,
@@ -13406,9 +13389,9 @@ const _selection = definePlugin((editor) => {
13406
13389
  }
13407
13390
  case "previousSibling":
13408
13391
  case "nextSibling": {
13409
- const value = findSibling(target === "previousSibling" ? "previous" : "next");
13410
- if (value) {
13411
- selection.value = [value];
13392
+ const sibling = findSibling(target === "previousSibling" ? "previous" : "next");
13393
+ if (sibling) {
13394
+ selection.value = [sibling];
13412
13395
  exec("zoomTo", "selection", {
13413
13396
  intoView: true,
13414
13397
  behavior: "smooth"
@@ -13421,6 +13404,17 @@ const _selection = definePlugin((editor) => {
13421
13404
  break;
13422
13405
  }
13423
13406
  }
13407
+ function marqueeSelect(marquee = selectionMarquee.value) {
13408
+ const area2 = new Obb2D(marquee);
13409
+ selection.value = root.value?.children.flatMap((node) => {
13410
+ if (isTopFrame(node) && !area2.contains(getObb(node, "drawboard"))) {
13411
+ return node.children;
13412
+ }
13413
+ return [node];
13414
+ }).filter((node) => {
13415
+ return "isVisibleInTree" in node && node.isVisibleInTree() && getObb(node, "drawboard").overlap(area2) && !isLock(node) && !node.findAncestor((ancestor) => isLock(ancestor));
13416
+ }) ?? [];
13417
+ }
13424
13418
  function groupSelection(inEditorIs2) {
13425
13419
  const elements = elementSelection.value;
13426
13420
  if (!elements.length) {
@@ -13514,6 +13508,7 @@ const _selection = definePlugin((editor) => {
13514
13508
  name: "mce:selection",
13515
13509
  commands: [
13516
13510
  { command: "select", handle: select },
13511
+ { command: "marqueeSelect", handle: marqueeSelect },
13517
13512
  { command: "selectAll", handle: () => select("all") },
13518
13513
  { command: "selectInverse", handle: () => select("inverse") },
13519
13514
  { command: "selectNone", handle: () => select("none") },
@@ -17076,12 +17071,11 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
17076
17071
  hoverElement,
17077
17072
  state,
17078
17073
  setCursor,
17079
- selectArea,
17080
17074
  exec,
17081
17075
  isLock,
17082
17076
  t,
17083
17077
  selectionAabbInDrawboard,
17084
- selectionArea,
17078
+ selectionMarquee,
17085
17079
  elementSelection,
17086
17080
  drawboardAabb,
17087
17081
  drawboardPointer,
@@ -17211,11 +17205,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
17211
17205
  if (state.value !== "selecting") {
17212
17206
  state.value = "selecting";
17213
17207
  }
17214
- selectionArea.value.x = Math.min(start.x, current.x) - drawboardAabb.value.left;
17215
- selectionArea.value.y = Math.min(start.y, current.y) - drawboardAabb.value.top;
17216
- selectionArea.value.width = Math.abs(start.x - current.x);
17217
- selectionArea.value.height = Math.abs(start.y - current.y);
17218
- selected = selectArea(selectionArea.value);
17208
+ selectionMarquee.value.x = Math.min(start.x, current.x) - drawboardAabb.value.left;
17209
+ selectionMarquee.value.y = Math.min(start.y, current.y) - drawboardAabb.value.top;
17210
+ selectionMarquee.value.width = Math.abs(start.x - current.x);
17211
+ selectionMarquee.value.height = Math.abs(start.y - current.y);
17212
+ exec("marqueeSelect");
17213
+ selected = elementSelection.value;
17219
17214
  }
17220
17215
  function onActivate() {
17221
17216
  const result = props.activeStrategy({
@@ -38,7 +38,7 @@ declare global {
38
38
  nodes: Ref<Node[]>;
39
39
  nodeIndexMap: Map<string, number>;
40
40
  selection: Ref<Node[]>;
41
- selectionArea: Ref<Aabb2D>;
41
+ selectionMarquee: Ref<Aabb2D>;
42
42
  elementSelection: Ref<Element2D[]>;
43
43
  textSelection: Ref<IndexCharacter[] | undefined>;
44
44
  hoverElement: Ref<Element2D | undefined>;
@@ -1,4 +1,4 @@
1
- import type { Aabb2D, Element2D, Node, Vector2Like } from 'modern-canvas';
1
+ import type { Element2D, Node, Vector2Like } from 'modern-canvas';
2
2
  import type { Element } from 'modern-idoc';
3
3
  declare global {
4
4
  namespace Mce {
@@ -20,7 +20,6 @@ declare global {
20
20
  addElement: (element: Element, options?: AddElementOptions) => Element2D;
21
21
  addElements: (element: Element[], options?: AddElementOptions) => Element2D[];
22
22
  resizeElement: (element: Element2D, newWidth: number, newHeight: number, options?: ResizeElementOptions) => void;
23
- selectArea: (areaInDrawboard: Aabb2D) => Element2D[];
24
23
  }
25
24
  }
26
25
  }
@@ -1,9 +1,10 @@
1
- import type { Element2D, Node } from 'modern-canvas';
1
+ import type { Aabb2D, Element2D, Node } from 'modern-canvas';
2
2
  declare global {
3
3
  namespace Mce {
4
4
  type SelectTarget = 'none' | 'all' | 'inverse' | 'children' | 'parent' | 'previousSibling' | 'nextSibling' | Node[];
5
5
  interface Commands {
6
6
  select: (target: SelectTarget) => void;
7
+ marqueeSelect: (marquee?: Aabb2D) => void;
7
8
  selectAll: () => void;
8
9
  selectInverse: () => void;
9
10
  selectNone: () => void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mce",
3
3
  "type": "module",
4
- "version": "0.15.37",
4
+ "version": "0.15.38",
5
5
  "description": "The headless canvas editor framework. only the ESM.",
6
6
  "author": "wxm",
7
7
  "license": "MIT",