@lvce-editor/find-widget-worker 3.18.0 → 3.19.0

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.
@@ -995,6 +995,7 @@ const Button = 1;
995
995
  const Div = 4;
996
996
  const Text = 12;
997
997
  const TextArea = 62;
998
+ const Reference = 100;
998
999
 
999
1000
  const ClientX = 'event.clientX';
1000
1001
  const ClientY = 'event.clientY';
@@ -1020,6 +1021,7 @@ const FocusSelector = 'Viewlet.focusSelector';
1020
1021
  const SetCss = 'Viewlet.setCss';
1021
1022
  const SetFocusContext = 'Viewlet.setFocusContext';
1022
1023
  const SetValueByName = 'Viewlet.setValueByName';
1024
+ const SetPatches = 'Viewlet.setPatches';
1023
1025
 
1024
1026
  const Empty = 0;
1025
1027
  const FocusFindWidget$1 = 16;
@@ -1488,7 +1490,7 @@ const isEqual$4 = (oldState, newState) => {
1488
1490
  };
1489
1491
 
1490
1492
  const isEqual$3 = (oldState, newState) => {
1491
- return oldState.inputErrorMessage === newState.inputErrorMessage && oldState.matchCase === newState.matchCase && oldState.matchCount === newState.matchCount && oldState.matchIndex === newState.matchIndex && oldState.matchWholeWord === newState.matchWholeWord && oldState.preserveCase === newState.preserveCase && oldState.replaceExpanded === newState.replaceExpanded && oldState.useRegularExpression === newState.useRegularExpression && oldState.version === newState.version;
1493
+ return oldState.inputErrorMessage === newState.inputErrorMessage && oldState.focus === newState.focus && oldState.matchCase === newState.matchCase && oldState.matchCount === newState.matchCount && oldState.matchIndex === newState.matchIndex && oldState.matchWholeWord === newState.matchWholeWord && oldState.preserveCase === newState.preserveCase && oldState.replaceExpanded === newState.replaceExpanded && oldState.useRegularExpression === newState.useRegularExpression && oldState.value === newState.value && oldState.version === newState.version;
1492
1494
  };
1493
1495
 
