@openui5/sap.ui.rta 1.144.0 → 1.146.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.
Files changed (169) hide show
  1. package/.eslintrc.json +7 -1
  2. package/REUSE.toml +40 -16
  3. package/THIRDPARTY.txt +28 -7
  4. package/package.json +6 -6
  5. package/src/sap/ui/rta/.library +1 -1
  6. package/src/sap/ui/rta/Client.js +1 -1
  7. package/src/sap/ui/rta/RuntimeAuthoring.js +25 -6
  8. package/src/sap/ui/rta/Utils.js +4 -2
  9. package/src/sap/ui/rta/appVariant/AppVariantManager.js +2 -2
  10. package/src/sap/ui/rta/appVariant/Feature.js +6 -4
  11. package/src/sap/ui/rta/appVariant/S4HanaCloudBackend.js +6 -3
  12. package/src/sap/ui/rta/appVariant/Utils.js +2 -2
  13. package/src/sap/ui/rta/command/AddIFrame.js +1 -1
  14. package/src/sap/ui/rta/command/AddProperty.js +1 -1
  15. package/src/sap/ui/rta/command/AddXML.js +1 -1
  16. package/src/sap/ui/rta/command/AddXMLAtExtensionPoint.js +1 -1
  17. package/src/sap/ui/rta/command/AnnotationCommand.js +1 -1
  18. package/src/sap/ui/rta/command/BaseCommand.js +1 -1
  19. package/src/sap/ui/rta/command/BindProperty.js +1 -1
  20. package/src/sap/ui/rta/command/Combine.js +1 -1
  21. package/src/sap/ui/rta/command/CommandFactory.js +1 -1
  22. package/src/sap/ui/rta/command/CompositeCommand.js +1 -1
  23. package/src/sap/ui/rta/command/ControlVariantConfigure.js +2 -1
  24. package/src/sap/ui/rta/command/ControlVariantSave.js +1 -1
  25. package/src/sap/ui/rta/command/ControlVariantSaveAs.js +1 -1
  26. package/src/sap/ui/rta/command/ControlVariantSetTitle.js +1 -1
  27. package/src/sap/ui/rta/command/ControlVariantSwitch.js +1 -1
  28. package/src/sap/ui/rta/command/CreateContainer.js +1 -1
  29. package/src/sap/ui/rta/command/CustomAdd.js +1 -1
  30. package/src/sap/ui/rta/command/ExtendControllerCommand.js +1 -1
  31. package/src/sap/ui/rta/command/FlexCommand.js +1 -1
  32. package/src/sap/ui/rta/command/LREPSerializer.js +1 -1
  33. package/src/sap/ui/rta/command/LocalReset.js +1 -1
  34. package/src/sap/ui/rta/command/ManifestCommand.js +1 -1
  35. package/src/sap/ui/rta/command/Move.js +1 -1
  36. package/src/sap/ui/rta/command/Property.js +1 -1
  37. package/src/sap/ui/rta/command/Remove.js +1 -1
  38. package/src/sap/ui/rta/command/Rename.js +1 -1
  39. package/src/sap/ui/rta/command/Resize.js +1 -1
  40. package/src/sap/ui/rta/command/Reveal.js +1 -1
  41. package/src/sap/ui/rta/command/Settings.js +1 -1
  42. package/src/sap/ui/rta/command/Split.js +1 -1
  43. package/src/sap/ui/rta/command/Stack.js +1 -1
  44. package/src/sap/ui/rta/command/compVariant/CompVariantContent.js +1 -1
  45. package/src/sap/ui/rta/command/compVariant/CompVariantSaveAs.js +1 -1
  46. package/src/sap/ui/rta/command/compVariant/CompVariantSwitch.js +1 -1
  47. package/src/sap/ui/rta/command/compVariant/CompVariantUpdate.js +1 -1
  48. package/src/sap/ui/rta/command/manifest/AddLibrary.js +1 -1
  49. package/src/sap/ui/rta/enablement/elementActionTest.js +90 -94
  50. package/src/sap/ui/rta/library.js +2 -2
  51. package/src/sap/ui/rta/messagebundle.properties +6 -4
  52. package/src/sap/ui/rta/messagebundle_ar.properties +4 -4
  53. package/src/sap/ui/rta/messagebundle_bg.properties +4 -4
  54. package/src/sap/ui/rta/messagebundle_ca.properties +4 -4
  55. package/src/sap/ui/rta/messagebundle_cnr.properties +4 -4
  56. package/src/sap/ui/rta/messagebundle_cs.properties +3 -3
  57. package/src/sap/ui/rta/messagebundle_cy.properties +4 -4
  58. package/src/sap/ui/rta/messagebundle_da.properties +4 -4
  59. package/src/sap/ui/rta/messagebundle_de.properties +4 -4
  60. package/src/sap/ui/rta/messagebundle_el.properties +4 -4
  61. package/src/sap/ui/rta/messagebundle_en.properties +4 -4
  62. package/src/sap/ui/rta/messagebundle_en_GB.properties +4 -4
  63. package/src/sap/ui/rta/messagebundle_en_US_saprigi.properties +5 -4
  64. package/src/sap/ui/rta/messagebundle_es.properties +3 -3
  65. package/src/sap/ui/rta/messagebundle_es_MX.properties +4 -4
  66. package/src/sap/ui/rta/messagebundle_et.properties +4 -4
  67. package/src/sap/ui/rta/messagebundle_fi.properties +4 -4
  68. package/src/sap/ui/rta/messagebundle_fr.properties +4 -4
  69. package/src/sap/ui/rta/messagebundle_fr_CA.properties +5 -5
  70. package/src/sap/ui/rta/messagebundle_hi.properties +4 -4
  71. package/src/sap/ui/rta/messagebundle_hr.properties +4 -4
  72. package/src/sap/ui/rta/messagebundle_hu.properties +3 -3
  73. package/src/sap/ui/rta/messagebundle_id.properties +5 -5
  74. package/src/sap/ui/rta/messagebundle_it.properties +5 -5
  75. package/src/sap/ui/rta/messagebundle_iw.properties +4 -4
  76. package/src/sap/ui/rta/messagebundle_ja.properties +4 -4
  77. package/src/sap/ui/rta/messagebundle_kk.properties +4 -4
  78. package/src/sap/ui/rta/messagebundle_ko.properties +4 -4
  79. package/src/sap/ui/rta/messagebundle_lt.properties +4 -4
  80. package/src/sap/ui/rta/messagebundle_lv.properties +4 -4
  81. package/src/sap/ui/rta/messagebundle_mk.properties +4 -4
  82. package/src/sap/ui/rta/messagebundle_ms.properties +4 -4
  83. package/src/sap/ui/rta/messagebundle_nl.properties +4 -4
  84. package/src/sap/ui/rta/messagebundle_no.properties +5 -5
  85. package/src/sap/ui/rta/messagebundle_pl.properties +4 -4
  86. package/src/sap/ui/rta/messagebundle_pt.properties +4 -4
  87. package/src/sap/ui/rta/messagebundle_pt_PT.properties +4 -4
  88. package/src/sap/ui/rta/messagebundle_ro.properties +4 -4
  89. package/src/sap/ui/rta/messagebundle_ru.properties +6 -6
  90. package/src/sap/ui/rta/messagebundle_sh.properties +4 -4
  91. package/src/sap/ui/rta/messagebundle_sk.properties +4 -4
  92. package/src/sap/ui/rta/messagebundle_sl.properties +4 -4
  93. package/src/sap/ui/rta/messagebundle_sr.properties +4 -4
  94. package/src/sap/ui/rta/messagebundle_sv.properties +4 -4
  95. package/src/sap/ui/rta/messagebundle_th.properties +4 -4
  96. package/src/sap/ui/rta/messagebundle_tr.properties +4 -4
  97. package/src/sap/ui/rta/messagebundle_uk.properties +4 -4
  98. package/src/sap/ui/rta/messagebundle_vi.properties +4 -4
  99. package/src/sap/ui/rta/messagebundle_zh_CN.properties +4 -4
  100. package/src/sap/ui/rta/messagebundle_zh_TW.properties +4 -4
  101. package/src/sap/ui/rta/plugin/AddXMLAtExtensionPoint.js +4 -4
  102. package/src/sap/ui/rta/plugin/AddXMLPlugin.js +1 -1
  103. package/src/sap/ui/rta/plugin/BaseCreate.js +1 -1
  104. package/src/sap/ui/rta/plugin/Combine.js +1 -1
  105. package/src/sap/ui/rta/plugin/ControlVariant.js +1 -1
  106. package/src/sap/ui/rta/plugin/CreateContainer.js +1 -1
  107. package/src/sap/ui/rta/plugin/CutPaste.js +1 -1
  108. package/src/sap/ui/rta/plugin/DragDrop.js +1 -1
  109. package/src/sap/ui/rta/plugin/ExtendControllerPlugin.js +1 -1
  110. package/src/sap/ui/rta/plugin/LocalReset.js +1 -1
  111. package/src/sap/ui/rta/plugin/Plugin.js +1 -1
  112. package/src/sap/ui/rta/plugin/RTAElementMover.js +1 -1
  113. package/src/sap/ui/rta/plugin/Remove.js +13 -11
  114. package/src/sap/ui/rta/plugin/Resize.js +1 -1
  115. package/src/sap/ui/rta/plugin/Selection.js +1 -1
  116. package/src/sap/ui/rta/plugin/Settings.js +1 -1
  117. package/src/sap/ui/rta/plugin/Split.js +1 -1
  118. package/src/sap/ui/rta/plugin/Stretch.js +1 -1
  119. package/src/sap/ui/rta/plugin/additionalElements/ActionExtractor.js +1 -1
  120. package/src/sap/ui/rta/plugin/additionalElements/AddElementsDialog.fragment.xml +5 -20
  121. package/src/sap/ui/rta/plugin/additionalElements/AddElementsDialog.js +278 -26
  122. package/src/sap/ui/rta/plugin/additionalElements/AdditionalElementsAnalyzer.js +40 -11
  123. package/src/sap/ui/rta/plugin/additionalElements/AdditionalElementsPlugin.js +4 -3
  124. package/src/sap/ui/rta/plugin/additionalElements/AdditionalElementsUtils.js +1 -1
  125. package/src/sap/ui/rta/plugin/additionalElements/CommandBuilder.js +1 -1
  126. package/src/sap/ui/rta/plugin/annotations/AnnotationChangeDialog.fragment.xml +1 -1
  127. package/src/sap/ui/rta/plugin/annotations/AnnotationChangeDialog.js +29 -4
  128. package/src/sap/ui/rta/plugin/annotations/AnnotationChangeDialogController.js +11 -17
  129. package/src/sap/ui/rta/plugin/annotations/AnnotationPlugin.js +8 -6
  130. package/src/sap/ui/rta/plugin/annotations/DocumentedAnnotationChanges.js +14 -0
  131. package/src/sap/ui/rta/plugin/iframe/AddIFrame.js +14 -12
  132. package/src/sap/ui/rta/plugin/iframe/AddIFrameDialog.fragment.xml +15 -94
  133. package/src/sap/ui/rta/plugin/iframe/AddIFrameDialog.js +22 -3
  134. package/src/sap/ui/rta/plugin/iframe/AddIFrameDialogController.js +282 -102
  135. package/src/sap/ui/rta/plugin/rename/Rename.js +1 -1
  136. package/src/sap/ui/rta/plugin/rename/RenameDialog.fragment.xml +1 -0
  137. package/src/sap/ui/rta/plugin/rename/RenameDialog.js +1 -1
  138. package/src/sap/ui/rta/service/Action.js +1 -1
  139. package/src/sap/ui/rta/service/ControllerExtension.js +1 -1
  140. package/src/sap/ui/rta/service/Outline.js +14 -6
  141. package/src/sap/ui/rta/service/Property.js +1 -1
  142. package/src/sap/ui/rta/service/Selection.js +1 -1
  143. package/src/sap/ui/rta/service/SupportTools.js +1 -1
  144. package/src/sap/ui/rta/themes/base/ContextMenu.less +1 -1
  145. package/src/sap/ui/rta/toolbar/Adaptation.fragment.xml +9 -4
  146. package/src/sap/ui/rta/toolbar/Adaptation.js +59 -4
  147. package/src/sap/ui/rta/toolbar/AdaptationRenderer.js +7 -9
  148. package/src/sap/ui/rta/toolbar/Base.js +1 -1
  149. package/src/sap/ui/rta/toolbar/BaseRenderer.js +12 -17
  150. package/src/sap/ui/rta/toolbar/Fiori.js +5 -1
  151. package/src/sap/ui/rta/toolbar/FioriLike.js +1 -1
  152. package/src/sap/ui/rta/toolbar/OverflowToolbarButton.js +1 -1
  153. package/src/sap/ui/rta/toolbar/Standalone.js +1 -1
  154. package/src/sap/ui/rta/toolbar/contextBased/ManageAdaptations.js +13 -11
  155. package/src/sap/ui/rta/toolbar/contextBased/SaveAsAdaptation.js +1 -1
  156. package/src/sap/ui/rta/toolbar/translation/Translation.js +1 -1
  157. package/src/sap/ui/rta/toolbar/versioning/Versioning.js +1 -1
  158. package/src/sap/ui/rta/util/PluginManager.js +1 -1
  159. package/src/sap/ui/rta/util/PopupManager.js +1 -1
  160. package/src/sap/ui/rta/util/ReloadManager.js +15 -12
  161. package/src/sap/ui/rta/util/ServiceEventBus.js +1 -1
  162. package/src/sap/ui/rta/util/ServiceManager.js +1 -1
  163. package/src/sap/ui/rta/util/changeVisualization/ChangeIndicator.js +1 -1
  164. package/src/sap/ui/rta/util/changeVisualization/ChangeIndicatorRegistry.js +1 -1
  165. package/src/sap/ui/rta/util/changeVisualization/ChangeVisualization.js +1 -1
  166. package/src/sap/ui/rta/util/changeVisualization/resolveBinding.js +1 -1
  167. package/src/sap/ui/rta/util/guidedTour/GuidedTour.js +3 -1
  168. package/src/sap/ui/rta/util/whatsNew/WhatsNew.js +1 -1
  169. package/src/sap/ui/rta/util/whatsNew/whatsNewContent/whatsNewImages/ExtendedActions.png +0 -0
