@windoc/react 0.3.23 → 0.3.24

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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/Editor.tsx
2
- import { useEffect as useEffect5, useRef as useRef19, useState as useState13 } from "react";
2
+ import { startTransition, useEffect as useEffect5, useRef as useRef19, useState as useState13 } from "react";
3
3
 
4
4
  // src/EditorContext.tsx
5
5
  import { createContext, useContext, useEffect, useState } from "react";
@@ -2350,6 +2350,49 @@ function EditorFooter() {
2350
2350
 
2351
2351
  // src/Editor.tsx
2352
2352
  import { jsx as jsx42, jsxs as jsxs25 } from "react/jsx-runtime";
2353
+ var CONTENT_SYNC_TIMEOUT = 300;
2354
+ function scheduleDeferredTask(callback) {
2355
+ const deferredWindow = window;
2356
+ if (deferredWindow.requestIdleCallback) {
2357
+ return deferredWindow.requestIdleCallback(
2358
+ () => {
2359
+ callback();
2360
+ },
2361
+ { timeout: CONTENT_SYNC_TIMEOUT }
2362
+ );
2363
+ }
2364
+ return window.setTimeout(callback, 0);
2365
+ }
2366
+ function cancelDeferredTask(handle) {
2367
+ if (handle === null) return;
2368
+ const deferredWindow = window;
2369
+ if (deferredWindow.cancelIdleCallback) {
2370
+ deferredWindow.cancelIdleCallback(handle);
2371
+ return;
2372
+ }
2373
+ window.clearTimeout(handle);
2374
+ }
2375
+ function isSameNumberArray(left, right) {
2376
+ if (left === right) return true;
2377
+ if (!left || !right || left.length !== right.length) return false;
2378
+ for (let i = 0; i < left.length; i++) {
2379
+ if (left[i] !== right[i]) return false;
2380
+ }
2381
+ return true;
2382
+ }
2383
+ function isSameStringArray(left, right) {
2384
+ if (left === right) return true;
2385
+ if (!left || !right || left.length !== right.length) return false;
2386
+ for (let i = 0; i < left.length; i++) {
2387
+ if (left[i] !== right[i]) return false;
2388
+ }
2389
+ return true;
2390
+ }
2391
+ function isSameRangeStyle(left, right) {
2392
+ if (left === right) return true;
2393
+ if (!left || !right) return false;
2394
+ return left.type === right.type && left.font === right.font && left.size === right.size && left.bold === right.bold && left.italic === right.italic && left.underline === right.underline && left.strikeout === right.strikeout && left.color === right.color && left.highlight === right.highlight && left.rowFlex === right.rowFlex && left.rowMargin === right.rowMargin && left.undo === right.undo && left.redo === right.redo && left.painter === right.painter && left.level === right.level && left.listType === right.listType && isSameNumberArray(left.dashArray, right.dashArray) && isSameStringArray(left.groupIds, right.groupIds);
2395
+ }
2353
2396
  function Editor({
2354
2397
  defaultValue,
2355
2398
  options: userOptions,
@@ -2403,6 +2446,9 @@ function EditorInner({
2403
2446
  const editorRef = useRef19(null);
2404
2447
  const [rangeStyle, setRangeStyle] = useState13(null);
2405
2448
  const [isInTable, setIsInTable] = useState13(false);
2449
+ const lastRangeStyleRef = useRef19(null);
2450
+ const deferredContentSyncRef = useRef19(null);
2451
+ const contentSyncVersionRef = useRef19(0);
2406
2452
  const {
2407
2453
  setPageNoList,
2408
2454
  setPageNo,
@@ -2432,11 +2478,10 @@ function EditorInner({
2432
2478
  } = await import("@windoc/core");
2433
2479
  if (cancelled) return;
2434
2480
  const data = defaultValue ?? { main: [] };
2435
- instance = new EditorClass(
2436
- containerRef.current,
2437
- data,
2438
- { maskMargin: [24, 0, 24, 0], ...userOptions }
2439
- );
2481
+ instance = new EditorClass(containerRef.current, data, {
2482
+ maskMargin: [24, 0, 24, 0],
2483
+ ...userOptions
2484
+ });
2440
2485
  editorRef.current = instance;
2441
2486
  const opts = instance.command.getOptions();
2442
2487
  setPageScale(Math.round(opts.scale * 100));
@@ -2444,40 +2489,67 @@ function EditorInner({
2444
2489
  setPaperWidth(opts.width);
2445
2490
  setPaperHeight(opts.height);
2446
2491
  instance.listener.rangeStyleChange = (payload) => {
2447
- setRangeStyle(payload);
2492
+ if (!isSameRangeStyle(lastRangeStyleRef.current, payload)) {
2493
+ lastRangeStyleRef.current = payload;
2494
+ startTransition(() => {
2495
+ setRangeStyle(payload);
2496
+ });
2497
+ }
2448
2498
  onRangeStyleChange?.(payload);
2449
2499
  const rangeContext = instance?.command.getRangeContext();
2450
- setIsInTable(rangeContext?.isTable === true);
2451
- if (rangeContext) {
2452
- setRowNo(rangeContext.startRowNo + 1);
2453
- setColNo(rangeContext.startColNo + 1);
2454
- }
2500
+ startTransition(() => {
2501
+ setIsInTable(rangeContext?.isTable === true);
2502
+ if (rangeContext) {
2503
+ setRowNo(rangeContext.startRowNo + 1);
2504
+ setColNo(rangeContext.startColNo + 1);
2505
+ }
2506
+ });
2455
2507
  };
2456
2508
  instance.listener.visiblePageNoListChange = (payload) => {
2457
- setPageNoList(payload.map((i) => i + 1).join(", "));
2509
+ startTransition(() => {
2510
+ setPageNoList(payload.map((i) => i + 1).join(", "));
2511
+ });
2458
2512
  };
2459
2513
  instance.listener.pageSizeChange = (payload) => {
2460
- setPageSize(payload);
2514
+ startTransition(() => {
2515
+ setPageSize(payload);
2516
+ });
2461
2517
  };
2462
2518
  instance.listener.intersectionPageNoChange = (payload) => {
2463
- setPageNo(payload + 1);
2519
+ startTransition(() => {
2520
+ setPageNo(payload + 1);
2521
+ });
2464
2522
  };
2465
2523
  instance.listener.pageScaleChange = (payload) => {
2466
- setPageScale(Math.floor(payload * 10 * 10));
2524
+ startTransition(() => {
2525
+ setPageScale(Math.floor(payload * 10 * 10));
2526
+ });
2467
2527
  };
2468
2528
  instance.listener.optionsChange = (payload) => {
2469
- setPageScale(Math.round(payload.scale * 100));
2470
- setPaperDirection(payload.paperDirection);
2471
- setPaperWidth(payload.width);
2472
- setPaperHeight(payload.height);
2529
+ startTransition(() => {
2530
+ setPageScale(Math.round(payload.scale * 100));
2531
+ setPaperDirection(payload.paperDirection);
2532
+ setPaperWidth(payload.width);
2533
+ setPaperHeight(payload.height);
2534
+ });
2473
2535
  };
2474
- instance.listener.contentChange = async () => {
2475
- const count2 = await instance?.command.getWordCount();
2476
- setWordCount(count2 || 0);
2477
- if (onChange) {
2478
- const value = instance?.command.getValue();
2479
- if (value) onChange(value);
2536
+ instance.listener.contentChange = () => {
2537
+ const currentVersion = ++contentSyncVersionRef.current;
2538
+ cancelDeferredTask(deferredContentSyncRef.current);
2539
+ if (onChange && instance) {
2540
+ onChange(instance.command.getValue());
2480
2541
  }
2542
+ deferredContentSyncRef.current = scheduleDeferredTask(async () => {
2543
+ if (cancelled || !instance) return;
2544
+ const count2 = await instance.command.getWordCount();
2545
+ if (cancelled || contentSyncVersionRef.current !== currentVersion) {
2546
+ return;
2547
+ }
2548
+ startTransition(() => {
2549
+ setWordCount(count2 || 0);
2550
+ });
2551
+ deferredContentSyncRef.current = null;
2552
+ });
2481
2553
  };
2482
2554
  instance.register.shortcutList([
2483
2555
  {
@@ -2551,12 +2623,16 @@ function EditorInner({
2551
2623
  };
2552
2624
  window.addEventListener("click", closeDropdowns, { capture: true });
2553
2625
  const count = await instance.command.getWordCount();
2554
- setWordCount(count || 0);
2626
+ startTransition(() => {
2627
+ setWordCount(count || 0);
2628
+ });
2555
2629
  onReady?.(instance);
2556
2630
  };
2557
2631
  initEditor();
2558
2632
  return () => {
2559
2633
  cancelled = true;
2634
+ cancelDeferredTask(deferredContentSyncRef.current);
2635
+ deferredContentSyncRef.current = null;
2560
2636
  instance?.destroy();
2561
2637
  editorRef.current = null;
2562
2638
  if (closeDropdowns) {
@@ -2575,23 +2651,31 @@ function EditorInner({
2575
2651
  e.preventDefault();
2576
2652
  e.dataTransfer.dropEffect = "copy";
2577
2653
  };
2578
- return /* @__PURE__ */ jsxs25(EditorProvider, { editorRef, rangeStyle, isInTable, children: [
2579
- toolbar && !renderToolbar && /* @__PURE__ */ jsx42(EditorToolbar, {}),
2580
- renderToolbar,
2581
- children,
2582
- /* @__PURE__ */ jsx42(
2583
- "div",
2584
- {
2585
- className: className ?? "editor",
2586
- style: style ?? { flex: 1, minHeight: 0, overflow: "auto" },
2587
- ref: containerRef,
2588
- onDrop: handleDrop,
2589
- onDragOver: handleDragOver
2590
- }
2591
- ),
2592
- footer && !renderFooter && /* @__PURE__ */ jsx42(EditorFooter, {}),
2593
- renderFooter
2594
- ] });
2654
+ return /* @__PURE__ */ jsxs25(
2655
+ EditorProvider,
2656
+ {
2657
+ editorRef,
2658
+ rangeStyle,
2659
+ isInTable,
2660
+ children: [
2661
+ toolbar && !renderToolbar && /* @__PURE__ */ jsx42(EditorToolbar, {}),
2662
+ renderToolbar,
2663
+ children,
2664
+ /* @__PURE__ */ jsx42(
2665
+ "div",
2666
+ {
2667
+ className: className ?? "editor",
2668
+ style: style ?? { flex: 1, minHeight: 0, overflow: "auto" },
2669
+ ref: containerRef,
2670
+ onDrop: handleDrop,
2671
+ onDragOver: handleDragOver
2672
+ }
2673
+ ),
2674
+ footer && !renderFooter && /* @__PURE__ */ jsx42(EditorFooter, {}),
2675
+ renderFooter
2676
+ ]
2677
+ }
2678
+ );
2595
2679
  }
2596
2680
  export {
2597
2681
  BoldTool,