mce 0.15.8 → 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.
- package/dist/crdt/Doc.d.ts +1 -1
- package/dist/index.js +127 -92
- package/dist/mixins/0.context.d.ts +2 -1
- package/dist/mixins/4.1.text.d.ts +5 -1
- package/package.json +2 -2
package/dist/crdt/Doc.d.ts
CHANGED
|
@@ -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>):
|
|
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.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
|
-
|
|
2336
|
+
if (isVertical) {
|
|
2337
|
+
style.height = "auto";
|
|
2338
|
+
} else {
|
|
2339
|
+
style.width = "auto";
|
|
2340
|
+
}
|
|
2327
2341
|
break;
|
|
2328
2342
|
case "autoHeight":
|
|
2329
|
-
|
|
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
|
-
|
|
2396
|
+
const el = element.value;
|
|
2397
|
+
if (!el) {
|
|
2383
2398
|
return void 0;
|
|
2384
2399
|
}
|
|
2385
|
-
let value =
|
|
2386
|
-
const content =
|
|
2387
|
-
if (
|
|
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
|
|
2415
|
-
|
|
2429
|
+
function setTextContentByEachFragment(handler) {
|
|
2430
|
+
const el = element.value;
|
|
2431
|
+
if (!el) {
|
|
2416
2432
|
return;
|
|
2417
2433
|
}
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
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
|
-
|
|
2426
|
-
|
|
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 };
|
|
2462
2453
|
}
|
|
2454
|
+
} else {
|
|
2455
|
+
newFragment = { ...style, content: c };
|
|
2463
2456
|
}
|
|
2464
|
-
|
|
2465
|
-
|
|
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: [] };
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
return true;
|
|
2467
|
+
});
|
|
2468
|
+
if (newContent.length) {
|
|
2469
|
+
el.text = { ...el.text.toJSON(), content: newContent };
|
|
2466
2470
|
}
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2517
|
+
const el = element.value;
|
|
2518
|
+
if (!el) {
|
|
2492
2519
|
return void 0;
|
|
2493
2520
|
}
|
|
2494
2521
|
let fill;
|
|
2495
|
-
if (
|
|
2522
|
+
if (hasTextSelectionRange.value) {
|
|
2496
2523
|
fill = getTextStyle("fill");
|
|
2497
2524
|
if (!fill) {
|
|
2498
|
-
|
|
2499
|
-
fill = { color };
|
|
2525
|
+
fill = { color: getTextStyle("color") };
|
|
2500
2526
|
}
|
|
2501
2527
|
}
|
|
2502
|
-
fill = fill ??
|
|
2528
|
+
fill = fill ?? el.text.fill ?? { color: el.style.color };
|
|
2503
2529
|
return fill;
|
|
2504
2530
|
}
|
|
2505
2531
|
function setTextFill(value) {
|
|
2506
|
-
|
|
2507
|
-
|
|
2532
|
+
const el = element.value;
|
|
2533
|
+
if (!el) {
|
|
2534
|
+
return void 0;
|
|
2508
2535
|
}
|
|
2509
|
-
if (
|
|
2536
|
+
if (hasTextSelectionRange.value && value?.color) {
|
|
2510
2537
|
setTextStyle("fill", value);
|
|
2511
2538
|
} else {
|
|
2512
|
-
|
|
2539
|
+
el.text.fill = value;
|
|
2513
2540
|
if (value?.color) {
|
|
2514
|
-
|
|
2541
|
+
el.style.color = value.color;
|
|
2515
2542
|
}
|
|
2516
|
-
|
|
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();
|
|
@@ -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
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mce",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.15.
|
|
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,7 +61,7 @@
|
|
|
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.
|
|
64
|
+
"modern-canvas": "^0.14.24",
|
|
65
65
|
"modern-font": "^0.4.4",
|
|
66
66
|
"modern-idoc": "^0.10.8",
|
|
67
67
|
"modern-text": "^1.10.7",
|