@@ -4,9 +4,14 @@
4
4
  * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
5
5
  */
6
6
  sap.ui.define([
7
+ "sap/base/util/Deferred",
7
8
  "sap/base/Log",
9
+ "sap/m/HBox",
10
+ "sap/m/Label",
11
+ "sap/m/MultiInput",
12
+ "sap/m/Switch",
8
13
  "sap/m/Token",
9
- "sap/ui/base/BindingParser",
14
+ "sap/m/VBox",
10
15
  "sap/ui/core/mvc/Controller",
11
16
  "sap/ui/core/Element",
12
17
  "sap/ui/core/Lib",
@@ -17,9 +22,14 @@ sap.ui.define([
17
22
  "sap/ui/rta/plugin/iframe/urlCleaner",
18
23
  "sap/ui/rta/util/validateText"
19
24
  ], function(
25
+ Deferred,
20
26
  Log,
27
+ HBox,
28
+ Label,
29
+ MultiInput,
30
+ Switch,
21
31
  Token,
22
- BindingParser,
32
+ VBox,
23
33
  Controller,
24
34
  Element,
25
35
  Lib,
@@ -33,13 +43,14 @@ sap.ui.define([
33
43
  "use strict";
34
44
 
35
45
  // shortcut for sap.ui.core.ValueState
36
- var { ValueState } = coreLibrary;
46
+ const { ValueState } = coreLibrary;
37
47
 
38
48
  const _oTextResources = Lib.getResourceBundleFor("sap.ui.rta");
39
49
 
40
- var _aTextInputFields = ["frameUrl", "title"];
41
- var _aNumericInputFields = ["frameWidth", "frameHeight"];
42
- var _aOtherInputFields = ["frameWidthUnit", "frameHeightUnit", "advancedSettings"];
50
+ const _aTextInputFields = ["frameUrl", "title"];
51
+ const _aNumericInputFields = ["frameWidth", "frameHeight"];
52
+ const _aUnitInputFields = ["frameWidthUnit", "frameHeightUnit"];
53
+ const _aAllConfigFields = _aTextInputFields.concat(_aNumericInputFields, _aUnitInputFields, ["advancedSettings"]);
43
54
 
44
55
  function isValidUrl(sUrl) {
45
56
  if (
@@ -67,6 +78,17 @@ sap.ui.define([
67
78
  oIFramePreview.setProperty(sIFramePropertyName, sValue + sUnit);
68
79
  }
69
80
 
81
+ function setURLErrorMessage(sError) {
82
+ const sErrorKey = {
83
+ [IFrame.VALIDATION_ERROR.UNSAFE_PROTOCOL]: "IFRAME_ADDIFRAME_ERROR_UNSAFE_PROTOCOL",
84
+ [IFrame.VALIDATION_ERROR.MIXED_CONTENT]: "IFRAME_ADDIFRAME_ERROR_MIXED_CONTENT",
85
+ [IFrame.VALIDATION_ERROR.FORBIDDEN_URL]: "IFRAME_ADDIFRAME_ERROR_FORBIDDEN_URL",
86
+ [IFrame.VALIDATION_ERROR.INVALID_URL]: "IFRAME_ADDIFRAME_ERROR_INVALID_URL"
87
+ }[sError];
88
+ const sErrorText = _oTextResources.getText(sErrorKey);
89
+ this._oJSONModel.setProperty("/frameUrlError/value", sErrorText);
90
+ }
91
+
70
92
  return Controller.extend("sap.ui.rta.plugin.iframe.AddIFrameDialogController", {
71
93
  constructor: function(oJSONModel, mSettings) {
72
94
  this._oJSONModel = oJSONModel;
@@ -74,23 +96,85 @@ sap.ui.define([
74
96
  },
75
97
 
76
98
  onBeforeOpen() {
77
- if (this._buildPreviewURL()) {
78
- // If a URL is set initially (updateIframe), validate it
79
- this.onValidateUrl();
80
- } else {
81
- // Disable the save button but don't show an error message
82
- this._checkIfAllFieldsValid(false);
83
- }
99
+ this._oJSONModel.setProperty("/initialFrameUrl/value", this._oJSONModel.getProperty("/frameUrl/value"));
100
+ this._storeInitialConfiguration();
84
101
  // Configure the MultiInput field
85
102
  // This syntax is the suggested way by the UI5 documentation to trigger a submit on the input field on focus loss
86
103
  const oMultiInput = Element.getElementById("sapUiRtaAddIFrameDialog_AddAdditionalParametersInput");
87
104
  oMultiInput.addValidator(multiInputValidator);
88
105
  },
89
106
 
107
+ /**
108
+ * Factory function to create controls for advanced settings Grid content
109
+ * @param {string} sId - Generated ID for the control
110
+ * @param {sap.ui.model.Context} oContext - Binding context
111
+ * @returns {sap.ui.core.Control} Control (HBox with Switch or VBox with MultiInput)
112
+ */
113
+ createAdvancedSettingsControl(sId, oContext) {
114
+ const oSetting = oContext.getObject();
115
+
116
+ // MultiInput for additional sandbox parameters
117
+ if (oSetting.isMultiInput) {
118
+ const oLabel = new Label("sapUiRtaAddIFrameDialog_AddAdditionalParametersLabel", {
119
+ text: "{i18n>IFRAME_ADDIFRAME_ADD_ADDITIONAL_SANDBOX_PARAMETERS_LABEL}",
120
+ labelFor: "sapUiRtaAddIFrameDialog_AddAdditionalParametersInput"
121
+ });
122
+
123
+ const oMultiInput = new MultiInput("sapUiRtaAddIFrameDialog_AddAdditionalParametersInput", {
124
+ placeholder: "{i18n>IFRAME_ADDIFRAME_ADD_ADDITIONAL_SANDBOX_PARAMETERS_PLACEHOLDER}",
125
+ showValueHelp: false,
126
+ tokenUpdate: this.onTokenUpdate.bind(this)
127
+ });
128
+
129
+ // Set up token binding programmatically
130
+ oMultiInput.bindAggregation("tokens", {
131
+ path: "dialogInfo>/advancedSettings/value/additionalSandboxParameters",
132
+ template: new Token({
133
+ text: "{dialogInfo>}",
134
+ key: "{dialogInfo>}"
135
+ }),
136
+ templateShareable: false
137
+ });
138
+
139
+ return new VBox(sId, {
140
+ items: [oLabel, oMultiInput]
141
+ });
142
+ }
143
+
144
+ // Switch for boolean settings
145
+ const oSwitch = new Switch(`sapUiRtaAddIFrameDialog_${oSetting.key}Switch`, {
146
+ state: `{dialogInfo>/advancedSettings/value/${oSetting.key}}`,
147
+ customTextOn: " ",
148
+ customTextOff: " ",
149
+ change: this.onSwitchChange.bind(this)
150
+ });
151
+
152
+ const oLabel = new Label({
153
+ text: oSetting.label
154
+ });
155
+
156
+ return new HBox(sId, {
157
+ alignItems: "Center",
158
+ items: [oSwitch, oLabel]
159
+ });
160
+ },
161
+
90
162
  onSwitchChange() {
163
+ this._checkIfSaveIsEnabled(true);
91
164
  this._oJSONModel.setProperty("/settingsUpdate/value", true);
92
165
  },
93
166
 
167
+ /**
168
+ * Event handler for URL live change
169
+ * Enables the Save button immediately when content is typed
170
+ */
171
+ onUrlLiveChange() {
172
+ // Clear any previous URL error to make typing user friendly
173
+ this._oJSONModel.setProperty("/frameUrlError/value", "");
174
+ // Check if save should be enabled based on changes (without full URL validation)
175
+ this._checkIfSaveIsEnabled(true);
176
+ },
177
+
94
178
  /**
95
179
  * Event handler for token update
96
180
  * @param {sap.ui.base.Event} oEvent - Event
@@ -99,19 +183,18 @@ sap.ui.define([
99
183
  let aSandboxParameters = this._oJSONModel.getProperty("/advancedSettings/value/additionalSandboxParameters");
100
184
 
101
185
  if (oEvent.getParameter("type") === "added") {
102
- oEvent.getParameter("addedTokens").forEach(function(oToken) {
186
+ oEvent.getParameter("addedTokens").forEach((oToken) => {
103
187
  aSandboxParameters = [...aSandboxParameters, oToken.getText()];
104
188
  });
105
189
  } else if (oEvent.getParameter("type") === "removed") {
106
- oEvent.getParameter("removedTokens").forEach(function(oToken) {
107
- aSandboxParameters = aSandboxParameters.filter(function(sText) {
108
- return sText !== oToken.getText();
109
- });
190
+ oEvent.getParameter("removedTokens").forEach((oToken) => {
191
+ aSandboxParameters = aSandboxParameters.filter((sText) => sText !== oToken.getText());
110
192
  });
111
193
  }
112
194
 
113
195
  this._oJSONModel.setProperty("/advancedSettings/value/additionalSandboxParameters", aSandboxParameters);
114
196
  this._oJSONModel.setProperty("/settingsUpdate/value", true);
197
+ this._checkIfSaveIsEnabled(true);
115
198
  },
116
199
 
117
200
  /**
@@ -120,7 +203,7 @@ sap.ui.define([
120
203
  */
121
204
  onValidationSuccess(oEvent) {
122
205
  oEvent.getSource().setValueState(ValueState.None);
123
- this._checkIfAllFieldsValid(true);
206
+ this._checkIfSaveIsEnabled(true);
124
207
  },
125
208
 
126
209
  /**
@@ -129,16 +212,25 @@ sap.ui.define([
129
212
  */
130
213
  onValidationError(oEvent) {
131
214
  oEvent.getSource().setValueState(ValueState.Error);
132
- this._checkIfAllFieldsValid(false);
215
+ this._checkIfSaveIsEnabled(false);
133
216
  this._setFocusOnInvalidInput();
134
217
  },
135
218
 
136
219
  /**
137
220
  * Event handler for save button
221
+ * Validates the URL before saving - if invalid, shows error and disables Save button
138
222
  */
139
- onSavePress() {
140
- const sUrl = this._buildPreviewURL();
141
- if (isValidUrl(sUrl).result && this._areAllTextFieldsValid() && this._areAllValueStateNones()) {
223
+ async onSavePress() {
224
+ const sUrl = await this._buildPreviewURL();
225
+ const { result: bResult, error: sError } = isValidUrl(sUrl);
226
+
227
+ if (!bResult) {
228
+ setURLErrorMessage.call(this, sError);
229
+ this._checkIfSaveIsEnabled(false);
230
+ return;
231
+ }
232
+
233
+ if (this._areAllTextFieldsValid() && this._areAllValueStateNones()) {
142
234
  this._close(this._buildReturnedSettings());
143
235
  } else {
144
236
  this._setFocusOnInvalidInput();
@@ -148,9 +240,9 @@ sap.ui.define([
148
240
  /**
149
241
  * Event handler for Show Preview button
150
242
  */
151
- onPreviewPress() {
243
+ async onPreviewPress() {
152
244
  const sReturnedURL = this._buildReturnedURL();
153
- const sURL = this._buildPreviewURL();
245
+ const sURL = await this._buildPreviewURL();
154
246
 
155
247
  if (!isValidUrl(sURL).result) {
156
248
  return;
@@ -195,8 +287,8 @@ sap.ui.define([
195
287
  * @param {sap.ui.base.Event} oEvent - Event
196
288
  */
197
289
  onLiveChange(oEvent) {
198
- var oFilter = new Filter("label", FilterOperator.Contains, oEvent.getParameter("newValue"));
199
- var oBinding = Element.getElementById("sapUiRtaAddIFrameDialog_ParameterTable").getBinding("items");
290
+ const oFilter = new Filter("label", FilterOperator.Contains, oEvent.getParameter("newValue"));
291
+ const oBinding = Element.getElementById("sapUiRtaAddIFrameDialog_ParameterTable").getBinding("items");
200
292
  oBinding.filter([oFilter]);
201
293
  },
202
294
 
@@ -212,6 +304,7 @@ sap.ui.define([
212
304
  // Extract "/frameWidth" or "/frameHeight" from the binding path (e.g. /frameWidth/value)
213
305
  const sPropertyName = sPropertyPath.replace(/\/value$/, "");
214
306
  setNewPreviewSize.call(this, sPropertyName);
307
+ this._checkIfSaveIsEnabled(true);
215
308
  },
216
309
 
217
310
  /**
@@ -226,6 +319,7 @@ sap.ui.define([
226
319
  // Extract "/frameWidth" or "/frameHeight" from the binding path (e.g. /frameWidthUnit/value)
227
320
  const sPropertyName = sPropertyPath.replace(/Unit\/value$/, "");
228
321
  setNewPreviewSize.call(this, sPropertyName);
322
+ this._checkIfSaveIsEnabled(true);
229
323
  },
230
324
 
231
325
  /**
@@ -234,6 +328,7 @@ sap.ui.define([
234
328
  * @private
235
329
  */
236
330
  _buildPreviewURL() {
331
+ const oValidationPromise = new Deferred();
237
332
  const sUrl = this._buildReturnedURL();
238
333
  const oResolver = Element.getElementById("sapUiRtaAddIFrameDialog_PreviewLinkResolver");
239
334
  try {
@@ -243,17 +338,24 @@ sap.ui.define([
243
338
  // value is a plain string, which can then lead to problems with two-way bindings
244
339
  // where the new plain value would leak back into the model
245
340
  // In this case the old binding has to be cleaned up explicitly
246
- if (!BindingParser.complexParser(sUrl)) {
247
- oResolver.unbindProperty("text");
248
- }
341
+ oResolver.unbindProperty("text");
249
342
 
250
343
  oResolver.applySettings({
251
344
  text: sUrl
252
345
  });
346
+ const oBinding = oResolver.getBinding("text");
347
+ if (oBinding?.isA("sap.ui.model.odata.v4.ODataPropertyBinding")) {
348
+ // V4 bindings are asynchronous, so we need to wait for the change event
349
+ oBinding.attachEventOnce("change", () => {
350
+ oValidationPromise.resolve(oResolver.getText());
351
+ });
352
+ } else {
353
+ oValidationPromise.resolve(oResolver.getText());
354
+ }
253
355
  } catch (err) {
254
356
  return undefined;
255
357
  }
256
- return oResolver.getText();
358
+ return oValidationPromise.promise;
257
359
  },
258
360
 
259
361
  /**
@@ -266,13 +368,17 @@ sap.ui.define([
266
368
  _addURLParameter(oObject) {
267
369
  const sParameterKey = oObject.key;
268
370
  let sParameterString;
269
- // If the type is available, this is an OData V4 Model and the target type must be set to 'any' when adding the parameter
270
- // to the URL to prevent it from being resolved to a localized value.
271
- // E.g. boolean is resolved to "yes/no" in a system with English locale - but we need to add "true/false" to the URL
272
- // The only type that does not require this special handling is Edm.String
371
+ const [, sParameter] = sParameterKey.match(/\{(.+?)\}/);
273
372
  if (oObject.type && oObject.type !== "Edm.String") {
274
- const [, sParameter] = sParameterKey.match(/\{(.+?)\}/);
373
+ // If the type is available, this is an OData V4 Model and the target type must be set to 'any' when adding the parameter
374
+ // to the URL to prevent it from being resolved to a localized value.
375
+ // E.g. boolean is resolved to "yes/no" in a system with English locale - but we need to add "true/false" to the URL
376
+ // The only type that does not require this special handling is Edm.String
275
377
  sParameterString = `{path:'${sParameter}',targetType:'any'}`;
378
+ } else if (sParameter.startsWith("@")) {
379
+ // Parameters starting with "@" (e.g. @odata.context) need special handling
380
+ // to avoid issues with the binding syntax
381
+ sParameterString = `{=%{${sParameter}}}`;
276
382
  } else {
277
383
  sParameterString = sParameterKey;
278
384
  }
@@ -293,32 +399,113 @@ sap.ui.define([
293
399
  return urlCleaner(this._oJSONModel.getProperty("/frameUrl/value"));
294
400
  },
295
401
 
296
- _checkIfAllFieldsValid(bExternalValidationSuccess) {
297
- const bAllFieldsValid = (
402
+ /**
403
+ * Stores the initial configuration values when the dialog opens.
404
+ * This is used to detect if any changes were made.
405
+ *
406
+ * @private
407
+ */
408
+ _storeInitialConfiguration() {
409
+ this._mInitialConfiguration = {};
410
+ const aAdvancedSettingsConfig = this._oJSONModel.getProperty("/advancedSettingsConfig");
411
+ _aAllConfigFields.forEach((sFieldName) => {
412
+ const vValue = this._oJSONModel.getProperty(`/${sFieldName}/value`);
413
+ // For advancedSettings, store each property individually to avoid reference issues
414
+ if (sFieldName === "advancedSettings") {
415
+ const mStoredSettings = {};
416
+ // Use explicit false for undefined boolean values since switches default to false
417
+ aAdvancedSettingsConfig.forEach((oSetting) => {
418
+ mStoredSettings[oSetting.key] = vValue[oSetting.key] ?? false;
419
+ });
420
+ mStoredSettings.additionalSandboxParameters = vValue.additionalSandboxParameters
421
+ ? [...vValue.additionalSandboxParameters]
422
+ : [];
423
+ this._mInitialConfiguration.advancedSettings = mStoredSettings;
424
+ } else if (vValue !== null && typeof vValue === "object") {
425
+ // Deep copy for other objects using JSON parse/stringify
426
+ this._mInitialConfiguration[sFieldName] = JSON.parse(JSON.stringify(vValue));
427
+ } else {
428
+ this._mInitialConfiguration[sFieldName] = vValue;
429
+ }
430
+ });
431
+ },
432
+
433
+ /**
434
+ * Checks if any configuration field has been modified compared to the initial state.
435
+ *
436
+ * @returns {boolean} True if any configuration was modified
437
+ * @private
438
+ */
439
+ _hasConfigurationChanged() {
440
+ if (!this._mInitialConfiguration) {
441
+ return true; // No initial config stored (e.g. new iframe)
442
+ }
443
+
444
+ const aAdvancedSettingsConfig = this._oJSONModel.getProperty("/advancedSettingsConfig");
445
+ return _aAllConfigFields.some((sFieldName) => {
446
+ const vCurrentValue = this._oJSONModel.getProperty(`/${sFieldName}/value`);
447
+ const vInitialValue = this._mInitialConfiguration[sFieldName];
448
+
449
+ // Handle advancedSettings by comparing each property individually
450
+ if (sFieldName === "advancedSettings") {
451
+ // Compare boolean switches using nullish coalescing to handle undefined values
452
+ const bSwitchChanged = aAdvancedSettingsConfig.some((oSetting) => {
453
+ if (oSetting.key === "additionalSandboxParameters") {
454
+ return false; // Array comparison is handled below
455
+ }
456
+ return (vCurrentValue[oSetting.key] ?? false) !== vInitialValue[oSetting.key];
457
+ });
458
+ if (bSwitchChanged) {
459
+ return true;
460
+ }
461
+ // Compare additionalSandboxParameters array
462
+ const aCurrentParams = vCurrentValue.additionalSandboxParameters || [];
463
+ const aInitialParams = vInitialValue.additionalSandboxParameters || [];
464
+ if (aCurrentParams.length !== aInitialParams.length) {
465
+ return true;
466
+ }
467
+ return aCurrentParams.some((vParam, iCounter) => vParam !== aInitialParams[iCounter]);
468
+ }
469
+
470
+ // Handle other objects by comparing JSON strings
471
+ if (vCurrentValue !== null && typeof vCurrentValue === "object") {
472
+ return JSON.stringify(vCurrentValue) !== JSON.stringify(vInitialValue);
473
+ }
474
+
475
+ return vCurrentValue !== vInitialValue;
476
+ });
477
+ },
478
+
479
+ /**
480
+ * Triggers the validation of all fields and updates the "saveEnabled" property in the model
481
+ * This property is used to enable/disable the Save button
482
+ * The Save button is only enabled if:
483
+ * 1. All validation checks pass
484
+ * 2. At least one configuration field was modified
485
+ *
486
+ * @param {boolean} bExternalValidationSuccess - Whether external validation was successful
487
+ */
488
+ _checkIfSaveIsEnabled(bExternalValidationSuccess) {
489
+ const bAllValidationsPass = (
298
490
  bExternalValidationSuccess
299
491
  && !this._oJSONModel.getProperty("/frameUrlError/value")
300
492
  && this._areAllTextFieldsValid()
301
493
  && this._areAllValueStateNones()
302
494
  );
303
- this._oJSONModel.setProperty("/areAllFieldsValid", bAllFieldsValid);
495
+ const bHasChanges = this._hasConfigurationChanged();
496
+ const bSaveEnabled = bAllValidationsPass && bHasChanges;
497
+ this._oJSONModel.setProperty("/saveEnabled", bSaveEnabled);
304
498
  },
305
499
 
306
- onValidateUrl() {
307
- const sUrl = this._buildPreviewURL();
500
+ async onValidateUrl() {
501
+ const sUrl = await this._buildPreviewURL();
308
502
  const { result: bResult, error: sError } = isValidUrl(sUrl);
309
503
  if (bResult) {
310
504
  this._oJSONModel.setProperty("/frameUrlError/value", "");
311
505
  } else {
312
- const sErrorKey = {
313
- [IFrame.VALIDATION_ERROR.UNSAFE_PROTOCOL]: "IFRAME_ADDIFRAME_ERROR_UNSAFE_PROTOCOL",
314
- [IFrame.VALIDATION_ERROR.MIXED_CONTENT]: "IFRAME_ADDIFRAME_ERROR_MIXED_CONTENT",
315
- [IFrame.VALIDATION_ERROR.FORBIDDEN_URL]: "IFRAME_ADDIFRAME_ERROR_FORBIDDEN_URL",
316
- [IFrame.VALIDATION_ERROR.INVALID_URL]: "IFRAME_ADDIFRAME_ERROR_INVALID_URL"
317
- }[sError];
318
- const sErrorText = _oTextResources.getText(sErrorKey);
319
- this._oJSONModel.setProperty("/frameUrlError/value", sErrorText);
506
+ setURLErrorMessage.call(this, sError);
320
507
  }
321
- this._checkIfAllFieldsValid(bResult);
508
+ this._checkIfSaveIsEnabled(bResult);
322
509
  },
323
510
 
324
511
  /**
@@ -329,28 +516,25 @@ sap.ui.define([
329
516
  },
330
517
 
331
518
  onContainerTitleChange(oEvent) {
332
- var oInput = oEvent.getSource();
333
- var sValueState = "None";
334
- var bValidationError = false;
335
- var sValue = oInput.getValue();
519
+ const oInput = oEvent.getSource();
520
+ const sValue = oInput.getValue();
521
+ let sValueState = ValueState.None;
336
522
 
337
523
  if (sValue.trim() === "") {
338
- sValueState = "Error";
339
- oInput.setValueState(sValueState);
340
- this._oJSONModel.setProperty("/areAllFieldsValid", false);
524
+ oInput.setValueState(ValueState.Error);
525
+ this._oJSONModel.setProperty("/saveEnabled", false);
341
526
  return true;
342
527
  }
343
528
 
344
529
  try {
345
530
  validateText(sValue);
346
531
  } catch (oException) {
347
- sValueState = "Error";
348
- bValidationError = true;
532
+ sValueState = ValueState.Error;
349
533
  }
350
534
 
351
- this._checkIfAllFieldsValid(!bValidationError);
352
535
  oInput.setValueState(sValueState);
353
- return bValidationError;
536
+ this._checkIfSaveIsEnabled(sValueState === ValueState.None);
537
+ return sValueState === ValueState.Error;
354
538
  },
355
539
 
356
540
  /**
@@ -360,7 +544,7 @@ sap.ui.define([
360
544
  * @private
361
545
  */
362
546
  _close(mSettings) {
363
- var oAddIFrameDialog = Element.getElementById("sapUiRtaAddIFrameDialog");
547
+ const oAddIFrameDialog = Element.getElementById("sapUiRtaAddIFrameDialog");
364
548
  this._mSettings = mSettings;
365
549
  oAddIFrameDialog.close();
366
550
  },
@@ -376,37 +560,33 @@ sap.ui.define([
376
560
  },
377
561
 
378
562
  _areAllValueStateNones() {
379
- var oData = this._oJSONModel.getData();
380
- return _aTextInputFields.concat(_aNumericInputFields).every(function(sFieldName) {
563
+ const oData = this._oJSONModel.getData();
564
+ return _aTextInputFields.concat(_aNumericInputFields).every((sFieldName) => {
381
565
  return oData[sFieldName].valueState === ValueState.None;
382
- }, this);
566
+ });
383
567
  },
384
568
 
385
569
  _areAllTextFieldsValid() {
386
- var oJSONModel = this._oJSONModel;
387
- var bAsContainer = this._oJSONModel.getProperty("asContainer/value");
388
- return _aTextInputFields.reduce(function(bAllValid, sFieldName) {
570
+ const bAsContainer = this._oJSONModel.getProperty("asContainer/value");
571
+ return _aTextInputFields.every((sFieldName) => {
389
572
  // The title field is only available on add as Section
390
573
  if (sFieldName === "title" && !bAsContainer) {
391
574
  return true;
392
575
  }
393
- var sValuePath = `/${sFieldName}/value`;
394
- var sValueState;
395
- if (oJSONModel.getProperty(sValuePath).trim() === "") {
396
- sValueState = ValueState.Error;
397
- } else {
398
- sValueState = ValueState.None;
399
- }
400
- oJSONModel.setProperty(`${sValuePath}State`, sValueState);
401
- return bAllValid && sValueState === ValueState.None;
402
- }, true);
576
+ const sValuePath = `/${sFieldName}/value`;
577
+ const sValueState = this._oJSONModel.getProperty(sValuePath).trim() === ""
578
+ ? ValueState.Error
579
+ : ValueState.None;
580
+ this._oJSONModel.setProperty(`${sValuePath}State`, sValueState);
581
+ return sValueState === ValueState.None;
582
+ });
403
583
  },
404
584
 
405
585
  _buildReturnedSettings() {
406
- var mSettings = {};
407
- var oData = this._oJSONModel.getData();
408
- _aTextInputFields.concat(_aNumericInputFields, _aOtherInputFields).forEach(function(sFieldName) {
409
- var sValue = oData[sFieldName].value;
586
+ const mSettings = {};
587
+ const oData = this._oJSONModel.getData();
588
+ _aAllConfigFields.forEach((sFieldName) => {
589
+ let sValue = oData[sFieldName].value;
410
590
  if (sFieldName === "frameUrl") {
411
591
  sValue = urlCleaner(sValue);
412
592
  }
@@ -422,29 +602,30 @@ sap.ui.define([
422
602
  * @private
423
603
  */
424
604
  _importSettings(mSettings) {
425
- if (mSettings) {
426
- Object.keys(mSettings).forEach(function(sFieldName) {
427
- if (sFieldName === "frameWidth" || sFieldName === "frameHeight") {
428
- this._importIFrameSize(sFieldName, mSettings[sFieldName]);
429
- // legacy iframes do not have advancedSettings properties so we need to skip the setProperty
430
- // on the json model to not overwrite the default values with undefined
431
- } else if (sFieldName === "advancedSettings" && !mSettings[sFieldName]) {
432
- return;
433
- } else {
434
- this._oJSONModel.setProperty(`/${sFieldName}/value`, mSettings[sFieldName]);
435
- }
436
- }, this);
605
+ if (!mSettings) {
606
+ return;
437
607
  }
608
+ Object.keys(mSettings).forEach((sFieldName) => {
609
+ if (sFieldName === "frameWidth" || sFieldName === "frameHeight") {
610
+ this._importIFrameSize(sFieldName, mSettings[sFieldName]);
611
+ // Legacy iframes do not have advancedSettings properties so we need to skip the setProperty
612
+ // on the json model to not overwrite the default values with undefined
613
+ } else if (sFieldName === "advancedSettings" && !mSettings[sFieldName]) {
614
+ return;
615
+ } else {
616
+ this._oJSONModel.setProperty(`/${sFieldName}/value`, mSettings[sFieldName]);
617
+ }
618
+ });
438
619
  },
439
620
 
440
621
  /**
441
622
  * Import IFrame size
442
623
  *
443
- * @param {string} sFieldName - Field name
444
- * @param {string} sSize - Size to import
624
+ * @param {string} sFieldName - Field name
625
+ * @param {string} sSize - Size to import
445
626
  */
446
627
  _importIFrameSize(sFieldName, sSize) {
447
- var aResults = sSize.split(/(px|rem|%|vh)/);
628
+ const aResults = sSize.split(/(px|rem|%|vh)/);
448
629
  if (aResults.length >= 2) {
449
630
  this._oJSONModel.setProperty(`/${sFieldName}/value`, parseFloat(aResults[0]));
450
631
  this._oJSONModel.setProperty(`/${sFieldName}Unit/value`, aResults[1]);
@@ -456,18 +637,17 @@ sap.ui.define([
456
637
  * Processed on saving the dialog
457
638
  * Only numerical values are checked
458
639
  * An empty URL field disables the Save button and does not need to be checked
459
- *
460
640
  */
461
641
  _setFocusOnInvalidInput() {
462
- var oData = this._oJSONModel.getData();
463
- _aNumericInputFields.some(function(sFieldName) {
642
+ const oData = this._oJSONModel.getData();
643
+ _aNumericInputFields.some((sFieldName) => {
464
644
  if (oData[sFieldName].valueState === ValueState.Error) {
465
- var oElement = Element.getElementById(oData[sFieldName].id);
645
+ const oElement = Element.getElementById(oData[sFieldName].id);
466
646
  oElement.focus();
467
647
  return true;
468
648
  }
469
649
  return false;
470
- }, this);
650
+ });
471
651
  }
472
652
  });
473
653
  });
@@ -28,7 +28,7 @@ sap.ui.define([
28
28
  * @extends sap.ui.rta.plugin.Plugin
29
29
  *
30
30
  * @author SAP SE
31
- * @version 1.144.0
31
+ * @version 1.146.0
32
32
  *
33
33
  * @constructor
34
34
  * @private
@@ -22,6 +22,7 @@
22
22
  text="{i18n>RENAME_DIALOG_LABEL}"
23
23
  labelFor="sapUiRtaRenameDialog_input"
24
24
  wrapping="true"
25
+ showColon="true"
25
26
  >
26
27
  <layoutData>
27
28
  <FlexItemData maxWidth="10rem" />
@@ -27,7 +27,7 @@ sap.ui.define([
27
27
  * @class Constructor for a new sap.ui.rta.plugin.rename.RenameDialog.
28
28
  * @extends sap.ui.base.ManagedObject
29
29
  * @author SAP SE
30
- * @version 1.144.0
30
+ * @version 1.146.0
31
31
  * @constructor
32
32
  * @since 1.136
33
33
  * @private
@@ -24,7 +24,7 @@ sap.ui.define([
24
24
  * @name sap.ui.rta.service.Action
25
25
  * @author SAP SE
26
26
  * @since 1.58
27
- * @version 1.144.0
27
+ * @version 1.146.0
28
28
  * @private
29
29
  * @ui5-restricted
30
30
  *
@@ -30,7 +30,7 @@ sap.ui.define([
30
30
  * @name sap.ui.rta.service.ControllerExtension
31
31
  * @author SAP SE
32
32
  * @since 1.58
33
- * @version 1.144.0
33
+ * @version 1.146.0
34
34
  * @private
35
35
  * @ui5-restricted
36
36
  */