@elementor/editor-canvas 4.4.0-1134 → 4.4.0-1136
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.js +101 -74
- package/dist/index.mjs +46 -19
- package/package.json +21 -21
- package/src/form-structure/__tests__/form-structure-utils.test.ts +10 -0
- package/src/form-structure/__tests__/hidden-field-hint.test.ts +137 -0
- package/src/form-structure/hidden-field-hint.ts +29 -0
- package/src/form-structure/utils.ts +2 -0
- package/src/init.tsx +2 -0
package/dist/index.js
CHANGED
|
@@ -1795,6 +1795,7 @@ var import_i18n = require("@wordpress/i18n");
|
|
|
1795
1795
|
// src/form-structure/utils.ts
|
|
1796
1796
|
var import_editor_elements4 = require("@elementor/editor-elements");
|
|
1797
1797
|
var FORM_ELEMENT_TYPE = "e-form";
|
|
1798
|
+
var FORM_HIDDEN_FIELD_ELEMENT_TYPE = "e-form-hidden";
|
|
1798
1799
|
var FORM_FIELD_ELEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
1799
1800
|
"e-form-input",
|
|
1800
1801
|
"e-form-textarea",
|
|
@@ -1805,7 +1806,8 @@ var FORM_FIELD_ELEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
1805
1806
|
"e-form-radio-button",
|
|
1806
1807
|
"e-form-file-upload",
|
|
1807
1808
|
"e-form-date-picker",
|
|
1808
|
-
"e-form-time-picker"
|
|
1809
|
+
"e-form-time-picker",
|
|
1810
|
+
FORM_HIDDEN_FIELD_ELEMENT_TYPE
|
|
1809
1811
|
]);
|
|
1810
1812
|
function getArgsElementType(args) {
|
|
1811
1813
|
return args.model?.widgetType || args.model?.elType;
|
|
@@ -1922,25 +1924,49 @@ function handleBlockedFormField() {
|
|
|
1922
1924
|
(0, import_editor_notifications.notify)(FORM_FIELDS_OUTSIDE_ALERT);
|
|
1923
1925
|
}
|
|
1924
1926
|
|
|
1925
|
-
// src/form-structure/
|
|
1927
|
+
// src/form-structure/hidden-field-hint.ts
|
|
1926
1928
|
var import_editor_notifications2 = require("@elementor/editor-notifications");
|
|
1927
1929
|
var import_editor_v1_adapters12 = require("@elementor/editor-v1-adapters");
|
|
1928
1930
|
var import_i18n2 = require("@wordpress/i18n");
|
|
1931
|
+
var MOVE_COMMAND = "document/elements/move";
|
|
1932
|
+
var notificationCounter = 0;
|
|
1933
|
+
function createHiddenFieldNotification() {
|
|
1934
|
+
return {
|
|
1935
|
+
type: "default",
|
|
1936
|
+
message: (0, import_i18n2.__)("Hidden field added - invisible on your form. Manage it in the Structure panel.", "elementor"),
|
|
1937
|
+
id: `hidden-field-added-${++notificationCounter}`
|
|
1938
|
+
};
|
|
1939
|
+
}
|
|
1940
|
+
function initHiddenFieldHint() {
|
|
1941
|
+
(0, import_editor_v1_adapters12.registerDataHook)("after", "document/elements/create", (args, _result, options) => {
|
|
1942
|
+
if (options?.commandsCurrentTrace?.includes(MOVE_COMMAND)) {
|
|
1943
|
+
return;
|
|
1944
|
+
}
|
|
1945
|
+
if (getArgsElementType(args) === FORM_HIDDEN_FIELD_ELEMENT_TYPE) {
|
|
1946
|
+
(0, import_editor_notifications2.notify)(createHiddenFieldNotification());
|
|
1947
|
+
}
|
|
1948
|
+
});
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
// src/form-structure/prevent-form-nesting-commands.ts
|
|
1952
|
+
var import_editor_notifications3 = require("@elementor/editor-notifications");
|
|
1953
|
+
var import_editor_v1_adapters13 = require("@elementor/editor-v1-adapters");
|
|
1954
|
+
var import_i18n3 = require("@wordpress/i18n");
|
|
1929
1955
|
var FORM_NESTING_ALERT = {
|
|
1930
1956
|
type: "default",
|
|
1931
|
-
message: (0,
|
|
1957
|
+
message: (0, import_i18n3.__)("Forms can't be nested. Create separate forms instead.", "elementor"),
|
|
1932
1958
|
id: "form-nesting-blocked"
|
|
1933
1959
|
};
|
|
1934
1960
|
function initFormNestingPrevention() {
|
|
1935
|
-
(0,
|
|
1961
|
+
(0, import_editor_v1_adapters13.blockCommand)({
|
|
1936
1962
|
command: "document/elements/create",
|
|
1937
1963
|
condition: blockFormCreate
|
|
1938
1964
|
});
|
|
1939
|
-
(0,
|
|
1965
|
+
(0, import_editor_v1_adapters13.blockCommand)({
|
|
1940
1966
|
command: "document/elements/move",
|
|
1941
1967
|
condition: blockFormMove
|
|
1942
1968
|
});
|
|
1943
|
-
(0,
|
|
1969
|
+
(0, import_editor_v1_adapters13.blockCommand)({
|
|
1944
1970
|
command: "document/elements/paste",
|
|
1945
1971
|
condition: blockFormPaste
|
|
1946
1972
|
});
|
|
@@ -1984,7 +2010,7 @@ function blockFormPaste(args) {
|
|
|
1984
2010
|
return false;
|
|
1985
2011
|
}
|
|
1986
2012
|
function handleBlockedFormField2() {
|
|
1987
|
-
(0,
|
|
2013
|
+
(0, import_editor_notifications3.notify)(FORM_NESTING_ALERT);
|
|
1988
2014
|
}
|
|
1989
2015
|
|
|
1990
2016
|
// src/settings-transformers-registry.ts
|
|
@@ -2674,7 +2700,7 @@ function initStyleTransformers() {
|
|
|
2674
2700
|
|
|
2675
2701
|
// src/legacy/init-legacy-views.ts
|
|
2676
2702
|
var import_editor_elements8 = require("@elementor/editor-elements");
|
|
2677
|
-
var
|
|
2703
|
+
var import_editor_v1_adapters15 = require("@elementor/editor-v1-adapters");
|
|
2678
2704
|
|
|
2679
2705
|
// src/renderers/create-dom-renderer.ts
|
|
2680
2706
|
var import_twing = require("@elementor/twing");
|
|
@@ -3425,8 +3451,8 @@ var import_client = require("react-dom/client");
|
|
|
3425
3451
|
var React11 = __toESM(require("react"));
|
|
3426
3452
|
var import_editor_elements7 = require("@elementor/editor-elements");
|
|
3427
3453
|
var import_editor_props4 = require("@elementor/editor-props");
|
|
3428
|
-
var
|
|
3429
|
-
var
|
|
3454
|
+
var import_editor_v1_adapters14 = require("@elementor/editor-v1-adapters");
|
|
3455
|
+
var import_i18n4 = require("@wordpress/i18n");
|
|
3430
3456
|
|
|
3431
3457
|
// src/legacy/replacements/base.ts
|
|
3432
3458
|
var TRIGGER_TIMING = {
|
|
@@ -3743,7 +3769,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3743
3769
|
return this.editing;
|
|
3744
3770
|
}
|
|
3745
3771
|
shouldRenderReplacement() {
|
|
3746
|
-
return this.isInlineEditingEligible() && (0,
|
|
3772
|
+
return this.isInlineEditingEligible() && (0, import_editor_v1_adapters14.getCurrentEditMode)() === "edit";
|
|
3747
3773
|
}
|
|
3748
3774
|
handleRenderInlineEditor = () => {
|
|
3749
3775
|
if (this.isEditingModeActive() || !this.isInlineEditingEligible()) {
|
|
@@ -3830,7 +3856,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3830
3856
|
setContentValue(value) {
|
|
3831
3857
|
const settingKey = this.getInlineEditablePropertyName();
|
|
3832
3858
|
const valueToSave = this.createContentPropValue(value);
|
|
3833
|
-
(0,
|
|
3859
|
+
(0, import_editor_v1_adapters14.undoable)(
|
|
3834
3860
|
{
|
|
3835
3861
|
do: () => {
|
|
3836
3862
|
const prevValue = this.getInlineEditablePropValue();
|
|
@@ -3844,7 +3870,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3844
3870
|
{
|
|
3845
3871
|
title: (0, import_editor_elements7.getElementLabel)(this.id),
|
|
3846
3872
|
// translators: %s is the name of the property that was edited.
|
|
3847
|
-
subtitle: (0,
|
|
3873
|
+
subtitle: (0, import_i18n4.__)("%s edited", "elementor").replace(
|
|
3848
3874
|
"%s",
|
|
3849
3875
|
this.getInlineEditablePropTypeKey() ?? "Inline editing"
|
|
3850
3876
|
),
|
|
@@ -3872,7 +3898,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3872
3898
|
return null;
|
|
3873
3899
|
}
|
|
3874
3900
|
runCommand(key, value) {
|
|
3875
|
-
(0,
|
|
3901
|
+
(0, import_editor_v1_adapters14.__privateRunCommandSync)(
|
|
3876
3902
|
"document/elements/set-settings",
|
|
3877
3903
|
{
|
|
3878
3904
|
container: (0, import_editor_elements7.getContainer)(this.id),
|
|
@@ -3882,7 +3908,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3882
3908
|
},
|
|
3883
3909
|
{ internal: true }
|
|
3884
3910
|
);
|
|
3885
|
-
(0,
|
|
3911
|
+
(0, import_editor_v1_adapters14.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
|
|
3886
3912
|
}
|
|
3887
3913
|
getExpectedTag() {
|
|
3888
3914
|
const tagPropType = this.getTagPropType();
|
|
@@ -4047,12 +4073,12 @@ function registerModelExtensions(type, extensions) {
|
|
|
4047
4073
|
}
|
|
4048
4074
|
function registerElementType(type, elementTypeGenerator) {
|
|
4049
4075
|
elementsLegacyTypes[type] = elementTypeGenerator;
|
|
4050
|
-
if ((0,
|
|
4076
|
+
if ((0, import_editor_v1_adapters15.__privateIsReady)()) {
|
|
4051
4077
|
registerElementInLegacyManager(type, createDomRenderer());
|
|
4052
4078
|
}
|
|
4053
4079
|
}
|
|
4054
4080
|
function initLegacyViews() {
|
|
4055
|
-
(0,
|
|
4081
|
+
(0, import_editor_v1_adapters15.__privateListenTo)((0, import_editor_v1_adapters15.v1ReadyEvent)(), () => {
|
|
4056
4082
|
const widgetsCache = (0, import_editor_elements8.getWidgetsCache)() ?? {};
|
|
4057
4083
|
const renderer = createDomRenderer();
|
|
4058
4084
|
registerProPromotionTypes(widgetsCache);
|
|
@@ -4190,9 +4216,9 @@ function initTabsModelExtensions() {
|
|
|
4190
4216
|
var import_editor_props8 = require("@elementor/editor-props");
|
|
4191
4217
|
|
|
4192
4218
|
// src/mcp/icon-library-experiment.ts
|
|
4193
|
-
var
|
|
4219
|
+
var import_editor_v1_adapters16 = require("@elementor/editor-v1-adapters");
|
|
4194
4220
|
var ICON_LIBRARY_EXPERIMENT = "e_svg_library";
|
|
4195
|
-
var isIconLibraryActive = () => (0,
|
|
4221
|
+
var isIconLibraryActive = () => (0, import_editor_v1_adapters16.isExperimentActive)(ICON_LIBRARY_EXPERIMENT);
|
|
4196
4222
|
|
|
4197
4223
|
// src/mcp/resources/available-widgets-resource.ts
|
|
4198
4224
|
var import_http_client3 = require("@elementor/http-client");
|
|
@@ -4270,7 +4296,7 @@ var initBestPracticesResource = (reg) => {
|
|
|
4270
4296
|
|
|
4271
4297
|
// src/mcp/resources/document-structure-resource.ts
|
|
4272
4298
|
var import_editor_elements9 = require("@elementor/editor-elements");
|
|
4273
|
-
var
|
|
4299
|
+
var import_editor_v1_adapters17 = require("@elementor/editor-v1-adapters");
|
|
4274
4300
|
var DOCUMENT_STRUCTURE_URI = "elementor://document/structure";
|
|
4275
4301
|
var initDocumentStructureResource = (reg) => {
|
|
4276
4302
|
const { resource, sendResourceUpdated } = reg;
|
|
@@ -4283,15 +4309,15 @@ var initDocumentStructureResource = (reg) => {
|
|
|
4283
4309
|
sendResourceUpdated({ uri: DOCUMENT_STRUCTURE_URI });
|
|
4284
4310
|
}
|
|
4285
4311
|
};
|
|
4286
|
-
(0,
|
|
4312
|
+
(0, import_editor_v1_adapters17.__privateListenTo)(
|
|
4287
4313
|
[
|
|
4288
|
-
(0,
|
|
4289
|
-
(0,
|
|
4290
|
-
(0,
|
|
4291
|
-
(0,
|
|
4292
|
-
(0,
|
|
4293
|
-
(0,
|
|
4294
|
-
(0,
|
|
4314
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("document/elements/create"),
|
|
4315
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("document/elements/delete"),
|
|
4316
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("document/elements/move"),
|
|
4317
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("document/elements/copy"),
|
|
4318
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("document/elements/paste"),
|
|
4319
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("editor/documents/attach-preview"),
|
|
4320
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("editor/documents/switch")
|
|
4295
4321
|
],
|
|
4296
4322
|
updateDocumentStructure
|
|
4297
4323
|
);
|
|
@@ -4394,7 +4420,7 @@ var initDynamicTagsResource = (reg) => {
|
|
|
4394
4420
|
};
|
|
4395
4421
|
|
|
4396
4422
|
// src/mcp/resources/editor-state-resource.ts
|
|
4397
|
-
var
|
|
4423
|
+
var import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
|
|
4398
4424
|
var CURRENTLY_VIEWED_SCREEN = "The user is currently viewing the Elementor editor";
|
|
4399
4425
|
var PAGE_CONTENT_CHARACTER_LIMIT = 500;
|
|
4400
4426
|
var PREVIEW_TEXT_NODE_MIN_LENGTH = 2;
|
|
@@ -4415,8 +4441,8 @@ var initEditorStateResource = (reg) => {
|
|
|
4415
4441
|
lastSerializedState = serialized;
|
|
4416
4442
|
sendResourceUpdated({ uri: EDITOR_STATE_URI });
|
|
4417
4443
|
};
|
|
4418
|
-
(0,
|
|
4419
|
-
[(0,
|
|
4444
|
+
(0, import_editor_v1_adapters18.__privateListenTo)(
|
|
4445
|
+
[(0, import_editor_v1_adapters18.commandEndEvent)("editor/documents/switch"), (0, import_editor_v1_adapters18.commandEndEvent)("editor/documents/attach-preview")],
|
|
4420
4446
|
notifyIfChanged
|
|
4421
4447
|
);
|
|
4422
4448
|
lastSerializedState = JSON.stringify(buildState());
|
|
@@ -4490,7 +4516,7 @@ function getPageTitle() {
|
|
|
4490
4516
|
}
|
|
4491
4517
|
|
|
4492
4518
|
// src/mcp/resources/general-context-resource.ts
|
|
4493
|
-
var
|
|
4519
|
+
var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
|
|
4494
4520
|
var GENERAL_CONTEXT_URI = "elementor://context/general";
|
|
4495
4521
|
var initGeneralContextResource = (reg) => {
|
|
4496
4522
|
const { resource, sendResourceUpdated } = reg;
|
|
@@ -4551,11 +4577,11 @@ var initGeneralContextResource = (reg) => {
|
|
|
4551
4577
|
};
|
|
4552
4578
|
}
|
|
4553
4579
|
);
|
|
4554
|
-
(0,
|
|
4580
|
+
(0, import_editor_v1_adapters19.__privateListenTo)(
|
|
4555
4581
|
[
|
|
4556
|
-
(0,
|
|
4557
|
-
(0,
|
|
4558
|
-
(0,
|
|
4582
|
+
(0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/switch"),
|
|
4583
|
+
(0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/attach-preview"),
|
|
4584
|
+
(0, import_editor_v1_adapters19.commandEndEvent)("document/elements/settings")
|
|
4559
4585
|
],
|
|
4560
4586
|
pushUpdateIfChanged
|
|
4561
4587
|
);
|
|
@@ -4564,7 +4590,7 @@ var initGeneralContextResource = (reg) => {
|
|
|
4564
4590
|
|
|
4565
4591
|
// src/mcp/resources/selected-element-resource.ts
|
|
4566
4592
|
var import_editor_elements10 = require("@elementor/editor-elements");
|
|
4567
|
-
var
|
|
4593
|
+
var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
|
|
4568
4594
|
var SELECTED_ELEMENT_URI = "elementor://context/selected-element";
|
|
4569
4595
|
var initSelectedElementResource = (reg) => {
|
|
4570
4596
|
const { resource, sendResourceUpdated } = reg;
|
|
@@ -4595,11 +4621,11 @@ var initSelectedElementResource = (reg) => {
|
|
|
4595
4621
|
}
|
|
4596
4622
|
publishIfChanged(readSelectionFromEditor());
|
|
4597
4623
|
};
|
|
4598
|
-
(0,
|
|
4624
|
+
(0, import_editor_v1_adapters20.__privateListenTo)(
|
|
4599
4625
|
[
|
|
4600
|
-
(0,
|
|
4601
|
-
(0,
|
|
4602
|
-
(0,
|
|
4626
|
+
(0, import_editor_v1_adapters20.commandEndEvent)("document/elements/select"),
|
|
4627
|
+
(0, import_editor_v1_adapters20.commandEndEvent)("document/elements/deselect-all"),
|
|
4628
|
+
(0, import_editor_v1_adapters20.commandEndEvent)("document/elements/settings")
|
|
4603
4629
|
],
|
|
4604
4630
|
onCommand
|
|
4605
4631
|
);
|
|
@@ -4717,7 +4743,7 @@ var import_editor_props7 = require("@elementor/editor-props");
|
|
|
4717
4743
|
var import_editor_elements12 = require("@elementor/editor-elements");
|
|
4718
4744
|
var import_editor_props6 = require("@elementor/editor-props");
|
|
4719
4745
|
var import_editor_styles4 = require("@elementor/editor-styles");
|
|
4720
|
-
var
|
|
4746
|
+
var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
|
|
4721
4747
|
|
|
4722
4748
|
// src/mcp/utils/merge-custom-css.ts
|
|
4723
4749
|
var CUSTOM_CSS_SEPARATOR = "\n";
|
|
@@ -4786,11 +4812,11 @@ function resolveCanonicalPropKeys(elementType, props) {
|
|
|
4786
4812
|
}
|
|
4787
4813
|
|
|
4788
4814
|
// src/mcp/utils/resolve-dynamic-tag.ts
|
|
4789
|
-
var
|
|
4815
|
+
var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
|
|
4790
4816
|
var DYNAMIC_PROP_TYPE_KEY = "dynamic";
|
|
4791
4817
|
var OMITTED_DYNAMIC_SETTING_KEYS = ["fallback"];
|
|
4792
4818
|
var getAtomicDynamicTags = () => {
|
|
4793
|
-
const config = (0,
|
|
4819
|
+
const config = (0, import_editor_v1_adapters21.getElementorConfig)();
|
|
4794
4820
|
return config.atomicDynamicTags?.tags ?? {};
|
|
4795
4821
|
};
|
|
4796
4822
|
var getDynamicTagNamesByCategories = (categories) => {
|
|
@@ -4991,7 +5017,7 @@ Expected Schema: ${jsonSchema}`
|
|
|
4991
5017
|
},
|
|
4992
5018
|
withHistory: false
|
|
4993
5019
|
});
|
|
4994
|
-
(0,
|
|
5020
|
+
(0, import_editor_v1_adapters22.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
|
|
4995
5021
|
};
|
|
4996
5022
|
|
|
4997
5023
|
// src/mcp/tools/configure-element/prompt.ts
|
|
@@ -5601,15 +5627,15 @@ Note: The "size" property controls image resolution/loading, not visual size. Se
|
|
|
5601
5627
|
|
|
5602
5628
|
// src/prevent-link-in-link-commands.ts
|
|
5603
5629
|
var import_editor_elements14 = require("@elementor/editor-elements");
|
|
5604
|
-
var
|
|
5605
|
-
var
|
|
5606
|
-
var
|
|
5630
|
+
var import_editor_notifications4 = require("@elementor/editor-notifications");
|
|
5631
|
+
var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
|
|
5632
|
+
var import_i18n5 = require("@wordpress/i18n");
|
|
5607
5633
|
function initLinkInLinkPrevention() {
|
|
5608
|
-
(0,
|
|
5634
|
+
(0, import_editor_v1_adapters23.blockCommand)({
|
|
5609
5635
|
command: "document/elements/paste",
|
|
5610
5636
|
condition: blockLinkInLinkPaste
|
|
5611
5637
|
});
|
|
5612
|
-
(0,
|
|
5638
|
+
(0, import_editor_v1_adapters23.blockCommand)({
|
|
5613
5639
|
command: "document/elements/move",
|
|
5614
5640
|
condition: blockLinkInLinkMove
|
|
5615
5641
|
});
|
|
@@ -5637,7 +5663,7 @@ function blockLinkInLinkPaste(args) {
|
|
|
5637
5663
|
const sourceElements = data.clipboard.elements;
|
|
5638
5664
|
const notification = {
|
|
5639
5665
|
type: "default",
|
|
5640
|
-
message: (0,
|
|
5666
|
+
message: (0, import_i18n5.__)(
|
|
5641
5667
|
"To paste a link to this element, first remove the link from it's parent container.",
|
|
5642
5668
|
"elementor"
|
|
5643
5669
|
),
|
|
@@ -5646,7 +5672,7 @@ function blockLinkInLinkPaste(args) {
|
|
|
5646
5672
|
};
|
|
5647
5673
|
const blocked = shouldBlock(sourceElements, targetElements);
|
|
5648
5674
|
if (blocked) {
|
|
5649
|
-
(0,
|
|
5675
|
+
(0, import_editor_notifications4.notify)(notification);
|
|
5650
5676
|
}
|
|
5651
5677
|
return blocked;
|
|
5652
5678
|
}
|
|
@@ -5656,13 +5682,13 @@ function blockLinkInLinkMove(args) {
|
|
|
5656
5682
|
const targetElement = target;
|
|
5657
5683
|
const notification = {
|
|
5658
5684
|
type: "default",
|
|
5659
|
-
message: (0,
|
|
5685
|
+
message: (0, import_i18n5.__)("To drag a link to this element, first remove the link from it's parent container.", "elementor"),
|
|
5660
5686
|
id: "move-in-link-blocked",
|
|
5661
5687
|
additionalActionProps: [learnMoreActionProps]
|
|
5662
5688
|
};
|
|
5663
5689
|
const isBlocked = shouldBlock(sourceElements, [targetElement]);
|
|
5664
5690
|
if (isBlocked) {
|
|
5665
|
-
(0,
|
|
5691
|
+
(0, import_editor_notifications4.notify)(notification);
|
|
5666
5692
|
}
|
|
5667
5693
|
return isBlocked;
|
|
5668
5694
|
}
|
|
@@ -5685,12 +5711,12 @@ function shouldBlock(sourceElements, targetElements) {
|
|
|
5685
5711
|
// src/style-commands/paste-style.ts
|
|
5686
5712
|
var import_editor_elements17 = require("@elementor/editor-elements");
|
|
5687
5713
|
var import_editor_props10 = require("@elementor/editor-props");
|
|
5688
|
-
var
|
|
5714
|
+
var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
|
|
5689
5715
|
|
|
5690
5716
|
// src/utils/command-utils.ts
|
|
5691
5717
|
var import_editor_elements15 = require("@elementor/editor-elements");
|
|
5692
5718
|
var import_editor_props9 = require("@elementor/editor-props");
|
|
5693
|
-
var
|
|
5719
|
+
var import_i18n6 = require("@wordpress/i18n");
|
|
5694
5720
|
function hasAtomicWidgets(args) {
|
|
5695
5721
|
const { containers = [args.container] } = args;
|
|
5696
5722
|
return containers.some(isAtomicWidget);
|
|
@@ -5726,15 +5752,15 @@ function getClipboardElements(storageKey = "clipboard") {
|
|
|
5726
5752
|
}
|
|
5727
5753
|
}
|
|
5728
5754
|
function getTitleForContainers(containers) {
|
|
5729
|
-
return containers.length > 1 ? (0,
|
|
5755
|
+
return containers.length > 1 ? (0, import_i18n6.__)("Elements", "elementor") : (0, import_editor_elements15.getElementLabel)(containers[0].id);
|
|
5730
5756
|
}
|
|
5731
5757
|
|
|
5732
5758
|
// src/style-commands/undoable-actions/paste-element-style.ts
|
|
5733
5759
|
var import_editor_elements16 = require("@elementor/editor-elements");
|
|
5734
5760
|
var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
|
|
5735
|
-
var
|
|
5736
|
-
var
|
|
5737
|
-
var undoablePasteElementStyle = () => (0,
|
|
5761
|
+
var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
|
|
5762
|
+
var import_i18n7 = require("@wordpress/i18n");
|
|
5763
|
+
var undoablePasteElementStyle = () => (0, import_editor_v1_adapters24.undoable)(
|
|
5738
5764
|
{
|
|
5739
5765
|
do: ({ containers, newStyle }) => {
|
|
5740
5766
|
return containers.map((container) => {
|
|
@@ -5803,19 +5829,19 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
5803
5829
|
},
|
|
5804
5830
|
{
|
|
5805
5831
|
title: ({ containers }) => getTitleForContainers(containers),
|
|
5806
|
-
subtitle: (0,
|
|
5832
|
+
subtitle: (0, import_i18n7.__)("Style Pasted", "elementor")
|
|
5807
5833
|
}
|
|
5808
5834
|
);
|
|
5809
5835
|
|
|
5810
5836
|
// src/style-commands/paste-style.ts
|
|
5811
5837
|
function initPasteStyleCommand() {
|
|
5812
5838
|
const pasteElementStyleCommand = undoablePasteElementStyle();
|
|
5813
|
-
(0,
|
|
5839
|
+
(0, import_editor_v1_adapters25.blockCommand)({
|
|
5814
5840
|
command: "document/elements/paste-style",
|
|
5815
5841
|
condition: hasAtomicWidgets
|
|
5816
5842
|
});
|
|
5817
|
-
(0,
|
|
5818
|
-
(0,
|
|
5843
|
+
(0, import_editor_v1_adapters25.__privateListenTo)(
|
|
5844
|
+
(0, import_editor_v1_adapters25.commandStartEvent)("document/elements/paste-style"),
|
|
5819
5845
|
(e) => pasteStyles(e.args, pasteElementStyleCommand)
|
|
5820
5846
|
);
|
|
5821
5847
|
}
|
|
@@ -5866,14 +5892,14 @@ function pasteClasses(containers, classes) {
|
|
|
5866
5892
|
}
|
|
5867
5893
|
|
|
5868
5894
|
// src/style-commands/reset-style.ts
|
|
5869
|
-
var
|
|
5895
|
+
var import_editor_v1_adapters27 = require("@elementor/editor-v1-adapters");
|
|
5870
5896
|
|
|
5871
5897
|
// src/style-commands/undoable-actions/reset-element-style.ts
|
|
5872
5898
|
var import_editor_elements18 = require("@elementor/editor-elements");
|
|
5873
5899
|
var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
|
|
5874
|
-
var
|
|
5875
|
-
var
|
|
5876
|
-
var undoableResetElementStyle = () => (0,
|
|
5900
|
+
var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
|
|
5901
|
+
var import_i18n8 = require("@wordpress/i18n");
|
|
5902
|
+
var undoableResetElementStyle = () => (0, import_editor_v1_adapters26.undoable)(
|
|
5877
5903
|
{
|
|
5878
5904
|
do: ({ containers }) => {
|
|
5879
5905
|
return containers.map((container) => {
|
|
@@ -5910,19 +5936,19 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
|
|
|
5910
5936
|
},
|
|
5911
5937
|
{
|
|
5912
5938
|
title: ({ containers }) => getTitleForContainers(containers),
|
|
5913
|
-
subtitle: (0,
|
|
5939
|
+
subtitle: (0, import_i18n8.__)("Style Reset", "elementor")
|
|
5914
5940
|
}
|
|
5915
5941
|
);
|
|
5916
5942
|
|
|
5917
5943
|
// src/style-commands/reset-style.ts
|
|
5918
5944
|
function initResetStyleCommand() {
|
|
5919
5945
|
const resetElementStyles = undoableResetElementStyle();
|
|
5920
|
-
(0,
|
|
5946
|
+
(0, import_editor_v1_adapters27.blockCommand)({
|
|
5921
5947
|
command: "document/elements/reset-style",
|
|
5922
5948
|
condition: hasAtomicWidgets
|
|
5923
5949
|
});
|
|
5924
|
-
(0,
|
|
5925
|
-
(0,
|
|
5950
|
+
(0, import_editor_v1_adapters27.__privateListenTo)(
|
|
5951
|
+
(0, import_editor_v1_adapters27.commandStartEvent)("document/elements/reset-style"),
|
|
5926
5952
|
(e) => resetStyles(e.args, resetElementStyles)
|
|
5927
5953
|
);
|
|
5928
5954
|
}
|
|
@@ -5948,6 +5974,7 @@ function init() {
|
|
|
5948
5974
|
initLinkInLinkPrevention();
|
|
5949
5975
|
initFormNestingPrevention();
|
|
5950
5976
|
initFormAncestorEnforcement();
|
|
5977
|
+
initHiddenFieldHint();
|
|
5951
5978
|
initViewReplacements();
|
|
5952
5979
|
initLegacyViews();
|
|
5953
5980
|
initSettingsTransformers();
|
|
@@ -6071,9 +6098,9 @@ function getRectClipPath(rect, viewport) {
|
|
|
6071
6098
|
}
|
|
6072
6099
|
|
|
6073
6100
|
// src/hooks/use-canvas-document.ts
|
|
6074
|
-
var
|
|
6101
|
+
var import_editor_v1_adapters28 = require("@elementor/editor-v1-adapters");
|
|
6075
6102
|
function useCanvasDocument() {
|
|
6076
|
-
return (0,
|
|
6103
|
+
return (0, import_editor_v1_adapters28.__privateUseListenTo)((0, import_editor_v1_adapters28.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters28.getCanvasIframeDocument)());
|
|
6077
6104
|
}
|
|
6078
6105
|
|
|
6079
6106
|
// src/hooks/use-escape-on-canvas.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1747,6 +1747,7 @@ import { __ } from "@wordpress/i18n";
|
|
|
1747
1747
|
// src/form-structure/utils.ts
|
|
1748
1748
|
import { getAllDescendants } from "@elementor/editor-elements";
|
|
1749
1749
|
var FORM_ELEMENT_TYPE = "e-form";
|
|
1750
|
+
var FORM_HIDDEN_FIELD_ELEMENT_TYPE = "e-form-hidden";
|
|
1750
1751
|
var FORM_FIELD_ELEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
1751
1752
|
"e-form-input",
|
|
1752
1753
|
"e-form-textarea",
|
|
@@ -1757,7 +1758,8 @@ var FORM_FIELD_ELEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
1757
1758
|
"e-form-radio-button",
|
|
1758
1759
|
"e-form-file-upload",
|
|
1759
1760
|
"e-form-date-picker",
|
|
1760
|
-
"e-form-time-picker"
|
|
1761
|
+
"e-form-time-picker",
|
|
1762
|
+
FORM_HIDDEN_FIELD_ELEMENT_TYPE
|
|
1761
1763
|
]);
|
|
1762
1764
|
function getArgsElementType(args) {
|
|
1763
1765
|
return args.model?.widgetType || args.model?.elType;
|
|
@@ -1874,13 +1876,37 @@ function handleBlockedFormField() {
|
|
|
1874
1876
|
notify(FORM_FIELDS_OUTSIDE_ALERT);
|
|
1875
1877
|
}
|
|
1876
1878
|
|
|
1877
|
-
// src/form-structure/
|
|
1879
|
+
// src/form-structure/hidden-field-hint.ts
|
|
1878
1880
|
import { notify as notify2 } from "@elementor/editor-notifications";
|
|
1879
|
-
import {
|
|
1881
|
+
import { registerDataHook as registerDataHook3 } from "@elementor/editor-v1-adapters";
|
|
1880
1882
|
import { __ as __2 } from "@wordpress/i18n";
|
|
1883
|
+
var MOVE_COMMAND = "document/elements/move";
|
|
1884
|
+
var notificationCounter = 0;
|
|
1885
|
+
function createHiddenFieldNotification() {
|
|
1886
|
+
return {
|
|
1887
|
+
type: "default",
|
|
1888
|
+
message: __2("Hidden field added - invisible on your form. Manage it in the Structure panel.", "elementor"),
|
|
1889
|
+
id: `hidden-field-added-${++notificationCounter}`
|
|
1890
|
+
};
|
|
1891
|
+
}
|
|
1892
|
+
function initHiddenFieldHint() {
|
|
1893
|
+
registerDataHook3("after", "document/elements/create", (args, _result, options) => {
|
|
1894
|
+
if (options?.commandsCurrentTrace?.includes(MOVE_COMMAND)) {
|
|
1895
|
+
return;
|
|
1896
|
+
}
|
|
1897
|
+
if (getArgsElementType(args) === FORM_HIDDEN_FIELD_ELEMENT_TYPE) {
|
|
1898
|
+
notify2(createHiddenFieldNotification());
|
|
1899
|
+
}
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
// src/form-structure/prevent-form-nesting-commands.ts
|
|
1904
|
+
import { notify as notify3 } from "@elementor/editor-notifications";
|
|
1905
|
+
import { blockCommand as blockCommand2 } from "@elementor/editor-v1-adapters";
|
|
1906
|
+
import { __ as __3 } from "@wordpress/i18n";
|
|
1881
1907
|
var FORM_NESTING_ALERT = {
|
|
1882
1908
|
type: "default",
|
|
1883
|
-
message:
|
|
1909
|
+
message: __3("Forms can't be nested. Create separate forms instead.", "elementor"),
|
|
1884
1910
|
id: "form-nesting-blocked"
|
|
1885
1911
|
};
|
|
1886
1912
|
function initFormNestingPrevention() {
|
|
@@ -1936,7 +1962,7 @@ function blockFormPaste(args) {
|
|
|
1936
1962
|
return false;
|
|
1937
1963
|
}
|
|
1938
1964
|
function handleBlockedFormField2() {
|
|
1939
|
-
|
|
1965
|
+
notify3(FORM_NESTING_ALERT);
|
|
1940
1966
|
}
|
|
1941
1967
|
|
|
1942
1968
|
// src/settings-transformers-registry.ts
|
|
@@ -3393,7 +3419,7 @@ import {
|
|
|
3393
3419
|
stringPropTypeUtil as stringPropTypeUtil2
|
|
3394
3420
|
} from "@elementor/editor-props";
|
|
3395
3421
|
import { __privateRunCommandSync as runCommandSync, getCurrentEditMode, undoable } from "@elementor/editor-v1-adapters";
|
|
3396
|
-
import { __ as
|
|
3422
|
+
import { __ as __4 } from "@wordpress/i18n";
|
|
3397
3423
|
|
|
3398
3424
|
// src/legacy/replacements/base.ts
|
|
3399
3425
|
var TRIGGER_TIMING = {
|
|
@@ -3815,7 +3841,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3815
3841
|
{
|
|
3816
3842
|
title: getElementLabel(this.id),
|
|
3817
3843
|
// translators: %s is the name of the property that was edited.
|
|
3818
|
-
subtitle:
|
|
3844
|
+
subtitle: __4("%s edited", "elementor").replace(
|
|
3819
3845
|
"%s",
|
|
3820
3846
|
this.getInlineEditablePropTypeKey() ?? "Inline editing"
|
|
3821
3847
|
),
|
|
@@ -5587,9 +5613,9 @@ import {
|
|
|
5587
5613
|
getAnchoredDescendantId,
|
|
5588
5614
|
isElementAnchored
|
|
5589
5615
|
} from "@elementor/editor-elements";
|
|
5590
|
-
import { notify as
|
|
5616
|
+
import { notify as notify4 } from "@elementor/editor-notifications";
|
|
5591
5617
|
import { blockCommand as blockCommand3 } from "@elementor/editor-v1-adapters";
|
|
5592
|
-
import { __ as
|
|
5618
|
+
import { __ as __5 } from "@wordpress/i18n";
|
|
5593
5619
|
function initLinkInLinkPrevention() {
|
|
5594
5620
|
blockCommand3({
|
|
5595
5621
|
command: "document/elements/paste",
|
|
@@ -5623,7 +5649,7 @@ function blockLinkInLinkPaste(args) {
|
|
|
5623
5649
|
const sourceElements = data.clipboard.elements;
|
|
5624
5650
|
const notification = {
|
|
5625
5651
|
type: "default",
|
|
5626
|
-
message:
|
|
5652
|
+
message: __5(
|
|
5627
5653
|
"To paste a link to this element, first remove the link from it's parent container.",
|
|
5628
5654
|
"elementor"
|
|
5629
5655
|
),
|
|
@@ -5632,7 +5658,7 @@ function blockLinkInLinkPaste(args) {
|
|
|
5632
5658
|
};
|
|
5633
5659
|
const blocked = shouldBlock(sourceElements, targetElements);
|
|
5634
5660
|
if (blocked) {
|
|
5635
|
-
|
|
5661
|
+
notify4(notification);
|
|
5636
5662
|
}
|
|
5637
5663
|
return blocked;
|
|
5638
5664
|
}
|
|
@@ -5642,13 +5668,13 @@ function blockLinkInLinkMove(args) {
|
|
|
5642
5668
|
const targetElement = target;
|
|
5643
5669
|
const notification = {
|
|
5644
5670
|
type: "default",
|
|
5645
|
-
message:
|
|
5671
|
+
message: __5("To drag a link to this element, first remove the link from it's parent container.", "elementor"),
|
|
5646
5672
|
id: "move-in-link-blocked",
|
|
5647
5673
|
additionalActionProps: [learnMoreActionProps]
|
|
5648
5674
|
};
|
|
5649
5675
|
const isBlocked = shouldBlock(sourceElements, [targetElement]);
|
|
5650
5676
|
if (isBlocked) {
|
|
5651
|
-
|
|
5677
|
+
notify4(notification);
|
|
5652
5678
|
}
|
|
5653
5679
|
return isBlocked;
|
|
5654
5680
|
}
|
|
@@ -5680,7 +5706,7 @@ import {
|
|
|
5680
5706
|
// src/utils/command-utils.ts
|
|
5681
5707
|
import { getElementLabel as getElementLabel2, getWidgetsCache as getWidgetsCache7 } from "@elementor/editor-elements";
|
|
5682
5708
|
import { CLASSES_PROP_KEY } from "@elementor/editor-props";
|
|
5683
|
-
import { __ as
|
|
5709
|
+
import { __ as __6 } from "@wordpress/i18n";
|
|
5684
5710
|
function hasAtomicWidgets(args) {
|
|
5685
5711
|
const { containers = [args.container] } = args;
|
|
5686
5712
|
return containers.some(isAtomicWidget);
|
|
@@ -5716,7 +5742,7 @@ function getClipboardElements(storageKey = "clipboard") {
|
|
|
5716
5742
|
}
|
|
5717
5743
|
}
|
|
5718
5744
|
function getTitleForContainers(containers) {
|
|
5719
|
-
return containers.length > 1 ?
|
|
5745
|
+
return containers.length > 1 ? __6("Elements", "elementor") : getElementLabel2(containers[0].id);
|
|
5720
5746
|
}
|
|
5721
5747
|
|
|
5722
5748
|
// src/style-commands/undoable-actions/paste-element-style.ts
|
|
@@ -5728,7 +5754,7 @@ import {
|
|
|
5728
5754
|
} from "@elementor/editor-elements";
|
|
5729
5755
|
import { ELEMENTS_STYLES_RESERVED_LABEL } from "@elementor/editor-styles-repository";
|
|
5730
5756
|
import { undoable as undoable2 } from "@elementor/editor-v1-adapters";
|
|
5731
|
-
import { __ as
|
|
5757
|
+
import { __ as __7 } from "@wordpress/i18n";
|
|
5732
5758
|
var undoablePasteElementStyle = () => undoable2(
|
|
5733
5759
|
{
|
|
5734
5760
|
do: ({ containers, newStyle }) => {
|
|
@@ -5798,7 +5824,7 @@ var undoablePasteElementStyle = () => undoable2(
|
|
|
5798
5824
|
},
|
|
5799
5825
|
{
|
|
5800
5826
|
title: ({ containers }) => getTitleForContainers(containers),
|
|
5801
|
-
subtitle:
|
|
5827
|
+
subtitle: __7("Style Pasted", "elementor")
|
|
5802
5828
|
}
|
|
5803
5829
|
);
|
|
5804
5830
|
|
|
@@ -5871,7 +5897,7 @@ import {
|
|
|
5871
5897
|
import { createElementStyle as createElementStyle3, deleteElementStyle as deleteElementStyle2, getElementStyles as getElementStyles3 } from "@elementor/editor-elements";
|
|
5872
5898
|
import { ELEMENTS_STYLES_RESERVED_LABEL as ELEMENTS_STYLES_RESERVED_LABEL2 } from "@elementor/editor-styles-repository";
|
|
5873
5899
|
import { undoable as undoable3 } from "@elementor/editor-v1-adapters";
|
|
5874
|
-
import { __ as
|
|
5900
|
+
import { __ as __8 } from "@wordpress/i18n";
|
|
5875
5901
|
var undoableResetElementStyle = () => undoable3(
|
|
5876
5902
|
{
|
|
5877
5903
|
do: ({ containers }) => {
|
|
@@ -5909,7 +5935,7 @@ var undoableResetElementStyle = () => undoable3(
|
|
|
5909
5935
|
},
|
|
5910
5936
|
{
|
|
5911
5937
|
title: ({ containers }) => getTitleForContainers(containers),
|
|
5912
|
-
subtitle:
|
|
5938
|
+
subtitle: __8("Style Reset", "elementor")
|
|
5913
5939
|
}
|
|
5914
5940
|
);
|
|
5915
5941
|
|
|
@@ -5947,6 +5973,7 @@ function init() {
|
|
|
5947
5973
|
initLinkInLinkPrevention();
|
|
5948
5974
|
initFormNestingPrevention();
|
|
5949
5975
|
initFormAncestorEnforcement();
|
|
5976
|
+
initHiddenFieldHint();
|
|
5950
5977
|
initViewReplacements();
|
|
5951
5978
|
initLegacyViews();
|
|
5952
5979
|
initSettingsTransformers();
|
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.4.0-
|
|
4
|
+
"version": "4.4.0-1136",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -37,26 +37,26 @@
|
|
|
37
37
|
"react-dom": "^18.3.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@elementor/editor": "4.4.0-
|
|
41
|
-
"@elementor/editor-controls": "4.4.0-
|
|
42
|
-
"@elementor/editor-documents": "4.4.0-
|
|
43
|
-
"@elementor/editor-elements": "4.4.0-
|
|
44
|
-
"@elementor/editor-interactions": "4.4.0-
|
|
45
|
-
"@elementor/editor-mcp": "4.4.0-
|
|
46
|
-
"@elementor/editor-notifications": "4.4.0-
|
|
47
|
-
"@elementor/editor-props": "4.4.0-
|
|
48
|
-
"@elementor/editor-responsive": "4.4.0-
|
|
49
|
-
"@elementor/editor-styles": "4.4.0-
|
|
50
|
-
"@elementor/editor-styles-repository": "4.4.0-
|
|
51
|
-
"@elementor/editor-ui": "4.4.0-
|
|
52
|
-
"@elementor/editor-v1-adapters": "4.4.0-
|
|
53
|
-
"@elementor/events": "4.4.0-
|
|
54
|
-
"@elementor/http-client": "4.4.0-
|
|
55
|
-
"@elementor/schema": "4.4.0-
|
|
56
|
-
"@elementor/twing": "4.4.0-
|
|
57
|
-
"@elementor/ui": "1.41.
|
|
58
|
-
"@elementor/utils": "4.4.0-
|
|
59
|
-
"@elementor/wp-media": "4.4.0-
|
|
40
|
+
"@elementor/editor": "4.4.0-1136",
|
|
41
|
+
"@elementor/editor-controls": "4.4.0-1136",
|
|
42
|
+
"@elementor/editor-documents": "4.4.0-1136",
|
|
43
|
+
"@elementor/editor-elements": "4.4.0-1136",
|
|
44
|
+
"@elementor/editor-interactions": "4.4.0-1136",
|
|
45
|
+
"@elementor/editor-mcp": "4.4.0-1136",
|
|
46
|
+
"@elementor/editor-notifications": "4.4.0-1136",
|
|
47
|
+
"@elementor/editor-props": "4.4.0-1136",
|
|
48
|
+
"@elementor/editor-responsive": "4.4.0-1136",
|
|
49
|
+
"@elementor/editor-styles": "4.4.0-1136",
|
|
50
|
+
"@elementor/editor-styles-repository": "4.4.0-1136",
|
|
51
|
+
"@elementor/editor-ui": "4.4.0-1136",
|
|
52
|
+
"@elementor/editor-v1-adapters": "4.4.0-1136",
|
|
53
|
+
"@elementor/events": "4.4.0-1136",
|
|
54
|
+
"@elementor/http-client": "4.4.0-1136",
|
|
55
|
+
"@elementor/schema": "4.4.0-1136",
|
|
56
|
+
"@elementor/twing": "4.4.0-1136",
|
|
57
|
+
"@elementor/ui": "1.41.3",
|
|
58
|
+
"@elementor/utils": "4.4.0-1136",
|
|
59
|
+
"@elementor/wp-media": "4.4.0-1136",
|
|
60
60
|
"@floating-ui/react": "^0.27.5",
|
|
61
61
|
"@wordpress/i18n": "^5.13.0",
|
|
62
62
|
"dompurify": "^3.2.6"
|
|
@@ -114,6 +114,16 @@ describe( 'form-structure utils', () => {
|
|
|
114
114
|
expect( errors[ 0 ] ).toContain( 'e-form-input' );
|
|
115
115
|
expect( errors[ 0 ] ).toContain( 'e-form' );
|
|
116
116
|
} );
|
|
117
|
+
it( 'returns an error when a hidden field has no e-form ancestor (invalid)', () => {
|
|
118
|
+
const xml = parseXml( `
|
|
119
|
+
<e-flexbox>
|
|
120
|
+
<e-form-hidden />
|
|
121
|
+
</e-flexbox>
|
|
122
|
+
` );
|
|
123
|
+
const errors = collectFormAncestorErrors( xml );
|
|
124
|
+
expect( errors ).toHaveLength( 1 );
|
|
125
|
+
expect( errors[ 0 ] ).toContain( 'e-form-hidden' );
|
|
126
|
+
} );
|
|
117
127
|
it( 'returns an error for each orphaned form field', () => {
|
|
118
128
|
const xml = parseXml( `
|
|
119
129
|
<e-flexbox>
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { createHooksRegistry, setupHooksRegistry } from 'test-utils';
|
|
2
|
+
import { notify } from '@elementor/editor-notifications';
|
|
3
|
+
|
|
4
|
+
import { initHiddenFieldHint } from '../hidden-field-hint';
|
|
5
|
+
|
|
6
|
+
jest.mock( '@elementor/editor-notifications', () => ( {
|
|
7
|
+
notify: jest.fn(),
|
|
8
|
+
} ) );
|
|
9
|
+
|
|
10
|
+
const CREATE_COMMAND = 'document/elements/create';
|
|
11
|
+
const MOVE_COMMAND = 'document/elements/move';
|
|
12
|
+
const HIDDEN_FIELD_TYPE = 'e-form-hidden';
|
|
13
|
+
|
|
14
|
+
describe( 'hidden field hint', () => {
|
|
15
|
+
const hooksRegistry = createHooksRegistry();
|
|
16
|
+
|
|
17
|
+
beforeEach( () => {
|
|
18
|
+
jest.mocked( notify ).mockClear();
|
|
19
|
+
setupHooksRegistry( hooksRegistry );
|
|
20
|
+
initHiddenFieldHint();
|
|
21
|
+
} );
|
|
22
|
+
|
|
23
|
+
it( 'should notify when a hidden field is added', () => {
|
|
24
|
+
// Arrange
|
|
25
|
+
const hook = hooksRegistry.getByCommand( CREATE_COMMAND );
|
|
26
|
+
|
|
27
|
+
// Act
|
|
28
|
+
hook?.apply( { model: { widgetType: HIDDEN_FIELD_TYPE } } );
|
|
29
|
+
|
|
30
|
+
// Assert
|
|
31
|
+
expect( notify ).toHaveBeenCalledWith(
|
|
32
|
+
expect.objectContaining( {
|
|
33
|
+
message: 'Hidden field added - invisible on your form. Manage it in the Structure panel.',
|
|
34
|
+
} )
|
|
35
|
+
);
|
|
36
|
+
} );
|
|
37
|
+
|
|
38
|
+
it( 'should use unique notification ids for back-to-back adds (not collapsed by the notification system)', () => {
|
|
39
|
+
// Arrange
|
|
40
|
+
const hook = hooksRegistry.getByCommand( CREATE_COMMAND );
|
|
41
|
+
|
|
42
|
+
// Act
|
|
43
|
+
hook?.apply( { model: { widgetType: HIDDEN_FIELD_TYPE } } );
|
|
44
|
+
hook?.apply( { model: { widgetType: HIDDEN_FIELD_TYPE } } );
|
|
45
|
+
|
|
46
|
+
// Assert
|
|
47
|
+
expect( notify ).toHaveBeenCalledTimes( 2 );
|
|
48
|
+
const firstCallId = jest.mocked( notify ).mock.calls[ 0 ][ 0 ].id;
|
|
49
|
+
const secondCallId = jest.mocked( notify ).mock.calls[ 1 ][ 0 ].id;
|
|
50
|
+
expect( firstCallId ).not.toBe( secondCallId );
|
|
51
|
+
} );
|
|
52
|
+
|
|
53
|
+
it( 'should notify again after remove and re-add (simulated by separate create calls)', () => {
|
|
54
|
+
// Arrange
|
|
55
|
+
const hook = hooksRegistry.getByCommand( CREATE_COMMAND );
|
|
56
|
+
|
|
57
|
+
// Act - first add
|
|
58
|
+
hook?.apply( { model: { widgetType: HIDDEN_FIELD_TYPE } } );
|
|
59
|
+
|
|
60
|
+
// simulate removal (no hook for delete affects this)
|
|
61
|
+
|
|
62
|
+
// Act - re-add
|
|
63
|
+
hook?.apply( { model: { widgetType: HIDDEN_FIELD_TYPE } } );
|
|
64
|
+
|
|
65
|
+
// Assert
|
|
66
|
+
expect( notify ).toHaveBeenCalledTimes( 2 );
|
|
67
|
+
} );
|
|
68
|
+
|
|
69
|
+
it( 'should not notify when another element type is created', () => {
|
|
70
|
+
// Arrange
|
|
71
|
+
const hook = hooksRegistry.getByCommand( CREATE_COMMAND );
|
|
72
|
+
|
|
73
|
+
// Act
|
|
74
|
+
hook?.apply( { model: { widgetType: 'e-form-input' } } );
|
|
75
|
+
|
|
76
|
+
// Assert
|
|
77
|
+
expect( notify ).not.toHaveBeenCalled();
|
|
78
|
+
} );
|
|
79
|
+
|
|
80
|
+
it( 'should not notify when the hidden field is created as part of a move', () => {
|
|
81
|
+
// Arrange
|
|
82
|
+
const hook = hooksRegistry.getByCommand( CREATE_COMMAND );
|
|
83
|
+
const eWindow = window as unknown as { $e: { commands?: { currentTrace?: string[] } } };
|
|
84
|
+
eWindow.$e.commands = { currentTrace: [ MOVE_COMMAND, CREATE_COMMAND ] };
|
|
85
|
+
|
|
86
|
+
// Act
|
|
87
|
+
hook?.apply( { model: { widgetType: HIDDEN_FIELD_TYPE } } );
|
|
88
|
+
|
|
89
|
+
// Assert
|
|
90
|
+
expect( notify ).not.toHaveBeenCalled();
|
|
91
|
+
} );
|
|
92
|
+
|
|
93
|
+
it( 'should not notify on selection (selection does not trigger create command)', () => {
|
|
94
|
+
// Arrange - selection uses a different command path, not document/elements/create
|
|
95
|
+
const hook = hooksRegistry.getByCommand( CREATE_COMMAND );
|
|
96
|
+
|
|
97
|
+
// Act - no create call is made for selection
|
|
98
|
+
// Selection triggers commands like document/elements/toggle-selection, not create
|
|
99
|
+
|
|
100
|
+
// Assert
|
|
101
|
+
expect( hook ).toBeDefined();
|
|
102
|
+
expect( notify ).not.toHaveBeenCalled();
|
|
103
|
+
} );
|
|
104
|
+
|
|
105
|
+
it( 'should notify on paste when it triggers create (current behavior: paste triggers toast)', () => {
|
|
106
|
+
// Arrange
|
|
107
|
+
const hook = hooksRegistry.getByCommand( CREATE_COMMAND );
|
|
108
|
+
|
|
109
|
+
// Act - paste internally calls create, so it will trigger the notification
|
|
110
|
+
hook?.apply( { model: { widgetType: HIDDEN_FIELD_TYPE } } );
|
|
111
|
+
|
|
112
|
+
// Assert
|
|
113
|
+
expect( notify ).toHaveBeenCalledTimes( 1 );
|
|
114
|
+
} );
|
|
115
|
+
|
|
116
|
+
it( 'should notify on duplicate when it triggers create (current behavior: duplicate triggers toast)', () => {
|
|
117
|
+
// Arrange
|
|
118
|
+
const hook = hooksRegistry.getByCommand( CREATE_COMMAND );
|
|
119
|
+
|
|
120
|
+
// Act - duplicate internally calls create, so it will trigger the notification
|
|
121
|
+
hook?.apply( { model: { widgetType: HIDDEN_FIELD_TYPE } } );
|
|
122
|
+
|
|
123
|
+
// Assert
|
|
124
|
+
expect( notify ).toHaveBeenCalledTimes( 1 );
|
|
125
|
+
} );
|
|
126
|
+
|
|
127
|
+
it( 'should notify on undo of delete (undo-delete triggers create, so toast shows)', () => {
|
|
128
|
+
// Arrange
|
|
129
|
+
const hook = hooksRegistry.getByCommand( CREATE_COMMAND );
|
|
130
|
+
|
|
131
|
+
// Act - undo of a delete restores via create command
|
|
132
|
+
hook?.apply( { model: { widgetType: HIDDEN_FIELD_TYPE } } );
|
|
133
|
+
|
|
134
|
+
// Assert
|
|
135
|
+
expect( notify ).toHaveBeenCalledTimes( 1 );
|
|
136
|
+
} );
|
|
137
|
+
} );
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type NotificationData, notify } from '@elementor/editor-notifications';
|
|
2
|
+
import { type HookOptions, registerDataHook } from '@elementor/editor-v1-adapters';
|
|
3
|
+
import { __ } from '@wordpress/i18n';
|
|
4
|
+
|
|
5
|
+
import { type CreateArgs, FORM_HIDDEN_FIELD_ELEMENT_TYPE, getArgsElementType } from './utils';
|
|
6
|
+
|
|
7
|
+
const MOVE_COMMAND = 'document/elements/move';
|
|
8
|
+
|
|
9
|
+
let notificationCounter = 0;
|
|
10
|
+
|
|
11
|
+
function createHiddenFieldNotification(): NotificationData {
|
|
12
|
+
return {
|
|
13
|
+
type: 'default',
|
|
14
|
+
message: __( 'Hidden field added - invisible on your form. Manage it in the Structure panel.', 'elementor' ),
|
|
15
|
+
id: `hidden-field-added-${ ++notificationCounter }`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function initHiddenFieldHint() {
|
|
20
|
+
registerDataHook( 'after', 'document/elements/create', ( args: CreateArgs, _result, options?: HookOptions ) => {
|
|
21
|
+
if ( options?.commandsCurrentTrace?.includes( MOVE_COMMAND ) ) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if ( getArgsElementType( args ) === FORM_HIDDEN_FIELD_ELEMENT_TYPE ) {
|
|
26
|
+
notify( createHiddenFieldNotification() );
|
|
27
|
+
}
|
|
28
|
+
} );
|
|
29
|
+
}
|
|
@@ -35,6 +35,7 @@ export type StorageContent = {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
export const FORM_ELEMENT_TYPE = 'e-form';
|
|
38
|
+
export const FORM_HIDDEN_FIELD_ELEMENT_TYPE = 'e-form-hidden';
|
|
38
39
|
export const FORM_FIELD_ELEMENT_TYPES = new Set( [
|
|
39
40
|
'e-form-input',
|
|
40
41
|
'e-form-textarea',
|
|
@@ -46,6 +47,7 @@ export const FORM_FIELD_ELEMENT_TYPES = new Set( [
|
|
|
46
47
|
'e-form-file-upload',
|
|
47
48
|
'e-form-date-picker',
|
|
48
49
|
'e-form-time-picker',
|
|
50
|
+
FORM_HIDDEN_FIELD_ELEMENT_TYPE,
|
|
49
51
|
] );
|
|
50
52
|
|
|
51
53
|
export function getArgsElementType( args: CreateArgs ): string | undefined {
|
package/src/init.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import { ElementsOverlays } from './components/elements-overlays';
|
|
|
6
6
|
import { InteractionsRenderer } from './components/interactions-renderer';
|
|
7
7
|
import { StyleRenderer } from './components/style-renderer';
|
|
8
8
|
import { initFormAncestorEnforcement } from './form-structure/enforce-form-ancestor-commands';
|
|
9
|
+
import { initHiddenFieldHint } from './form-structure/hidden-field-hint';
|
|
9
10
|
import { initFormNestingPrevention } from './form-structure/prevent-form-nesting-commands';
|
|
10
11
|
import { initSettingsTransformers } from './init-settings-transformers';
|
|
11
12
|
import { initStyleTransformers } from './init-style-transformers';
|
|
@@ -25,6 +26,7 @@ export function init() {
|
|
|
25
26
|
initLinkInLinkPrevention();
|
|
26
27
|
initFormNestingPrevention();
|
|
27
28
|
initFormAncestorEnforcement();
|
|
29
|
+
initHiddenFieldHint();
|
|
28
30
|
|
|
29
31
|
initViewReplacements();
|
|
30
32
|
|