@elementor/editor-canvas 4.1.0-740 → 4.1.0-741
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.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +86 -33
- package/dist/index.mjs +87 -34
- package/package.json +18 -18
- package/src/legacy/replacements/base.ts +4 -0
- package/src/legacy/replacements/inline-editing/canvas-inline-editor.tsx +49 -27
- package/src/legacy/replacements/inline-editing/inline-editing-elements.tsx +16 -10
- package/src/legacy/replacements/inline-editing/inline-editing-utils.ts +11 -1
- package/src/legacy/replacements/manager.ts +13 -0
- package/src/legacy/types.ts +3 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { V1Element, V1ElementConfig, V1ElementModelProps } from '@elementor/editor-elements';
|
|
2
2
|
import { TwingArrayLoader, TwingEnvironment } from '@elementor/twing';
|
|
3
|
+
import { Root } from 'react-dom/client';
|
|
3
4
|
import * as _elementor_editor_props from '@elementor/editor-props';
|
|
4
5
|
import { Props, PropValue, PropType, PropTypeKey, PropsSchema, AnyTransformable } from '@elementor/editor-props';
|
|
5
6
|
import * as _elementor_utils from '@elementor/utils';
|
|
@@ -204,6 +205,8 @@ type ReplacementSettings = {
|
|
|
204
205
|
id: string;
|
|
205
206
|
element: HTMLElement;
|
|
206
207
|
refreshView: () => void;
|
|
208
|
+
reactRoot: Root;
|
|
209
|
+
reactContainer: HTMLElement;
|
|
207
210
|
};
|
|
208
211
|
|
|
209
212
|
type CreateTemplatedElementTypeOptions = {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { V1Element, V1ElementConfig, V1ElementModelProps } from '@elementor/editor-elements';
|
|
2
2
|
import { TwingArrayLoader, TwingEnvironment } from '@elementor/twing';
|
|
3
|
+
import { Root } from 'react-dom/client';
|
|
3
4
|
import * as _elementor_editor_props from '@elementor/editor-props';
|
|
4
5
|
import { Props, PropValue, PropType, PropTypeKey, PropsSchema, AnyTransformable } from '@elementor/editor-props';
|
|
5
6
|
import * as _elementor_utils from '@elementor/utils';
|
|
@@ -204,6 +205,8 @@ type ReplacementSettings = {
|
|
|
204
205
|
id: string;
|
|
205
206
|
element: HTMLElement;
|
|
206
207
|
refreshView: () => void;
|
|
208
|
+
reactRoot: Root;
|
|
209
|
+
reactContainer: HTMLElement;
|
|
207
210
|
};
|
|
208
211
|
|
|
209
212
|
type CreateTemplatedElementTypeOptions = {
|
package/dist/index.js
CHANGED
|
@@ -2421,9 +2421,11 @@ function createNestedTemplatedElementView({
|
|
|
2421
2421
|
});
|
|
2422
2422
|
}
|
|
2423
2423
|
|
|
2424
|
+
// src/legacy/replacements/manager.ts
|
|
2425
|
+
var import_client = require("react-dom/client");
|
|
2426
|
+
|
|
2424
2427
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
2425
2428
|
var React6 = __toESM(require("react"));
|
|
2426
|
-
var import_client = require("react-dom/client");
|
|
2427
2429
|
var import_editor_elements5 = require("@elementor/editor-elements");
|
|
2428
2430
|
var import_editor_props4 = require("@elementor/editor-props");
|
|
2429
2431
|
var import_editor_v1_adapters12 = require("@elementor/editor-v1-adapters");
|
|
@@ -2442,6 +2444,8 @@ var ReplacementBase = class {
|
|
|
2442
2444
|
type;
|
|
2443
2445
|
id;
|
|
2444
2446
|
refreshView;
|
|
2447
|
+
reactRoot;
|
|
2448
|
+
reactContainer;
|
|
2445
2449
|
constructor(settings) {
|
|
2446
2450
|
this.getSetting = settings.getSetting;
|
|
2447
2451
|
this.setSetting = settings.setSetting;
|
|
@@ -2449,6 +2453,8 @@ var ReplacementBase = class {
|
|
|
2449
2453
|
this.type = settings.type;
|
|
2450
2454
|
this.id = settings.id;
|
|
2451
2455
|
this.refreshView = settings.refreshView;
|
|
2456
|
+
this.reactRoot = settings.reactRoot;
|
|
2457
|
+
this.reactContainer = settings.reactContainer;
|
|
2452
2458
|
}
|
|
2453
2459
|
static getTypes() {
|
|
2454
2460
|
return null;
|
|
@@ -2518,6 +2524,11 @@ var useOnClickOutsideIframe = (handleUnmount) => {
|
|
|
2518
2524
|
};
|
|
2519
2525
|
var useRenderToolbar = (ownerDocument, id) => {
|
|
2520
2526
|
const [anchor, setAnchor] = (0, import_react11.useState)(null);
|
|
2527
|
+
(0, import_react11.useEffect)(() => {
|
|
2528
|
+
if (!anchor) {
|
|
2529
|
+
removeToolbarAnchor(ownerDocument, id);
|
|
2530
|
+
}
|
|
2531
|
+
}, [anchor, ownerDocument, id]);
|
|
2521
2532
|
const onSelectionEnd = (view) => {
|
|
2522
2533
|
const hasSelection = !view.state.selection.empty;
|
|
2523
2534
|
removeToolbarAnchor(ownerDocument, id);
|
|
@@ -2527,7 +2538,10 @@ var useRenderToolbar = (ownerDocument, id) => {
|
|
|
2527
2538
|
setAnchor(null);
|
|
2528
2539
|
}
|
|
2529
2540
|
};
|
|
2530
|
-
|
|
2541
|
+
const clearAnchor = (0, import_react11.useCallback)(() => {
|
|
2542
|
+
setAnchor(null);
|
|
2543
|
+
}, []);
|
|
2544
|
+
return { onSelectionEnd, anchor, clearAnchor };
|
|
2531
2545
|
};
|
|
2532
2546
|
var createAnchorBasedOnSelection = (ownerDocument, id) => {
|
|
2533
2547
|
const frameWindow = ownerDocument.defaultView;
|
|
@@ -2594,46 +2608,59 @@ var horizontalShifterMiddleware = {
|
|
|
2594
2608
|
};
|
|
2595
2609
|
|
|
2596
2610
|
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
2597
|
-
var EDITOR_WRAPPER_SELECTOR = "inline-editor-wrapper";
|
|
2598
2611
|
var CanvasInlineEditor = ({
|
|
2599
2612
|
elementClasses,
|
|
2600
2613
|
initialValue,
|
|
2601
2614
|
expectedTag,
|
|
2602
2615
|
rootElement,
|
|
2616
|
+
contentElement,
|
|
2603
2617
|
id,
|
|
2604
2618
|
setValue,
|
|
2605
|
-
|
|
2619
|
+
requestDestroy
|
|
2606
2620
|
}) => {
|
|
2621
|
+
const [active, setActive] = (0, import_react12.useState)(true);
|
|
2607
2622
|
const [editor, setEditor] = (0, import_react12.useState)(null);
|
|
2608
|
-
const { onSelectionEnd, anchor: toolbarAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
+
const { onSelectionEnd, anchor: toolbarAnchor, clearAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
|
|
2624
|
+
(0, import_react12.useEffect)(() => {
|
|
2625
|
+
if (!active) {
|
|
2626
|
+
clearAnchor();
|
|
2627
|
+
requestDestroy();
|
|
2628
|
+
}
|
|
2629
|
+
}, [active, clearAnchor, requestDestroy]);
|
|
2630
|
+
const dismiss = (0, import_react12.useCallback)(() => {
|
|
2631
|
+
setEditor(null);
|
|
2632
|
+
setActive(false);
|
|
2633
|
+
}, []);
|
|
2634
|
+
useOnClickOutsideIframe(dismiss);
|
|
2635
|
+
(0, import_react12.useEffect)(() => {
|
|
2636
|
+
const ownerDocument = contentElement.ownerDocument;
|
|
2637
|
+
const handleClickAway = (event) => {
|
|
2638
|
+
if (contentElement.contains(event.target)) {
|
|
2639
|
+
return;
|
|
2640
|
+
}
|
|
2641
|
+
dismiss();
|
|
2642
|
+
};
|
|
2643
|
+
ownerDocument.addEventListener("mousedown", handleClickAway);
|
|
2644
|
+
return () => ownerDocument.removeEventListener("mousedown", handleClickAway);
|
|
2645
|
+
}, [contentElement, dismiss]);
|
|
2646
|
+
if (!active) {
|
|
2647
|
+
return null;
|
|
2648
|
+
}
|
|
2649
|
+
return /* @__PURE__ */ React5.createElement(import_ui4.ThemeProvider, null, /* @__PURE__ */ React5.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React5.createElement(
|
|
2623
2650
|
import_editor_controls2.InlineEditor,
|
|
2624
2651
|
{
|
|
2625
2652
|
onEditorCreate: setEditor,
|
|
2653
|
+
mountElement: contentElement,
|
|
2626
2654
|
editorProps: {
|
|
2627
2655
|
attributes: {
|
|
2628
|
-
style: "outline: none;
|
|
2656
|
+
style: "outline: none; display: inherit; justify-content: inherit; align-items: inherit; flex-direction: inherit; text-align: inherit;"
|
|
2629
2657
|
}
|
|
2630
2658
|
},
|
|
2631
2659
|
elementClasses,
|
|
2632
2660
|
value: initialValue,
|
|
2633
2661
|
setValue,
|
|
2634
|
-
onBlur,
|
|
2662
|
+
onBlur: dismiss,
|
|
2635
2663
|
autofocus: true,
|
|
2636
|
-
expectedTag,
|
|
2637
2664
|
onSelectionEnd
|
|
2638
2665
|
}
|
|
2639
2666
|
), toolbarAnchor && editor && /* @__PURE__ */ React5.createElement(InlineEditingToolbar, { anchor: toolbarAnchor, editor, id }));
|
|
@@ -2662,7 +2689,18 @@ var InlineEditingToolbar = ({ anchor, editor, id }) => {
|
|
|
2662
2689
|
refs.setReference(anchor);
|
|
2663
2690
|
return () => refs.setReference(null);
|
|
2664
2691
|
}, [anchor, refs]);
|
|
2665
|
-
return /* @__PURE__ */ React5.createElement(import_react13.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(
|
|
2692
|
+
return /* @__PURE__ */ React5.createElement(import_react13.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(
|
|
2693
|
+
import_ui4.Box,
|
|
2694
|
+
{
|
|
2695
|
+
ref: refs.setFloating,
|
|
2696
|
+
role: "presentation",
|
|
2697
|
+
style: {
|
|
2698
|
+
...floatingStyles,
|
|
2699
|
+
pointerEvents: "none"
|
|
2700
|
+
}
|
|
2701
|
+
},
|
|
2702
|
+
/* @__PURE__ */ React5.createElement(import_editor_controls2.InlineEditorToolbar, { editor, elementId: id })
|
|
2703
|
+
));
|
|
2666
2704
|
};
|
|
2667
2705
|
|
|
2668
2706
|
// src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
|
|
@@ -2696,8 +2734,8 @@ var isInlineEditingAllowed = ({ rawValue, propTypeFromSchema }) => {
|
|
|
2696
2734
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
2697
2735
|
var HISTORY_DEBOUNCE_WAIT = 800;
|
|
2698
2736
|
var InlineEditingReplacement = class extends ReplacementBase {
|
|
2699
|
-
inlineEditorRoot = null;
|
|
2700
2737
|
handlerAttached = false;
|
|
2738
|
+
editing = false;
|
|
2701
2739
|
getReplacementKey() {
|
|
2702
2740
|
return "inline-editing";
|
|
2703
2741
|
}
|
|
@@ -2705,7 +2743,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2705
2743
|
return Object.keys(INLINE_EDITING_PROPERTY_PER_TYPE);
|
|
2706
2744
|
}
|
|
2707
2745
|
isEditingModeActive() {
|
|
2708
|
-
return
|
|
2746
|
+
return this.editing;
|
|
2709
2747
|
}
|
|
2710
2748
|
shouldRenderReplacement() {
|
|
2711
2749
|
return this.isInlineEditingEligible() && (0, import_editor_v1_adapters12.getCurrentEditMode)() === "edit";
|
|
@@ -2748,8 +2786,8 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2748
2786
|
resetInlineEditorRoot() {
|
|
2749
2787
|
this.element.removeEventListener("click", this.handleRenderInlineEditor);
|
|
2750
2788
|
this.handlerAttached = false;
|
|
2751
|
-
this.
|
|
2752
|
-
this.
|
|
2789
|
+
this.reactRoot.render(null);
|
|
2790
|
+
this.editing = false;
|
|
2753
2791
|
}
|
|
2754
2792
|
unmountInlineEditor() {
|
|
2755
2793
|
this.resetInlineEditorRoot();
|
|
@@ -2860,12 +2898,16 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2860
2898
|
if (this.isEditingModeActive()) {
|
|
2861
2899
|
this.resetInlineEditorRoot();
|
|
2862
2900
|
}
|
|
2863
|
-
const
|
|
2901
|
+
const contentElement = this.element.children?.[0];
|
|
2902
|
+
if (!contentElement) {
|
|
2903
|
+
return;
|
|
2904
|
+
}
|
|
2905
|
+
const elementClasses = contentElement.classList.toString();
|
|
2864
2906
|
const propValue = this.getExtractedContentValue();
|
|
2865
2907
|
const expectedTag = this.getExpectedTag();
|
|
2866
|
-
|
|
2867
|
-
this.
|
|
2868
|
-
this.
|
|
2908
|
+
contentElement.innerHTML = "";
|
|
2909
|
+
this.editing = true;
|
|
2910
|
+
this.reactRoot.render(
|
|
2869
2911
|
/* @__PURE__ */ React6.createElement(
|
|
2870
2912
|
CanvasInlineEditor,
|
|
2871
2913
|
{
|
|
@@ -2873,9 +2915,10 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2873
2915
|
initialValue: propValue,
|
|
2874
2916
|
expectedTag,
|
|
2875
2917
|
rootElement: this.element,
|
|
2918
|
+
contentElement,
|
|
2876
2919
|
id: this.id,
|
|
2877
2920
|
setValue: this.setContentValue.bind(this),
|
|
2878
|
-
|
|
2921
|
+
requestDestroy: this.unmountInlineEditor.bind(this)
|
|
2879
2922
|
}
|
|
2880
2923
|
)
|
|
2881
2924
|
);
|
|
@@ -2904,16 +2947,24 @@ var createViewWithReplacements = (options) => {
|
|
|
2904
2947
|
return class extends TemplatedView {
|
|
2905
2948
|
#replacement = null;
|
|
2906
2949
|
#config;
|
|
2950
|
+
#reactContainer;
|
|
2951
|
+
#reactRoot;
|
|
2907
2952
|
constructor(...args) {
|
|
2908
2953
|
super(...args);
|
|
2909
2954
|
const settings = this.model.get("settings");
|
|
2955
|
+
this.#reactContainer = this.el.ownerDocument.createElement("div");
|
|
2956
|
+
this.#reactContainer.style.display = "none";
|
|
2957
|
+
this.el.ownerDocument.body.appendChild(this.#reactContainer);
|
|
2958
|
+
this.#reactRoot = (0, import_client.createRoot)(this.#reactContainer);
|
|
2910
2959
|
this.#config = {
|
|
2911
2960
|
getSetting: settings.get.bind(settings),
|
|
2912
2961
|
setSetting: settings.set.bind(settings),
|
|
2913
2962
|
element: this.el,
|
|
2914
2963
|
type: this?.model?.get("widgetType") ?? this.container?.model?.get("elType") ?? null,
|
|
2915
2964
|
id: this?.model?.get("id") ?? null,
|
|
2916
|
-
refreshView: this.refreshView.bind(this)
|
|
2965
|
+
refreshView: this.refreshView.bind(this),
|
|
2966
|
+
reactRoot: this.#reactRoot,
|
|
2967
|
+
reactContainer: this.#reactContainer
|
|
2917
2968
|
};
|
|
2918
2969
|
}
|
|
2919
2970
|
refreshView() {
|
|
@@ -2934,6 +2985,8 @@ var createViewWithReplacements = (options) => {
|
|
|
2934
2985
|
}
|
|
2935
2986
|
onDestroy() {
|
|
2936
2987
|
this.#triggerAltMethod("onDestroy");
|
|
2988
|
+
this.#reactRoot.unmount();
|
|
2989
|
+
this.#reactContainer.remove();
|
|
2937
2990
|
}
|
|
2938
2991
|
_afterRender() {
|
|
2939
2992
|
this.#triggerAltMethod("_afterRender");
|
package/dist/index.mjs
CHANGED
|
@@ -2387,9 +2387,11 @@ function createNestedTemplatedElementView({
|
|
|
2387
2387
|
});
|
|
2388
2388
|
}
|
|
2389
2389
|
|
|
2390
|
+
// src/legacy/replacements/manager.ts
|
|
2391
|
+
import { createRoot } from "react-dom/client";
|
|
2392
|
+
|
|
2390
2393
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
2391
2394
|
import * as React6 from "react";
|
|
2392
|
-
import { createRoot } from "react-dom/client";
|
|
2393
2395
|
import { getContainer, getElementLabel, getElementType as getElementType2 } from "@elementor/editor-elements";
|
|
2394
2396
|
import {
|
|
2395
2397
|
htmlV3PropTypeUtil as htmlV3PropTypeUtil2,
|
|
@@ -2412,6 +2414,8 @@ var ReplacementBase = class {
|
|
|
2412
2414
|
type;
|
|
2413
2415
|
id;
|
|
2414
2416
|
refreshView;
|
|
2417
|
+
reactRoot;
|
|
2418
|
+
reactContainer;
|
|
2415
2419
|
constructor(settings) {
|
|
2416
2420
|
this.getSetting = settings.getSetting;
|
|
2417
2421
|
this.setSetting = settings.setSetting;
|
|
@@ -2419,6 +2423,8 @@ var ReplacementBase = class {
|
|
|
2419
2423
|
this.type = settings.type;
|
|
2420
2424
|
this.id = settings.id;
|
|
2421
2425
|
this.refreshView = settings.refreshView;
|
|
2426
|
+
this.reactRoot = settings.reactRoot;
|
|
2427
|
+
this.reactContainer = settings.reactContainer;
|
|
2422
2428
|
}
|
|
2423
2429
|
static getTypes() {
|
|
2424
2430
|
return null;
|
|
@@ -2439,7 +2445,7 @@ var ReplacementBase = class {
|
|
|
2439
2445
|
|
|
2440
2446
|
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
2441
2447
|
import * as React5 from "react";
|
|
2442
|
-
import { useEffect as useEffect8, useLayoutEffect, useState as useState5 } from "react";
|
|
2448
|
+
import { useCallback as useCallback2, useEffect as useEffect8, useLayoutEffect, useState as useState5 } from "react";
|
|
2443
2449
|
import { InlineEditor, InlineEditorToolbar } from "@elementor/editor-controls";
|
|
2444
2450
|
import { Box as Box2, ThemeProvider } from "@elementor/ui";
|
|
2445
2451
|
import { autoUpdate as autoUpdate2, flip, FloatingPortal as FloatingPortal2, useFloating as useFloating2 } from "@floating-ui/react";
|
|
@@ -2488,6 +2494,11 @@ var useOnClickOutsideIframe = (handleUnmount) => {
|
|
|
2488
2494
|
};
|
|
2489
2495
|
var useRenderToolbar = (ownerDocument, id) => {
|
|
2490
2496
|
const [anchor, setAnchor] = useState4(null);
|
|
2497
|
+
useEffect7(() => {
|
|
2498
|
+
if (!anchor) {
|
|
2499
|
+
removeToolbarAnchor(ownerDocument, id);
|
|
2500
|
+
}
|
|
2501
|
+
}, [anchor, ownerDocument, id]);
|
|
2491
2502
|
const onSelectionEnd = (view) => {
|
|
2492
2503
|
const hasSelection = !view.state.selection.empty;
|
|
2493
2504
|
removeToolbarAnchor(ownerDocument, id);
|
|
@@ -2497,7 +2508,10 @@ var useRenderToolbar = (ownerDocument, id) => {
|
|
|
2497
2508
|
setAnchor(null);
|
|
2498
2509
|
}
|
|
2499
2510
|
};
|
|
2500
|
-
|
|
2511
|
+
const clearAnchor = useCallback(() => {
|
|
2512
|
+
setAnchor(null);
|
|
2513
|
+
}, []);
|
|
2514
|
+
return { onSelectionEnd, anchor, clearAnchor };
|
|
2501
2515
|
};
|
|
2502
2516
|
var createAnchorBasedOnSelection = (ownerDocument, id) => {
|
|
2503
2517
|
const frameWindow = ownerDocument.defaultView;
|
|
@@ -2564,46 +2578,59 @@ var horizontalShifterMiddleware = {
|
|
|
2564
2578
|
};
|
|
2565
2579
|
|
|
2566
2580
|
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
2567
|
-
var EDITOR_WRAPPER_SELECTOR = "inline-editor-wrapper";
|
|
2568
2581
|
var CanvasInlineEditor = ({
|
|
2569
2582
|
elementClasses,
|
|
2570
2583
|
initialValue,
|
|
2571
2584
|
expectedTag,
|
|
2572
2585
|
rootElement,
|
|
2586
|
+
contentElement,
|
|
2573
2587
|
id,
|
|
2574
2588
|
setValue,
|
|
2575
|
-
|
|
2589
|
+
requestDestroy
|
|
2576
2590
|
}) => {
|
|
2591
|
+
const [active, setActive] = useState5(true);
|
|
2577
2592
|
const [editor, setEditor] = useState5(null);
|
|
2578
|
-
const { onSelectionEnd, anchor: toolbarAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
+
const { onSelectionEnd, anchor: toolbarAnchor, clearAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
|
|
2594
|
+
useEffect8(() => {
|
|
2595
|
+
if (!active) {
|
|
2596
|
+
clearAnchor();
|
|
2597
|
+
requestDestroy();
|
|
2598
|
+
}
|
|
2599
|
+
}, [active, clearAnchor, requestDestroy]);
|
|
2600
|
+
const dismiss = useCallback2(() => {
|
|
2601
|
+
setEditor(null);
|
|
2602
|
+
setActive(false);
|
|
2603
|
+
}, []);
|
|
2604
|
+
useOnClickOutsideIframe(dismiss);
|
|
2605
|
+
useEffect8(() => {
|
|
2606
|
+
const ownerDocument = contentElement.ownerDocument;
|
|
2607
|
+
const handleClickAway = (event) => {
|
|
2608
|
+
if (contentElement.contains(event.target)) {
|
|
2609
|
+
return;
|
|
2610
|
+
}
|
|
2611
|
+
dismiss();
|
|
2612
|
+
};
|
|
2613
|
+
ownerDocument.addEventListener("mousedown", handleClickAway);
|
|
2614
|
+
return () => ownerDocument.removeEventListener("mousedown", handleClickAway);
|
|
2615
|
+
}, [contentElement, dismiss]);
|
|
2616
|
+
if (!active) {
|
|
2617
|
+
return null;
|
|
2618
|
+
}
|
|
2619
|
+
return /* @__PURE__ */ React5.createElement(ThemeProvider, null, /* @__PURE__ */ React5.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React5.createElement(
|
|
2593
2620
|
InlineEditor,
|
|
2594
2621
|
{
|
|
2595
2622
|
onEditorCreate: setEditor,
|
|
2623
|
+
mountElement: contentElement,
|
|
2596
2624
|
editorProps: {
|
|
2597
2625
|
attributes: {
|
|
2598
|
-
style: "outline: none;
|
|
2626
|
+
style: "outline: none; display: inherit; justify-content: inherit; align-items: inherit; flex-direction: inherit; text-align: inherit;"
|
|
2599
2627
|
}
|
|
2600
2628
|
},
|
|
2601
2629
|
elementClasses,
|
|
2602
2630
|
value: initialValue,
|
|
2603
2631
|
setValue,
|
|
2604
|
-
onBlur,
|
|
2632
|
+
onBlur: dismiss,
|
|
2605
2633
|
autofocus: true,
|
|
2606
|
-
expectedTag,
|
|
2607
2634
|
onSelectionEnd
|
|
2608
2635
|
}
|
|
2609
2636
|
), toolbarAnchor && editor && /* @__PURE__ */ React5.createElement(InlineEditingToolbar, { anchor: toolbarAnchor, editor, id }));
|
|
@@ -2632,7 +2659,18 @@ var InlineEditingToolbar = ({ anchor, editor, id }) => {
|
|
|
2632
2659
|
refs.setReference(anchor);
|
|
2633
2660
|
return () => refs.setReference(null);
|
|
2634
2661
|
}, [anchor, refs]);
|
|
2635
|
-
return /* @__PURE__ */ React5.createElement(FloatingPortal2, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(
|
|
2662
|
+
return /* @__PURE__ */ React5.createElement(FloatingPortal2, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(
|
|
2663
|
+
Box2,
|
|
2664
|
+
{
|
|
2665
|
+
ref: refs.setFloating,
|
|
2666
|
+
role: "presentation",
|
|
2667
|
+
style: {
|
|
2668
|
+
...floatingStyles,
|
|
2669
|
+
pointerEvents: "none"
|
|
2670
|
+
}
|
|
2671
|
+
},
|
|
2672
|
+
/* @__PURE__ */ React5.createElement(InlineEditorToolbar, { editor, elementId: id })
|
|
2673
|
+
));
|
|
2636
2674
|
};
|
|
2637
2675
|
|
|
2638
2676
|
// src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
|
|
@@ -2666,8 +2704,8 @@ var isInlineEditingAllowed = ({ rawValue, propTypeFromSchema }) => {
|
|
|
2666
2704
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
2667
2705
|
var HISTORY_DEBOUNCE_WAIT = 800;
|
|
2668
2706
|
var InlineEditingReplacement = class extends ReplacementBase {
|
|
2669
|
-
inlineEditorRoot = null;
|
|
2670
2707
|
handlerAttached = false;
|
|
2708
|
+
editing = false;
|
|
2671
2709
|
getReplacementKey() {
|
|
2672
2710
|
return "inline-editing";
|
|
2673
2711
|
}
|
|
@@ -2675,7 +2713,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2675
2713
|
return Object.keys(INLINE_EDITING_PROPERTY_PER_TYPE);
|
|
2676
2714
|
}
|
|
2677
2715
|
isEditingModeActive() {
|
|
2678
|
-
return
|
|
2716
|
+
return this.editing;
|
|
2679
2717
|
}
|
|
2680
2718
|
shouldRenderReplacement() {
|
|
2681
2719
|
return this.isInlineEditingEligible() && getCurrentEditMode() === "edit";
|
|
@@ -2718,8 +2756,8 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2718
2756
|
resetInlineEditorRoot() {
|
|
2719
2757
|
this.element.removeEventListener("click", this.handleRenderInlineEditor);
|
|
2720
2758
|
this.handlerAttached = false;
|
|
2721
|
-
this.
|
|
2722
|
-
this.
|
|
2759
|
+
this.reactRoot.render(null);
|
|
2760
|
+
this.editing = false;
|
|
2723
2761
|
}
|
|
2724
2762
|
unmountInlineEditor() {
|
|
2725
2763
|
this.resetInlineEditorRoot();
|
|
@@ -2830,12 +2868,16 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2830
2868
|
if (this.isEditingModeActive()) {
|
|
2831
2869
|
this.resetInlineEditorRoot();
|
|
2832
2870
|
}
|
|
2833
|
-
const
|
|
2871
|
+
const contentElement = this.element.children?.[0];
|
|
2872
|
+
if (!contentElement) {
|
|
2873
|
+
return;
|
|
2874
|
+
}
|
|
2875
|
+
const elementClasses = contentElement.classList.toString();
|
|
2834
2876
|
const propValue = this.getExtractedContentValue();
|
|
2835
2877
|
const expectedTag = this.getExpectedTag();
|
|
2836
|
-
|
|
2837
|
-
this.
|
|
2838
|
-
this.
|
|
2878
|
+
contentElement.innerHTML = "";
|
|
2879
|
+
this.editing = true;
|
|
2880
|
+
this.reactRoot.render(
|
|
2839
2881
|
/* @__PURE__ */ React6.createElement(
|
|
2840
2882
|
CanvasInlineEditor,
|
|
2841
2883
|
{
|
|
@@ -2843,9 +2885,10 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2843
2885
|
initialValue: propValue,
|
|
2844
2886
|
expectedTag,
|
|
2845
2887
|
rootElement: this.element,
|
|
2888
|
+
contentElement,
|
|
2846
2889
|
id: this.id,
|
|
2847
2890
|
setValue: this.setContentValue.bind(this),
|
|
2848
|
-
|
|
2891
|
+
requestDestroy: this.unmountInlineEditor.bind(this)
|
|
2849
2892
|
}
|
|
2850
2893
|
)
|
|
2851
2894
|
);
|
|
@@ -2874,16 +2917,24 @@ var createViewWithReplacements = (options) => {
|
|
|
2874
2917
|
return class extends TemplatedView {
|
|
2875
2918
|
#replacement = null;
|
|
2876
2919
|
#config;
|
|
2920
|
+
#reactContainer;
|
|
2921
|
+
#reactRoot;
|
|
2877
2922
|
constructor(...args) {
|
|
2878
2923
|
super(...args);
|
|
2879
2924
|
const settings = this.model.get("settings");
|
|
2925
|
+
this.#reactContainer = this.el.ownerDocument.createElement("div");
|
|
2926
|
+
this.#reactContainer.style.display = "none";
|
|
2927
|
+
this.el.ownerDocument.body.appendChild(this.#reactContainer);
|
|
2928
|
+
this.#reactRoot = createRoot(this.#reactContainer);
|
|
2880
2929
|
this.#config = {
|
|
2881
2930
|
getSetting: settings.get.bind(settings),
|
|
2882
2931
|
setSetting: settings.set.bind(settings),
|
|
2883
2932
|
element: this.el,
|
|
2884
2933
|
type: this?.model?.get("widgetType") ?? this.container?.model?.get("elType") ?? null,
|
|
2885
2934
|
id: this?.model?.get("id") ?? null,
|
|
2886
|
-
refreshView: this.refreshView.bind(this)
|
|
2935
|
+
refreshView: this.refreshView.bind(this),
|
|
2936
|
+
reactRoot: this.#reactRoot,
|
|
2937
|
+
reactContainer: this.#reactContainer
|
|
2887
2938
|
};
|
|
2888
2939
|
}
|
|
2889
2940
|
refreshView() {
|
|
@@ -2904,6 +2955,8 @@ var createViewWithReplacements = (options) => {
|
|
|
2904
2955
|
}
|
|
2905
2956
|
onDestroy() {
|
|
2906
2957
|
this.#triggerAltMethod("onDestroy");
|
|
2958
|
+
this.#reactRoot.unmount();
|
|
2959
|
+
this.#reactContainer.remove();
|
|
2907
2960
|
}
|
|
2908
2961
|
_afterRender() {
|
|
2909
2962
|
this.#triggerAltMethod("_afterRender");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-canvas",
|
|
3
3
|
"description": "Elementor Editor Canvas",
|
|
4
|
-
"version": "4.1.0-
|
|
4
|
+
"version": "4.1.0-741",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -37,25 +37,25 @@
|
|
|
37
37
|
"react-dom": "^18.3.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@elementor/editor": "4.1.0-
|
|
40
|
+
"@elementor/editor": "4.1.0-741",
|
|
41
41
|
"dompurify": "^3.2.6",
|
|
42
|
-
"@elementor/editor-controls": "4.1.0-
|
|
43
|
-
"@elementor/editor-documents": "4.1.0-
|
|
44
|
-
"@elementor/editor-elements": "4.1.0-
|
|
45
|
-
"@elementor/editor-interactions": "4.1.0-
|
|
46
|
-
"@elementor/editor-mcp": "4.1.0-
|
|
47
|
-
"@elementor/editor-notifications": "4.1.0-
|
|
48
|
-
"@elementor/editor-props": "4.1.0-
|
|
49
|
-
"@elementor/editor-responsive": "4.1.0-
|
|
50
|
-
"@elementor/editor-styles": "4.1.0-
|
|
51
|
-
"@elementor/editor-styles-repository": "4.1.0-
|
|
52
|
-
"@elementor/editor-ui": "4.1.0-
|
|
53
|
-
"@elementor/editor-v1-adapters": "4.1.0-
|
|
54
|
-
"@elementor/schema": "4.1.0-
|
|
55
|
-
"@elementor/twing": "4.1.0-
|
|
42
|
+
"@elementor/editor-controls": "4.1.0-741",
|
|
43
|
+
"@elementor/editor-documents": "4.1.0-741",
|
|
44
|
+
"@elementor/editor-elements": "4.1.0-741",
|
|
45
|
+
"@elementor/editor-interactions": "4.1.0-741",
|
|
46
|
+
"@elementor/editor-mcp": "4.1.0-741",
|
|
47
|
+
"@elementor/editor-notifications": "4.1.0-741",
|
|
48
|
+
"@elementor/editor-props": "4.1.0-741",
|
|
49
|
+
"@elementor/editor-responsive": "4.1.0-741",
|
|
50
|
+
"@elementor/editor-styles": "4.1.0-741",
|
|
51
|
+
"@elementor/editor-styles-repository": "4.1.0-741",
|
|
52
|
+
"@elementor/editor-ui": "4.1.0-741",
|
|
53
|
+
"@elementor/editor-v1-adapters": "4.1.0-741",
|
|
54
|
+
"@elementor/schema": "4.1.0-741",
|
|
55
|
+
"@elementor/twing": "4.1.0-741",
|
|
56
56
|
"@elementor/ui": "1.36.17",
|
|
57
|
-
"@elementor/utils": "4.1.0-
|
|
58
|
-
"@elementor/wp-media": "4.1.0-
|
|
57
|
+
"@elementor/utils": "4.1.0-741",
|
|
58
|
+
"@elementor/wp-media": "4.1.0-741",
|
|
59
59
|
"@floating-ui/react": "^0.27.5",
|
|
60
60
|
"@wordpress/i18n": "^5.13.0"
|
|
61
61
|
},
|
|
@@ -26,6 +26,8 @@ export class ReplacementBase implements ReplacementBaseInterface {
|
|
|
26
26
|
protected type: ReplacementSettings[ 'type' ];
|
|
27
27
|
protected id: ReplacementSettings[ 'id' ];
|
|
28
28
|
protected refreshView: ReplacementSettings[ 'refreshView' ];
|
|
29
|
+
protected reactRoot: ReplacementSettings[ 'reactRoot' ];
|
|
30
|
+
protected reactContainer: ReplacementSettings[ 'reactContainer' ];
|
|
29
31
|
|
|
30
32
|
constructor( settings: ReplacementSettings ) {
|
|
31
33
|
this.getSetting = settings.getSetting;
|
|
@@ -34,6 +36,8 @@ export class ReplacementBase implements ReplacementBaseInterface {
|
|
|
34
36
|
this.type = settings.type;
|
|
35
37
|
this.id = settings.id;
|
|
36
38
|
this.refreshView = settings.refreshView;
|
|
39
|
+
this.reactRoot = settings.reactRoot;
|
|
40
|
+
this.reactContainer = settings.reactContainer;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
static getTypes(): string[] | null {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useEffect, useLayoutEffect, useState } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useLayoutEffect, useState } from 'react';
|
|
3
3
|
import { InlineEditor, InlineEditorToolbar } from '@elementor/editor-controls';
|
|
4
4
|
import { Box, ThemeProvider } from '@elementor/ui';
|
|
5
5
|
import { autoUpdate, flip, FloatingPortal, useFloating } from '@floating-ui/react';
|
|
@@ -9,68 +9,83 @@ import {
|
|
|
9
9
|
type Editor,
|
|
10
10
|
getInlineEditorElement,
|
|
11
11
|
horizontalShifterMiddleware as horizontalShifter,
|
|
12
|
-
removeToolbarAnchor,
|
|
13
12
|
useOnClickOutsideIframe,
|
|
14
13
|
useRenderToolbar,
|
|
15
14
|
} from './inline-editing-utils';
|
|
16
15
|
|
|
17
|
-
const EDITOR_WRAPPER_SELECTOR = 'inline-editor-wrapper';
|
|
18
|
-
|
|
19
16
|
export const CanvasInlineEditor = ( {
|
|
20
17
|
elementClasses,
|
|
21
18
|
initialValue,
|
|
22
19
|
expectedTag,
|
|
23
20
|
rootElement,
|
|
21
|
+
contentElement,
|
|
24
22
|
id,
|
|
25
23
|
setValue,
|
|
26
|
-
|
|
24
|
+
requestDestroy,
|
|
27
25
|
}: {
|
|
28
26
|
elementClasses: string;
|
|
29
27
|
initialValue: string | null;
|
|
30
28
|
expectedTag: string | null;
|
|
31
29
|
rootElement: HTMLElement;
|
|
30
|
+
contentElement: HTMLElement;
|
|
32
31
|
id: string;
|
|
33
32
|
setValue: ( value: string | null ) => void;
|
|
34
|
-
|
|
33
|
+
requestDestroy: () => void;
|
|
35
34
|
} ) => {
|
|
35
|
+
const [ active, setActive ] = useState( true );
|
|
36
36
|
const [ editor, setEditor ] = useState< Editor | null >( null );
|
|
37
|
-
const { onSelectionEnd, anchor: toolbarAnchor } = useRenderToolbar( rootElement.ownerDocument, id );
|
|
37
|
+
const { onSelectionEnd, anchor: toolbarAnchor, clearAnchor } = useRenderToolbar( rootElement.ownerDocument, id );
|
|
38
|
+
|
|
39
|
+
useEffect( () => {
|
|
40
|
+
if ( ! active ) {
|
|
41
|
+
clearAnchor();
|
|
42
|
+
requestDestroy();
|
|
43
|
+
}
|
|
44
|
+
}, [ active, clearAnchor, requestDestroy ] );
|
|
45
|
+
|
|
46
|
+
const dismiss = useCallback( () => {
|
|
47
|
+
setEditor( null );
|
|
48
|
+
setActive( false );
|
|
49
|
+
}, [] );
|
|
38
50
|
|
|
39
|
-
|
|
40
|
-
removeToolbarAnchor( rootElement.ownerDocument, id );
|
|
51
|
+
useOnClickOutsideIframe( dismiss );
|
|
41
52
|
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
useEffect( () => {
|
|
54
|
+
const ownerDocument = contentElement.ownerDocument;
|
|
55
|
+
|
|
56
|
+
const handleClickAway = ( event: MouseEvent ) => {
|
|
57
|
+
if ( contentElement.contains( event.target as Node ) ) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
44
60
|
|
|
45
|
-
|
|
61
|
+
dismiss();
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
ownerDocument.addEventListener( 'mousedown', handleClickAway );
|
|
65
|
+
|
|
66
|
+
return () => ownerDocument.removeEventListener( 'mousedown', handleClickAway );
|
|
67
|
+
}, [ contentElement, dismiss ] );
|
|
68
|
+
|
|
69
|
+
if ( ! active ) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
46
72
|
|
|
47
73
|
return (
|
|
48
74
|
<ThemeProvider>
|
|
49
75
|
<InlineEditingOverlay expectedTag={ expectedTag } rootElement={ rootElement } id={ id } />
|
|
50
|
-
<style>
|
|
51
|
-
{ `
|
|
52
|
-
.ProseMirror > * {
|
|
53
|
-
height: 100%;
|
|
54
|
-
}
|
|
55
|
-
.${ EDITOR_WRAPPER_SELECTOR } .ProseMirror > button[contenteditable="true"] {
|
|
56
|
-
height: auto;
|
|
57
|
-
cursor: text;
|
|
58
|
-
}
|
|
59
|
-
` }
|
|
60
|
-
</style>
|
|
61
76
|
<InlineEditor
|
|
62
77
|
onEditorCreate={ setEditor }
|
|
78
|
+
mountElement={ contentElement }
|
|
63
79
|
editorProps={ {
|
|
64
80
|
attributes: {
|
|
65
|
-
style: 'outline: none;
|
|
81
|
+
style: 'outline: none; display: inherit; justify-content: inherit; align-items: inherit; flex-direction: inherit; text-align: inherit;',
|
|
66
82
|
},
|
|
67
83
|
} }
|
|
68
84
|
elementClasses={ elementClasses }
|
|
69
85
|
value={ initialValue }
|
|
70
86
|
setValue={ setValue }
|
|
71
|
-
onBlur={
|
|
87
|
+
onBlur={ dismiss }
|
|
72
88
|
autofocus
|
|
73
|
-
expectedTag={ expectedTag }
|
|
74
89
|
onSelectionEnd={ onSelectionEnd }
|
|
75
90
|
/>
|
|
76
91
|
{ toolbarAnchor && editor && <InlineEditingToolbar anchor={ toolbarAnchor } editor={ editor } id={ id } /> }
|
|
@@ -114,7 +129,14 @@ const InlineEditingToolbar = ( { anchor, editor, id }: { anchor: HTMLElement; ed
|
|
|
114
129
|
|
|
115
130
|
return (
|
|
116
131
|
<FloatingPortal id={ CANVAS_WRAPPER_ID }>
|
|
117
|
-
<Box
|
|
132
|
+
<Box
|
|
133
|
+
ref={ refs.setFloating }
|
|
134
|
+
role="presentation"
|
|
135
|
+
style={ {
|
|
136
|
+
...floatingStyles,
|
|
137
|
+
pointerEvents: 'none',
|
|
138
|
+
} }
|
|
139
|
+
>
|
|
118
140
|
<InlineEditorToolbar editor={ editor } elementId={ id } />
|
|
119
141
|
</Box>
|
|
120
142
|
</FloatingPortal>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { createRoot, type Root } from 'react-dom/client';
|
|
3
2
|
import { getContainer, getElementLabel, getElementType } from '@elementor/editor-elements';
|
|
4
3
|
import {
|
|
5
4
|
htmlV3PropTypeUtil,
|
|
@@ -25,8 +24,8 @@ type TagPropType = PropType< 'tag' > & {
|
|
|
25
24
|
const HISTORY_DEBOUNCE_WAIT = 800;
|
|
26
25
|
|
|
27
26
|
export default class InlineEditingReplacement extends ReplacementBase {
|
|
28
|
-
private inlineEditorRoot: Root | null = null;
|
|
29
27
|
private handlerAttached = false;
|
|
28
|
+
private editing = false;
|
|
30
29
|
|
|
31
30
|
getReplacementKey() {
|
|
32
31
|
return 'inline-editing';
|
|
@@ -37,7 +36,7 @@ export default class InlineEditingReplacement extends ReplacementBase {
|
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
isEditingModeActive() {
|
|
40
|
-
return
|
|
39
|
+
return this.editing;
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
shouldRenderReplacement() {
|
|
@@ -91,8 +90,8 @@ export default class InlineEditingReplacement extends ReplacementBase {
|
|
|
91
90
|
resetInlineEditorRoot() {
|
|
92
91
|
this.element.removeEventListener( 'click', this.handleRenderInlineEditor );
|
|
93
92
|
this.handlerAttached = false;
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
93
|
+
this.reactRoot.render( null );
|
|
94
|
+
this.editing = false;
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
unmountInlineEditor() {
|
|
@@ -239,22 +238,29 @@ export default class InlineEditingReplacement extends ReplacementBase {
|
|
|
239
238
|
this.resetInlineEditorRoot();
|
|
240
239
|
}
|
|
241
240
|
|
|
242
|
-
const
|
|
241
|
+
const contentElement = this.element.children?.[ 0 ] as HTMLElement | undefined;
|
|
242
|
+
|
|
243
|
+
if ( ! contentElement ) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const elementClasses = contentElement.classList.toString();
|
|
243
248
|
const propValue = this.getExtractedContentValue();
|
|
244
249
|
const expectedTag = this.getExpectedTag();
|
|
245
250
|
|
|
246
|
-
|
|
251
|
+
contentElement.innerHTML = '';
|
|
252
|
+
this.editing = true;
|
|
247
253
|
|
|
248
|
-
this.
|
|
249
|
-
this.inlineEditorRoot.render(
|
|
254
|
+
this.reactRoot.render(
|
|
250
255
|
<CanvasInlineEditor
|
|
251
256
|
elementClasses={ elementClasses }
|
|
252
257
|
initialValue={ propValue }
|
|
253
258
|
expectedTag={ expectedTag }
|
|
254
259
|
rootElement={ this.element }
|
|
260
|
+
contentElement={ contentElement }
|
|
255
261
|
id={ this.id }
|
|
256
262
|
setValue={ this.setContentValue.bind( this ) }
|
|
257
|
-
|
|
263
|
+
requestDestroy={ this.unmountInlineEditor.bind( this ) }
|
|
258
264
|
/>
|
|
259
265
|
);
|
|
260
266
|
}
|
|
@@ -80,6 +80,12 @@ export const useOnClickOutsideIframe = ( handleUnmount: () => void ) => {
|
|
|
80
80
|
export const useRenderToolbar = ( ownerDocument: Document, id: string ) => {
|
|
81
81
|
const [ anchor, setAnchor ] = useState< HTMLElement | null >( null );
|
|
82
82
|
|
|
83
|
+
useEffect( () => {
|
|
84
|
+
if ( ! anchor ) {
|
|
85
|
+
removeToolbarAnchor( ownerDocument, id );
|
|
86
|
+
}
|
|
87
|
+
}, [ anchor, ownerDocument, id ] );
|
|
88
|
+
|
|
83
89
|
const onSelectionEnd = ( view: EditorView ) => {
|
|
84
90
|
const hasSelection = ! view.state.selection.empty;
|
|
85
91
|
|
|
@@ -92,7 +98,11 @@ export const useRenderToolbar = ( ownerDocument: Document, id: string ) => {
|
|
|
92
98
|
}
|
|
93
99
|
};
|
|
94
100
|
|
|
95
|
-
|
|
101
|
+
const clearAnchor = useCallback( () => {
|
|
102
|
+
setAnchor( null );
|
|
103
|
+
}, [] );
|
|
104
|
+
|
|
105
|
+
return { onSelectionEnd, anchor, clearAnchor };
|
|
96
106
|
};
|
|
97
107
|
|
|
98
108
|
const createAnchorBasedOnSelection = ( ownerDocument: Document, id: string ): HTMLElement | null => {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createRoot, type Root } from 'react-dom/client';
|
|
2
|
+
|
|
1
3
|
import type { CreateTemplatedElementTypeOptions } from '../create-templated-element-type';
|
|
2
4
|
import { createTemplatedElementView } from '../create-templated-element-type';
|
|
3
5
|
import type { ElementType, ElementView, LegacyWindow, ReplacementSettings } from '../types';
|
|
@@ -34,11 +36,18 @@ export const createViewWithReplacements = ( options: CreateTemplatedElementTypeO
|
|
|
34
36
|
return class extends TemplatedView {
|
|
35
37
|
#replacement: ReplacementBaseInterface | null = null;
|
|
36
38
|
#config: ReplacementSettings;
|
|
39
|
+
#reactContainer: HTMLElement;
|
|
40
|
+
#reactRoot: Root;
|
|
37
41
|
|
|
38
42
|
constructor( ...args: unknown[] ) {
|
|
39
43
|
super( ...args );
|
|
40
44
|
const settings = this.model.get( 'settings' );
|
|
41
45
|
|
|
46
|
+
this.#reactContainer = this.el.ownerDocument.createElement( 'div' );
|
|
47
|
+
this.#reactContainer.style.display = 'none';
|
|
48
|
+
this.el.ownerDocument.body.appendChild( this.#reactContainer );
|
|
49
|
+
this.#reactRoot = createRoot( this.#reactContainer );
|
|
50
|
+
|
|
42
51
|
this.#config = {
|
|
43
52
|
getSetting: settings.get.bind( settings ),
|
|
44
53
|
setSetting: settings.set.bind( settings ),
|
|
@@ -46,6 +55,8 @@ export const createViewWithReplacements = ( options: CreateTemplatedElementTypeO
|
|
|
46
55
|
type: this?.model?.get( 'widgetType' ) ?? this.container?.model?.get( 'elType' ) ?? null,
|
|
47
56
|
id: this?.model?.get( 'id' ) ?? null,
|
|
48
57
|
refreshView: this.refreshView.bind( this ),
|
|
58
|
+
reactRoot: this.#reactRoot,
|
|
59
|
+
reactContainer: this.#reactContainer,
|
|
49
60
|
};
|
|
50
61
|
}
|
|
51
62
|
|
|
@@ -72,6 +83,8 @@ export const createViewWithReplacements = ( options: CreateTemplatedElementTypeO
|
|
|
72
83
|
|
|
73
84
|
onDestroy() {
|
|
74
85
|
this.#triggerAltMethod( 'onDestroy' );
|
|
86
|
+
this.#reactRoot.unmount();
|
|
87
|
+
this.#reactContainer.remove();
|
|
75
88
|
}
|
|
76
89
|
|
|
77
90
|
_afterRender() {
|
package/src/legacy/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Root } from 'react-dom/client';
|
|
1
2
|
import { type V1Element } from '@elementor/editor-elements';
|
|
2
3
|
import { type Props, type PropValue } from '@elementor/editor-props';
|
|
3
4
|
|
|
@@ -241,4 +242,6 @@ export type ReplacementSettings = {
|
|
|
241
242
|
id: string;
|
|
242
243
|
element: HTMLElement;
|
|
243
244
|
refreshView: () => void;
|
|
245
|
+
reactRoot: Root;
|
|
246
|
+
reactContainer: HTMLElement;
|
|
244
247
|
};
|