1494
1496
  const isEqual$2 = (oldState, newState) => {
@@ -1887,7 +1889,7 @@ const FocusPrevious = 'FocusPrevious';
1887
1889
  const MatchCase$2 = 'MatchCase';
1888
1890
  const MatchWholeWord$2 = 'MatchWholeWord';
1889
1891
  const PreserveCase$1 = 'PreserveCase';
1890
- const Replace$2 = 'Replace';
1892
+ const Replace$3 = 'Replace';
1891
1893
  const ReplaceAll$2 = 'ReplaceAll';
1892
1894
  const ReplaceValue = 'replace-value';
1893
1895
  const SearchValue = 'search-value';
@@ -2142,7 +2144,7 @@ const getClickHandler = name => {
2142
2144
  return toggleMatchWholeWord;
2143
2145
  case PreserveCase$1:
2144
2146
  return togglePreserveCase;
2145
- case Replace$2:
2147
+ case Replace$3:
2146
2148
  return replace$1;
2147
2149
  case ReplaceAll$2:
2148
2150
  return replaceAll$1;
@@ -2167,7 +2169,7 @@ const getFindWidgetFocusKey = name => {
2167
2169
  return FocusSearchWholeWord;
2168
2170
  case PreserveCase$1:
2169
2171
  return FocusSearchPreserveCase;
2170
- case Replace$2:
2172
+ case Replace$3:
2171
2173
  return FocusFindWidgetReplaceButton$1;
2172
2174
  case ReplaceAll$2:
2173
2175
  return FocusFindWidgetReplaceAllButton$1;
@@ -2685,6 +2687,343 @@ const renderBounds = (oldState, newState) => {
2685
2687
  return [SetBounds, uid, x, y, width, height];
2686
2688
  };
2687
2689
 
2690
+ const mergeClassNames = (...classNames) => {
2691
+ return classNames.filter(Boolean).join(' ');
2692
+ };
2693
+
2694
+ const text = data => {
2695
+ return {
2696
+ childCount: 0,
2697
+ text: data,
2698
+ type: Text
2699
+ };
2700
+ };
2701
+
2702
+ const SetText = 1;
2703
+ const Replace$2 = 2;
2704
+ const SetAttribute = 3;
2705
+ const RemoveAttribute = 4;
2706
+ const Add = 6;
2707
+ const NavigateChild = 7;
2708
+ const NavigateParent = 8;
2709
+ const RemoveChild = 9;
2710
+ const NavigateSibling = 10;
2711
+ const SetReferenceNodeUid = 11;
2712
+ const MultiNavigation = 18;
2713
+
2714
+ const isKey = key => {
2715
+ return key !== 'type' && key !== 'childCount';
2716
+ };
2717
+
2718
+ const getKeys = node => {
2719
+ const keys = Object.keys(node).filter(isKey);
2720
+ return keys;
2721
+ };
2722
+
2723
+ const arrayToTree = nodes => {
2724
+ const result = [];
2725
+ let i = 0;
2726
+ while (i < nodes.length) {
2727
+ const node = nodes[i];
2728
+ const {
2729
+ children,
2730
+ nodesConsumed
2731
+ } = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
2732
+ result.push({
2733
+ node,
2734
+ children
2735
+ });
2736
+ i += 1 + nodesConsumed;
2737
+ }
2738
+ return result;
2739
+ };
2740
+ const getChildrenWithCount = (nodes, startIndex, childCount) => {
2741
+ if (childCount === 0) {
2742
+ return {
2743
+ children: [],
2744
+ nodesConsumed: 0
2745
+ };
2746
+ }
2747
+ const children = [];
2748
+ let i = startIndex;
2749
+ let remaining = childCount;
2750
+ let totalConsumed = 0;
2751
+ while (remaining > 0 && i < nodes.length) {
2752
+ const node = nodes[i];
2753
+ const nodeChildCount = node.childCount || 0;
2754
+ const {
2755
+ children: nodeChildren,
2756
+ nodesConsumed
2757
+ } = getChildrenWithCount(nodes, i + 1, nodeChildCount);
2758
+ children.push({
2759
+ node,
2760
+ children: nodeChildren
2761
+ });
2762
+ const nodeSize = 1 + nodesConsumed;
2763
+ i += nodeSize;
2764
+ totalConsumed += nodeSize;
2765
+ remaining--;
2766
+ }
2767
+ return {
2768
+ children,
2769
+ nodesConsumed: totalConsumed
2770
+ };
2771
+ };
2772
+
2773
+ const isNavigationPatch = patch => {
2774
+ switch (patch.type) {
2775
+ case NavigateChild:
2776
+ case NavigateParent:
2777
+ case NavigateSibling:
2778
+ return true;
2779
+ default:
2780
+ return false;
2781
+ }
2782
+ };
2783
+ const getNavigationIndex = patch => {
2784
+ switch (patch.type) {
2785
+ case NavigateChild:
2786
+ case NavigateSibling:
2787
+ return patch.index;
2788
+ default:
2789
+ return 0;
2790
+ }
2791
+ };
2792
+ const appendNavigationPatch = (patches, type, index) => {
2793
+ const previousPatch = patches.at(-1);
2794
+ if (!previousPatch) {
2795
+ patches.push(type === NavigateParent ? {
2796
+ type
2797
+ } : {
2798
+ index,
2799
+ type
2800
+ });
2801
+ return;
2802
+ }
2803
+ if (previousPatch.type === MultiNavigation) {
2804
+ previousPatch.navigations.push(type, index);
2805
+ return;
2806
+ }
2807
+ if (isNavigationPatch(previousPatch)) {
2808
+ patches[patches.length - 1] = {
2809
+ navigations: [previousPatch.type, getNavigationIndex(previousPatch), type, index],
2810
+ type: MultiNavigation
2811
+ };
2812
+ return;
2813
+ }
2814
+ patches.push(type === NavigateParent ? {
2815
+ type
2816
+ } : {
2817
+ index,
2818
+ type
2819
+ });
2820
+ };
2821
+
2822
+ const compareNodes = (oldNode, newNode) => {
2823
+ // Check if node type changed - return null to signal incompatible nodes
2824
+ // (caller should handle this with a Replace operation)
2825
+ if (oldNode.type !== newNode.type) {
2826
+ return null;
2827
+ }
2828
+ const patches = [];
2829
+ // Handle reference nodes - special handling for uid changes
2830
+ if (oldNode.type === Reference && oldNode.uid !== newNode.uid) {
2831
+ patches.push({
2832
+ type: SetReferenceNodeUid,
2833
+ uid: newNode.uid
2834
+ });
2835
+ }
2836
+ // Handle text nodes
2837
+ if (oldNode.type === Text && newNode.type === Text) {
2838
+ if (oldNode.text !== newNode.text) {
2839
+ patches.push({
2840
+ type: SetText,
2841
+ value: newNode.text
2842
+ });
2843
+ }
2844
+ return patches;
2845
+ }
2846
+ // Compare attributes
2847
+ const oldKeys = getKeys(oldNode).filter(key => oldNode.type !== Reference || key !== 'uid');
2848
+ const newKeys = getKeys(newNode).filter(key => newNode.type !== Reference || key !== 'uid');
2849
+ // Check for attribute changes
2850
+ for (const key of newKeys) {
2851
+ if (oldNode[key] !== newNode[key]) {
2852
+ patches.push({
2853
+ type: SetAttribute,
2854
+ key,
2855
+ value: newNode[key]
2856
+ });
2857
+ }
2858
+ }
2859
+ // Check for removed attributes
2860
+ for (const key of oldKeys) {
2861
+ if (!Object.hasOwn(newNode, key)) {
2862
+ patches.push({
2863
+ type: RemoveAttribute,
2864
+ key
2865
+ });
2866
+ }
2867
+ }
2868
+ return patches;
2869
+ };
2870
+
2871
+ const treeToArray = node => {
2872
+ const result = [];
2873
+ const stack = [node];
2874
+ while (stack.length > 0) {
2875
+ const current = stack.pop();
2876
+ result.push(current.node);
2877
+ for (let i = current.children.length - 1; i >= 0; i--) {
2878
+ stack.push(current.children[i]);
2879
+ }
2880
+ }
2881
+ return result;
2882
+ };
2883
+
2884
+ const navigateToChild = (patches, currentChildIndex, index) => {
2885
+ if (currentChildIndex === -1) {
2886
+ appendNavigationPatch(patches, NavigateChild, index);
2887
+ return index;
2888
+ }
2889
+ if (currentChildIndex !== index) {
2890
+ appendNavigationPatch(patches, NavigateSibling, index);
2891
+ }
2892
+ return index;
2893
+ };
2894
+ const navigateToParent = (patches, currentChildIndex) => {
2895
+ if (currentChildIndex >= 0) {
2896
+ appendNavigationPatch(patches, NavigateParent, 0);
2897
+ }
2898
+ return -1;
2899
+ };
2900
+ const addTree = (newNode, patches) => {
2901
+ patches.push({
2902
+ type: Add,
2903
+ nodes: treeToArray(newNode)
2904
+ });
2905
+ };
2906
+ const replaceTree = (newNode, patches) => {
2907
+ patches.push({
2908
+ type: Replace$2,
2909
+ nodes: treeToArray(newNode)
2910
+ });
2911
+ };
2912
+ const appendPatch = (patches, patch) => {
2913
+ switch (patch.type) {
2914
+ case MultiNavigation:
2915
+ for (let i = 0; i < patch.navigations.length; i += 2) {
2916
+ appendNavigationPatch(patches, patch.navigations[i], patch.navigations[i + 1]);
2917
+ }
2918
+ return;
2919
+ case NavigateChild:
2920
+ case NavigateSibling:
2921
+ appendNavigationPatch(patches, patch.type, patch.index);
2922
+ return;
2923
+ case NavigateParent:
2924
+ appendNavigationPatch(patches, patch.type, 0);
2925
+ return;
2926
+ default:
2927
+ patches.push(patch);
2928
+ }
2929
+ };
2930
+ const appendPatches = (patches, newPatches) => {
2931
+ for (const patch of newPatches) {
2932
+ appendPatch(patches, patch);
2933
+ }
2934
+ };
2935
+ const diffExistingChild = (oldNode, newNode, patches, currentChildIndex, index) => {
2936
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
2937
+ if (nodePatches === null) {
2938
+ const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
2939
+ replaceTree(newNode, patches);
2940
+ return nextChildIndex;
2941
+ }
2942
+ const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
2943
+ const childPatches = [];
2944
+ if (hasChildrenToCompare) {
2945
+ diffChildren(oldNode.children, newNode.children, childPatches);
2946
+ }
2947
+ if (nodePatches.length === 0 && childPatches.length === 0) {
2948
+ return currentChildIndex;
2949
+ }
2950
+ const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
2951
+ patches.push(...nodePatches);
2952
+ appendPatches(patches, childPatches);
2953
+ return nextChildIndex;
2954
+ };
2955
+ const diffRootNode = (oldNode, newNode, patches) => {
2956
+ const nodePatches = compareNodes(oldNode.node, newNode.node);
2957
+ if (nodePatches === null) {
2958
+ replaceTree(newNode, patches);
2959
+ return;
2960
+ }
2961
+ if (nodePatches.length > 0) {
2962
+ patches.push(...nodePatches);
2963
+ }
2964
+ if (oldNode.children.length > 0 || newNode.children.length > 0) {
2965
+ diffChildren(oldNode.children, newNode.children, patches);
2966
+ }
2967
+ };
2968
+ const diffChildren = (oldChildren, newChildren, patches) => {
2969
+ const maxLength = Math.max(oldChildren.length, newChildren.length);
2970
+ let currentChildIndex = -1;
2971
+ const indicesToRemove = [];
2972
+ for (let i = 0; i < maxLength; i++) {
2973
+ const oldNode = oldChildren[i];
2974
+ const newNode = newChildren[i];
2975
+ if (!oldNode && !newNode) {
2976
+ continue;
2977
+ }
2978
+ if (!oldNode) {
2979
+ currentChildIndex = navigateToParent(patches, currentChildIndex);
2980
+ addTree(newNode, patches);
2981
+ continue;
2982
+ }
2983
+ if (!newNode) {
2984
+ indicesToRemove.push(i);
2985
+ continue;
2986
+ }
2987
+ currentChildIndex = diffExistingChild(oldNode, newNode, patches, currentChildIndex, i);
2988
+ }
2989
+ navigateToParent(patches, currentChildIndex);
2990
+ for (let j = indicesToRemove.length - 1; j >= 0; j--) {
2991
+ patches.push({
2992
+ type: RemoveChild,
2993
+ index: indicesToRemove[j]
2994
+ });
2995
+ }
2996
+ };
2997
+ const diffTrees = (oldTree, newTree, patches, path) => {
2998
+ if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
2999
+ diffRootNode(oldTree[0], newTree[0], patches);
3000
+ return;
3001
+ }
3002
+ diffChildren(oldTree, newTree, patches);
3003
+ };
3004
+
3005
+ const removeTrailingNavigationPatches = patches => {
3006
+ while (patches.length > 0) {
3007
+ const patch = patches.at(-1);
3008
+ if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling && patch.type !== MultiNavigation) {
3009
+ break;
3010
+ }
3011
+ patches.pop();
3012
+ }
3013
+ return patches;
3014
+ };
3015
+
3016
+ const diffTree = (oldNodes, newNodes) => {
3017
+ // Step 1: Convert flat arrays to tree structures
3018
+ const oldTree = arrayToTree(oldNodes);
3019
+ const newTree = arrayToTree(newNodes);
3020
+ // Step 3: Compare the trees
3021
+ const patches = [];
3022
+ diffTrees(oldTree, newTree, patches, []);
3023
+ // Remove trailing navigation patches since they serve no purpose
3024
+ return removeTrailingNavigationPatches(patches);
3025
+ };
3026
+
2688
3027
  const HandleBlur = 1;
2689
3028
  const HandleClickButton = 2;
2690
3029
  const HandleClickClose = 3;
@@ -2832,7 +3171,7 @@ const getFindWidgetButtons = (findButtonsEnabled, replaceButtonsEnabled, matchCa
2832
3171
  disabled: !replaceButtonsEnabled,
2833
3172
  icon: Replace,
2834
3173
  label: replace(),
2835
- name: Replace$2,
3174
+ name: Replace$3,
2836
3175
  onClick: HandleClickButton
2837
3176
  }, {
2838
3177
  disabled: !replaceButtonsEnabled,
@@ -2858,18 +3197,6 @@ const getFindWidgetButtonsEnabled = (matchCount, value) => {
2858
3197
  };
2859
3198
  };
2860
3199
 
2861
- const mergeClassNames = (...classNames) => {
2862
- return classNames.filter(Boolean).join(' ');
2863
- };
2864
-
2865
- const text = data => {
2866
- return {
2867
- childCount: 0,
2868
- text: data,
2869
- type: Text
2870
- };
2871
- };
2872
-
2873
3200
  const FindWidget = 'FindWidget';
2874
3201
  const FindWidgetFind = 'FindWidgetFind';
2875
3202
  const FindWidgetMatchCount = 'FindWidgetMatchCount';
@@ -3103,20 +3430,20 @@ const getMatchCountText = (matchIndex, matchCount) => {
3103
3430
  return matchOf(matchIndex + 1, matchCount);
3104
3431
  };
3105
3432
 
3106
- const renderContent = (oldState, newState) => {
3433
+ const getDom = state => {
3107
3434
  const {
3108
3435
  focus,
3109
3436
  inputErrorMessage,
3110
3437
  matchCase,
3111
3438
  matchCount,
3439
+ matchIndex,
3112
3440
  matchWholeWord,
3113
3441
  preserveCase,
3114
3442
  replaceExpanded,
3115
- uid,
3116
3443
  useRegularExpression,
3117
3444
  value
3118
- } = newState;
3119
- const matchCountText = inputErrorMessage || getMatchCountText(newState.matchIndex, newState.matchCount);
3445
+ } = state;
3446
+ const matchCountText = inputErrorMessage || getMatchCountText(matchIndex, matchCount);
3120
3447
  const {
3121
3448
  findButtonsEnabled,
3122
3449
  replaceButtonsEnabled
@@ -3131,7 +3458,18 @@ const renderContent = (oldState, newState) => {
3131
3458
  const inputFocused = focus === FocusSearchInput;
3132
3459
  const replaceInputFocused = focus === FocusSearchReplaceInput;
3133
3460
  const dom = getFindWidgetVirtualDom(matchCountText, replaceExpanded, findButtons, findFieldButtons, replaceButtons, replaceFieldButtons, matchCount, value, hasError, inputFocused, replaceInputFocused);
3134
- return [SetDom2, uid, dom];
3461
+ return dom;
3462
+ };
3463
+ const renderContent = (oldState, newState) => {
3464
+ const {
3465
+ uid
3466
+ } = newState;
3467
+ const dom = getDom(newState);
3468
+ if (oldState.version === 0) {
3469
+ return [SetDom2, uid, dom];
3470
+ }
3471
+ const oldDom = getDom(oldState);
3472
+ return [SetPatches, uid, diffTree(oldDom, dom)];
3135
3473
  };
3136
3474
 
3137
3475
  const renderCss = (oldState, newState) => {
@@ -3239,7 +3577,7 @@ const getFocusSelector = focusKey => {
3239
3577
  case FocusFindWidgetReplaceAllButton$1:
3240
3578
  return ReplaceAll$2;
3241
3579
  case FocusFindWidgetReplaceButton$1:
3242
- return Replace$2;
3580
+ return Replace$3;
3243
3581
  case FocusSearchInput:
3244
3582
  return SearchValue;
3245
3583
  case FocusSearchMatchCase:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/find-widget-worker",
3
- "version": "3.18.0",
3
+ "version": "3.19.0",
4
4
  "description": "Web Worker for the find widget in Lvce Editor",
5
5
  "repository": {
6
6
  "type": "git",