@sapui5/sap.fe.navigation 1.102.2 → 1.104.1

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.
@@ -55,7 +55,6 @@ sap.ui.define(
55
55
  * <b>Note:</b> The check for excluded data requires that the OData metadata has already been loaded completely.<br>
56
56
  * If the OData metadata model has not been loaded completely, all properties are removed from the application context.<br>
57
57
  * <b>Note:</b> This class requires that the UShell {@link sap.ushell.services.CrossApplicationNavigation} is available and initialized.
58
- *
59
58
  * @extends sap.ui.base.Object
60
59
  * @class
61
60
  * @public
@@ -77,9 +76,9 @@ sap.ui.define(
77
76
  * <td>Indicates that the input parameter is invalid</td>
78
77
  * </tr>
79
78
  * </table>
80
- * @alias sap.fe.navigation.NavigationHandler
79
+ * @name sap.fe.navigation.NavigationHandler
81
80
  */
82
- var NavigationHandler = BaseObject.extend("sap.fe.navigation.NavigationHandler" /** @lends sap.fe.navigation.NavigationHandler */, {
81
+ return BaseObject.extend("sap.fe.navigation.NavigationHandler" /** @lends sap.fe.navigation.NavigationHandler.prototype */, {
83
82
  metadata: {
84
83
  publicMethods: [
85
84
  "navigate",
@@ -127,17 +126,6 @@ sap.ui.define(
127
126
  throw new NavError("NavigationHandler.INVALID_INPUT");
128
127
  }
129
128
 
130
- try {
131
- this.oCrossAppNavService = this._getAppNavigationService();
132
- if (!this.oCrossAppNavService) {
133
- Log.error("NavigationHandler: CrossApplicationNavigation is not available.");
134
- throw new NavError("NavigationHandler.NO.XAPPSERVICE");
135
- }
136
- } catch (ex) {
137
- Log.error("NavigationHandler: UShell service API for CrossApplicationNavigation is not available.");
138
- // throw new NavError("NavigationHandler.NO.SHELL");
139
- }
140
-
141
129
  this.IAPP_STATE = "sap-iapp-state";
142
130
  this.sDefaultedParamProp = "sap-ushell-defaultedParameterNames";
143
131
  this.sSAPSystemProp = "sap-system";
@@ -189,6 +177,7 @@ sap.ui.define(
189
177
 
190
178
  /**
191
179
  * Retrieves the shell navigation service.
180
+ *
192
181
  * @returns {object} The Navigation service
193
182
  * @private
194
183
  */
@@ -196,6 +185,23 @@ sap.ui.define(
196
185
  return sap.ushell.Container.getService("CrossApplicationNavigation");
197
186
  },
198
187
 
188
+ /**
189
+ * Retrieves the shell navigation service.
190
+ *
191
+ * @returns {object} The Navigation service
192
+ * @private
193
+ */
194
+ _getAppNavigationServiceAsync: function () {
195
+ return sap.ushell.Container.getServiceAsync("CrossApplicationNavigation")
196
+ .then(function (oCrossAppNavService) {
197
+ return oCrossAppNavService;
198
+ })
199
+ .catch(function () {
200
+ Log.error("NavigationHandler: CrossApplicationNavigation is not available.");
201
+ throw new NavError("NavigationHandler.NO.XAPPSERVICE");
202
+ });
203
+ },
204
+
199
205
  /**
200
206
  * Retrieves the reference to the router object for navigation for this given Controller.
201
207
  *
@@ -209,6 +215,7 @@ sap.ui.define(
209
215
 
210
216
  /**
211
217
  * This method is to be used only by FE V2 to get access to toExternal promise.
218
+ *
212
219
  * @param {object} fnCallback Callback to be called by 'navigate' method in case of toExternal is used to navigate.
213
220
  * @private
214
221
  */
@@ -221,6 +228,28 @@ sap.ui.define(
221
228
  * <code>sap-ushell-next-navmode</code> is taken into account. If set to <code>explace</code> the inner app state will not be changed.
222
229
  * <b>Note:</b> The <code>sNavMode</code> argument can be used to overwrite the SAP Fiori launchpad default navigation for opening a URL
223
230
  * in-place or ex-place.
231
+ * <br>
232
+ * <b>Node:</b> If the <code>oExternalAppData</code> parameter is not supplied, the external app data will be calculated based on
233
+ * the <code>oInnerAppData</code> data.<br>
234
+ * SmartFilterBar control <b>Parameters:</b> <table>
235
+ * <tr>
236
+ * <td align="center">{object}</td>
237
+ * <td><b>oError</b></td>
238
+ * <td>NavError object (instance of {@link sap.fe.navigation.NavError}) that describes which kind of error occurred</td>
239
+ * <tr>
240
+ * <td align="center">{string}</td>
241
+ * <td><b>oError.errorCode</b></td>
242
+ * <td>Code to identify the error</td>
243
+ * <tr>
244
+ * <td align="center">{string}</td>
245
+ * <td><b>oError.type</b></td>
246
+ * <td>Severity of the error (info/warning/error)</td>
247
+ * <tr>
248
+ * <td align="center">{array}</td>
249
+ * <td><b>oError.params</b></td>
250
+ * <td>An array of objects (typically strings) that describe additional value parameters required for generating the message</td>
251
+ * </table>.
252
+ *
224
253
  * @param {string} sSemanticObject Name of the semantic object of the target app
225
254
  * @param {string} sActionName Name of the action of the target app
226
255
  * @param {object | string } [vNavigationParameters] Navigation parameters as an object with key/value pairs or as a string representation of
@@ -244,27 +273,7 @@ sap.ui.define(
244
273
  * @param {string} [sNavMode] Argument is used to overwrite the FLP-configured target for opening a URL. If used, only the
245
274
  * <code>explace</code> or <code>inplace</code> values are allowed. Any other value will lead to an exception
246
275
  * <code>NavigationHandler.INVALID_NAV_MODE</code>.
247
- * @public <br>
248
- * <b>Node:</b> If the <code>oExternalAppData</code> parameter is not supplied, the external app data will be calculated based on
249
- * the <code>oInnerAppData</code> data.<br>
250
- * SmartFilterBar control <b>Parameters:</b> <table>
251
- * <tr>
252
- * <td align="center">{object}</td>
253
- * <td><b>oError</b></td>
254
- * <td>NavError object (instance of {@link sap.fe.navigation.NavError}) that describes which kind of error occurred</td>
255
- * <tr>
256
- * <td align="center">{string}</td>
257
- * <td><b>oError.errorCode</b></td>
258
- * <td>Code to identify the error</td>
259
- * <tr>
260
- * <td align="center">{string}</td>
261
- * <td><b>oError.type</b></td>
262
- * <td>Severity of the error (info/warning/error)</td>
263
- * <tr>
264
- * <td align="center">{array}</td>
265
- * <td><b>oError.params</b></td>
266
- * <td>An array of objects (typically strings) that describe additional value parameters required for generating the message</td>
267
- * </table>
276
+ * @public
268
277
  * @example <code>
269
278
  * sap.ui.define(["sap/fe/navigation/NavigationHandler", "sap/fe/navigation/SelectionVariant"], function (NavigationHandler, SelectionVariant) {
270
279
  * var oNavigationHandler = new NavigationHandler(oController);
@@ -312,7 +321,7 @@ sap.ui.define(
312
321
  oStartupParameters,
313
322
  bExPlace = false,
314
323
  oTmpData = {},
315
- that = this;
324
+ oNavHandler = this;
316
325
 
317
326
  oComponentData = this.oComponent.getComponentData();
318
327
  /*
@@ -376,7 +385,6 @@ sap.ui.define(
376
385
  sSelectionVariant = null;
377
386
  }
378
387
 
379
- var oNavHandler = this;
380
388
  var oNavArguments = {
381
389
  target: {
382
390
  semanticObject: sSemanticObject,
@@ -385,31 +393,26 @@ sap.ui.define(
385
393
  params: mParameters || {}
386
394
  };
387
395
 
388
- if (sNavMode) {
389
- oNavArguments.params["sap-ushell-navmode"] = bExPlace ? "explace" : "inplace";
390
- }
391
-
392
- var oSupportedPromise = oNavHandler.oCrossAppNavService.isNavigationSupported([oNavArguments], oNavHandler.oComponent);
393
- oSupportedPromise.done(function (oTargets) {
394
- if (oTargets[0].supported) {
395
- var oReturn;
396
-
397
- if (!bExPlace) {
398
- oReturn = oNavHandler.storeInnerAppStateWithImmediateReturn(oInnerAppData, true);
399
- if (oReturn && oReturn.appStateKey) {
400
- oNavHandler.replaceHash(oReturn.appStateKey);
401
- }
402
- }
403
-
404
- if (!oXAppDataObj.selectionVariant) {
405
- oXAppDataObj.selectionVariant = sSelectionVariant;
406
- }
396
+ var fnNavigate = function (oCrossAppNavService) {
397
+ if (!oXAppDataObj.selectionVariant) {
398
+ oXAppDataObj.selectionVariant = sSelectionVariant;
399
+ }
407
400
 
408
- oXAppDataObj = oNavHandler._removeMeasureBasedInformation(oXAppDataObj);
401
+ var fnNavExplace = function () {
402
+ var sNewHrefPromise = oCrossAppNavService.hrefForExternalAsync(oNavArguments, oNavHandler.oComponent);
403
+ sNewHrefPromise
404
+ .then(function (sNewHref) {
405
+ openWindow(sNewHref);
406
+ })
407
+ .catch(function (oError) {
408
+ Log.error("Error while retireving hrefForExternal : " + oError);
409
+ });
410
+ };
409
411
 
410
- oReturn = oNavHandler._saveAppStateWithImmediateReturn(oXAppDataObj, fnOnError);
411
- if (oReturn) {
412
- oNavArguments.appStateKey = oReturn.appStateKey;
412
+ oXAppDataObj = oNavHandler._removeMeasureBasedInformation(oXAppDataObj);
413
+ return oNavHandler._fnSaveAppStateAsync(oXAppDataObj, fnOnError).then(function (oSaveAppStateReturn) {
414
+ if (oSaveAppStateReturn) {
415
+ oNavArguments.appStateKey = oSaveAppStateReturn.appStateKey;
413
416
 
414
417
  // Remark:
415
418
  // The Cross App Service takes care of encoding parameter keys and values. Example:
@@ -419,47 +422,71 @@ sap.ui.define(
419
422
  // toExternal sets sap-xapp-state in the URL if appStateKey is provided in oNavArguments
420
423
  // toExternal has issues on sticky apps FIORITECHP1-14400, temp fix using hrefForExternal
421
424
  if (sNavMode == "explace") {
422
- var sNewHrefPromise = oNavHandler.oCrossAppNavService.hrefForExternalAsync(
423
- oNavArguments,
424
- oNavHandler.oComponent
425
- );
426
- sNewHrefPromise
427
- .then(function (sNewHref) {
428
- openWindow(sNewHref);
429
- })
430
- .catch(function (oError) {
431
- Log.error("Error while retireving hrefForExternal : " + oError);
432
- });
425
+ fnNavExplace();
433
426
  } else {
434
- var ptoExt = oNavHandler.oCrossAppNavService.toExternal(oNavArguments, oNavHandler.oComponent);
427
+ var ptoExt = oCrossAppNavService.toExternal(oNavArguments, oNavHandler.oComponent);
435
428
  // TODO: This is just a temporary solution to allow FE V2 to use toExternal promise.
436
- if (that._navigateCallback) {
437
- that._navigateCallback(ptoExt);
429
+ if (oNavHandler._navigateCallback) {
430
+ oNavHandler._navigateCallback(ptoExt);
438
431
  }
439
432
  }
440
433
  } // else : error was already reported
441
- } else {
442
- // intent is not supported
434
+ });
435
+ };
436
+ var fnStoreAndNavigate = function (oCrossAppNavService) {
437
+ oNavHandler
438
+ .storeInnerAppState(oInnerAppData, true)
439
+ .then(function (sAppStateKey) {
440
+ if (sAppStateKey) {
441
+ oNavHandler.replaceHash(sAppStateKey);
442
+ }
443
+ return fnNavigate(oCrossAppNavService);
444
+ })
445
+ .catch(function (oError) {
446
+ if (fnOnError) {
447
+ fnOnError(oError);
448
+ }
449
+ });
450
+ };
451
+ if (sNavMode) {
452
+ oNavArguments.params["sap-ushell-navmode"] = bExPlace ? "explace" : "inplace";
453
+ }
454
+ oNavHandler
455
+ ._getAppNavigationServiceAsync()
456
+ .then(function (oCrossAppNavService) {
457
+ var oSupportedPromise = oCrossAppNavService.isNavigationSupported([oNavArguments], oNavHandler.oComponent);
458
+ oSupportedPromise.done(function (oTargets) {
459
+ if (oTargets[0].supported) {
460
+ if (!bExPlace) {
461
+ fnStoreAndNavigate(oCrossAppNavService);
462
+ } else {
463
+ fnNavigate(oCrossAppNavService);
464
+ }
465
+ } else if (fnOnError) {
466
+ // intent is not supported
467
+ var oError = new NavError("NavigationHandler.isIntentSupported.notSupported");
468
+ fnOnError(oError);
469
+ }
470
+ });
471
+
443
472
  if (fnOnError) {
444
- var oError = new NavError("NavigationHandler.isIntentSupported.notSupported");
445
- fnOnError(oError);
473
+ oSupportedPromise.fail(function () {
474
+ // technical error: could not determine if intent is supported
475
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.isIntentSupported.failed");
476
+ fnOnError(oError);
477
+ });
446
478
  }
447
- }
448
- });
449
-
450
- if (fnOnError) {
451
- oSupportedPromise.fail(function () {
452
- // technical error: could not determine if intent is supported
453
- var oError = oNavHandler._createTechnicalError("NavigationHandler.isIntentSupported.failed");
479
+ })
480
+ .catch(function (oError) {
454
481
  fnOnError(oError);
455
482
  });
456
- }
457
483
  },
458
484
 
459
485
  /**
460
486
  * Parses the incoming URL and returns a Promise. If this method detects a back navigation, the inner app state is returned in the resolved
461
487
  * Promise. Otherwise startup parameters will be merged into the app state provided by cross app navigation, and a combined app state will be
462
488
  * returned. The conflict resolution can be influenced with sParamHandlingMode defined in the constructor.
489
+ *
463
490
  * @returns {object} A Promise object to monitor when all the actions of the function have been executed. If the execution is successful, the
464
491
  * extracted app state, the startup parameters, and the type of navigation are returned, see also the example above. The app state is
465
492
  * an object that contains the following information:
@@ -545,12 +572,12 @@ sap.ui.define(
545
572
 
546
573
  var oMyDeferred = jQuery.Deferred();
547
574
  var oNavHandler = this;
548
- var parseUrlParams = function (oStartupParameters, aDefaultedParameters, oMyDeferred, sNavType) {
575
+ var parseUrlParams = function (oSubStartupParameters, aSubDefaultedParameters, oSubMyDeferred, sNavType) {
549
576
  // standard URL navigation
550
577
  var oSelVars = oNavHandler._splitInboundNavigationParameters(
551
578
  new SelectionVariant(),
552
- oStartupParameters,
553
- aDefaultedParameters
579
+ oSubStartupParameters,
580
+ aSubDefaultedParameters
554
581
  );
555
582
  if (oSelVars.oNavigationSelVar.isEmpty() && oSelVars.oDefaultedSelVar.isEmpty()) {
556
583
  // Startup parameters contain only technical parameters (SAP system) which were filtered out.
@@ -558,9 +585,9 @@ sap.ui.define(
558
585
  // Thus, consider this type of navigation as an initial navigation.
559
586
  if (sNavType === NavType.xAppState) {
560
587
  var oError = oNavHandler._createTechnicalError("NavigationHandler.getDataFromAppState.failed");
561
- oMyDeferred.reject(oError, oStartupParameters || {}, NavType.xAppState);
588
+ oSubMyDeferred.reject(oError, oSubStartupParameters || {}, NavType.xAppState);
562
589
  } else {
563
- oMyDeferred.resolve({}, oStartupParameters, NavType.initial);
590
+ oSubMyDeferred.resolve({}, oSubStartupParameters, NavType.initial);
564
591
  }
565
592
  } else {
566
593
  var oAppStateData = {};
@@ -568,7 +595,7 @@ sap.ui.define(
568
595
  oAppStateData.oSelectionVariant = oSelVars.oNavigationSelVar;
569
596
  oAppStateData.oDefaultedSelectionVariant = oSelVars.oDefaultedSelVar;
570
597
  oAppStateData.bNavSelVarHasDefaultsOnly = oSelVars.bNavSelVarHasDefaultsOnly;
571
- oMyDeferred.resolve(oAppStateData, oStartupParameters, sNavType);
598
+ oSubMyDeferred.resolve(oAppStateData, oSubStartupParameters, sNavType);
572
599
  }
573
600
  };
574
601
  if (sIAppState) {
@@ -578,58 +605,62 @@ sap.ui.define(
578
605
  // no back navigation
579
606
  var bIsXappStateNavigation = oComponentData["sap-xapp-state"] !== undefined;
580
607
  if (bIsXappStateNavigation) {
608
+ var that = this;
581
609
  // inner app state was not found in the AppHash, but xapp state => try to read the xapp state
582
- var oStartupPromise = this.oCrossAppNavService.getStartupAppState(this.oComponent);
583
-
584
- oStartupPromise.done(function (oAppState) {
585
- // get app state from sap-xapp-state,
586
- // create a copy, not only a reference, because we want to modify the object
587
- var oAppStateData = oAppState.getData();
588
- if (oAppStateData) {
589
- try {
590
- oAppStateData = JSON.parse(JSON.stringify(oAppStateData));
591
- } catch (x) {
592
- var oError = oNavHandler._createTechnicalError("NavigationHandler.AppStateData.parseError");
593
- oMyDeferred.reject(oError, oStartupParameters, NavType.xAppState);
594
- return oMyDeferred.promise();
595
- }
596
- }
597
-
598
- if (oAppStateData) {
599
- var oSelVar = new SelectionVariant(oAppStateData.selectionVariant);
610
+ this._getAppNavigationServiceAsync()
611
+ .then(function (oCrossAppNavService) {
612
+ var oStartupPromise = oCrossAppNavService.getStartupAppState(that.oComponent);
613
+ oStartupPromise.done(function (oAppState) {
614
+ // get app state from sap-xapp-state,
615
+ // create a copy, not only a reference, because we want to modify the object
616
+ var oAppStateData = oAppState.getData();
617
+ var oError;
618
+ if (oAppStateData) {
619
+ try {
620
+ oAppStateData = JSON.parse(JSON.stringify(oAppStateData));
621
+ } catch (x) {
622
+ oError = oNavHandler._createTechnicalError("NavigationHandler.AppStateData.parseError");
623
+ oMyDeferred.reject(oError, oStartupParameters, NavType.xAppState);
624
+ return oMyDeferred.promise();
625
+ }
626
+ }
600
627
 
601
- var oSelVars = oNavHandler._splitInboundNavigationParameters(
602
- oSelVar,
603
- oStartupParameters,
604
- aDefaultedParameters
605
- );
606
- oAppStateData.selectionVariant = oSelVars.oNavigationSelVar.toJSONString();
607
- oAppStateData.oSelectionVariant = oSelVars.oNavigationSelVar;
608
- oAppStateData.oDefaultedSelectionVariant = oSelVars.oDefaultedSelVar;
609
- oAppStateData.bNavSelVarHasDefaultsOnly = oSelVars.bNavSelVarHasDefaultsOnly;
610
- oMyDeferred.resolve(oAppStateData, oStartupParameters, NavType.xAppState);
611
- } else {
612
- if (oStartupParameters) {
613
- parseUrlParams(oStartupParameters, aDefaultedParameters, oMyDeferred, NavType.xAppState);
614
- } else {
615
- // sap-xapp-state navigation, but ID has already expired, but URL parameters available
616
- oError = oNavHandler._createTechnicalError("NavigationHandler.getDataFromAppState.failed");
617
- oMyDeferred.reject(oError, oStartupParameters || {}, NavType.xAppState);
618
- }
619
- }
620
- });
621
- oStartupPromise.fail(function () {
622
- var oError = oNavHandler._createTechnicalError("NavigationHandler.getStartupState.failed");
623
- oMyDeferred.reject(oError, {}, NavType.xAppState);
624
- });
625
- } else {
628
+ if (oAppStateData) {
629
+ var oSelVar = new SelectionVariant(oAppStateData.selectionVariant);
630
+
631
+ var oSelVars = oNavHandler._splitInboundNavigationParameters(
632
+ oSelVar,
633
+ oStartupParameters,
634
+ aDefaultedParameters
635
+ );
636
+ oAppStateData.selectionVariant = oSelVars.oNavigationSelVar.toJSONString();
637
+ oAppStateData.oSelectionVariant = oSelVars.oNavigationSelVar;
638
+ oAppStateData.oDefaultedSelectionVariant = oSelVars.oDefaultedSelVar;
639
+ oAppStateData.bNavSelVarHasDefaultsOnly = oSelVars.bNavSelVarHasDefaultsOnly;
640
+ oMyDeferred.resolve(oAppStateData, oStartupParameters, NavType.xAppState);
641
+ } else if (oStartupParameters) {
642
+ parseUrlParams(oStartupParameters, aDefaultedParameters, oMyDeferred, NavType.xAppState);
643
+ } else {
644
+ // sap-xapp-state navigation, but ID has already expired, but URL parameters available
645
+ oError = oNavHandler._createTechnicalError("NavigationHandler.getDataFromAppState.failed");
646
+ oMyDeferred.reject(oError, oStartupParameters || {}, NavType.xAppState);
647
+ }
648
+ });
649
+ oStartupPromise.fail(function () {
650
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.getStartupState.failed");
651
+ oMyDeferred.reject(oError, {}, NavType.xAppState);
652
+ });
653
+ })
654
+ .catch(function () {
655
+ var oError = oNavHandler._createTechnicalError("NavigationHandler._getAppNavigationServiceAsync.failed");
656
+ oMyDeferred.reject(oError, {}, NavType.xAppState);
657
+ });
658
+ } else if (oStartupParameters) {
626
659
  // no sap-xapp-state
627
- if (oStartupParameters) {
628
- parseUrlParams(oStartupParameters, aDefaultedParameters, oMyDeferred, NavType.URLParams);
629
- } else {
630
- // initial navigation
631
- oMyDeferred.resolve({}, {}, NavType.initial);
632
- }
660
+ parseUrlParams(oStartupParameters, aDefaultedParameters, oMyDeferred, NavType.URLParams);
661
+ } else {
662
+ // initial navigation
663
+ oMyDeferred.resolve({}, {}, NavType.initial);
633
664
  }
634
665
  }
635
666
 
@@ -680,6 +711,7 @@ sap.ui.define(
680
711
 
681
712
  /**
682
713
  * Checks if the passed parameter is considered as technical parameter.
714
+ *
683
715
  * @param {string} sParameterName Name of a request parameter, considered as technical parameter.
684
716
  * @returns {boolean} Indicates if the parameter is considered as technical parameter or not.
685
717
  * @private
@@ -710,6 +742,7 @@ sap.ui.define(
710
742
 
711
743
  /**
712
744
  * Rmoves if the passed parameter is considered as technical parameter.
745
+ *
713
746
  * @param {object} oSelectionVariant Selection Variant which consists of technical Parameters.
714
747
  * @returns {object} Selection Variant without technical Parameters.
715
748
  * @private
@@ -829,13 +862,11 @@ sap.ui.define(
829
862
  throw new NavError("NavigationHandler.INVALID_INPUT");
830
863
  }
831
864
  }
832
- } else {
865
+ } else if (aDefaultedParameters.indexOf(sPropName) > -1) {
833
866
  // parameter only in SelVar
834
- if (aDefaultedParameters.indexOf(sPropName) > -1) {
835
- oDefaultedSelVar.massAddSelectOption(sPropName, oSelectionVariant.getValue(sPropName));
836
- } else {
837
- oNavigationSelVar.massAddSelectOption(sPropName, oSelectionVariant.getValue(sPropName));
838
- }
867
+ oDefaultedSelVar.massAddSelectOption(sPropName, oSelectionVariant.getValue(sPropName));
868
+ } else {
869
+ oNavigationSelVar.massAddSelectOption(sPropName, oSelectionVariant.getValue(sPropName));
839
870
  }
840
871
  }
841
872
 
@@ -881,6 +912,7 @@ sap.ui.define(
881
912
 
882
913
  /**
883
914
  * Changes the URL according to the current sAppStateKey. As an reaction route change event will be triggered.
915
+ *
884
916
  * @param {string} sAppStateKey The new app state key.
885
917
  * @public
886
918
  */
@@ -897,6 +929,7 @@ sap.ui.define(
897
929
 
898
930
  /**
899
931
  * Changes the URL according to the current app state and stores the app state for later retrieval.
932
+ *
900
933
  * @param {object} mInnerAppData Object containing the current state of the app
901
934
  * @param {string} mInnerAppData.selectionVariant Stringified JSON object as returned, for example, from getDataSuiteFormat() of the
902
935
  * SmartFilterBar control
@@ -907,6 +940,8 @@ sap.ui.define(
907
940
  * @param {object} [mInnerAppData.semanticDates] Object containing semanticDates filter information
908
941
  * @param {boolean} [bImmediateHashReplace=true] If set to false, the inner app hash will not be replaced until storing is successful; do not
909
942
  * set to false if you cannot react to the resolution of the Promise, for example, when calling the beforeLinkPressed event
943
+ * @param {boolean} [bSkipHashReplace=false] If set to true, the inner app hash will not be replaced in the storeInnerAppState. Also the bImmediateHashReplace
944
+ * will be ignored.
910
945
  * @returns {object} A Promise object to monitor when all the actions of the function have been executed; if the execution is successful, the
911
946
  * app state key is returned; if an error occurs, an object of type {@link sap.fe.navigation.NavError} is
912
947
  * returned
@@ -933,7 +968,7 @@ sap.ui.define(
933
968
  * });
934
969
  * </code>
935
970
  */
936
- storeInnerAppState: function (mInnerAppData, bImmediateHashReplace) {
971
+ storeInnerAppState: function (mInnerAppData, bImmediateHashReplace, bSkipHashReplace) {
937
972
  if (typeof bImmediateHashReplace !== "boolean") {
938
973
  bImmediateHashReplace = true; // default
939
974
  }
@@ -976,7 +1011,7 @@ sap.ui.define(
976
1011
 
977
1012
  var fnOnAfterSave = function (sAppStateKey) {
978
1013
  // replace inner app hash with new appStateKey in url
979
- if (!bImmediateHashReplace) {
1014
+ if (!bSkipHashReplace && !bImmediateHashReplace) {
980
1015
  fnReplaceHash(sAppStateKey);
981
1016
  }
982
1017
 
@@ -990,26 +1025,31 @@ sap.ui.define(
990
1025
  oMyDeferred.reject(oError);
991
1026
  };
992
1027
 
993
- var sAppStateKey = this._saveAppState(mInnerAppData, fnOnAfterSave, fnOnError);
994
- /*
995
- * Note that _sapAppState may return 'undefined' in case that the parsing has failed. In this case, we should not trigger the replacement
996
- * of the App Hash with the generated key, as the container was not written before. Note as well that the error handling has already
997
- * happened before by making the oMyDeferred promise fail (see fnOnError above).
998
- */
999
- if (sAppStateKey !== undefined) {
1000
- // replace inner app hash with new appStateKey in url
1001
- // note: we do not wait for the save to be completed: this asynchronously behaviour is necessary if
1002
- // this method is called e.g. in a onLinkPressed event with no possibility to wait for the promise resolution
1003
- if (bImmediateHashReplace) {
1004
- fnReplaceHash(sAppStateKey);
1005
- }
1006
- }
1028
+ this._saveAppStateAsync(mInnerAppData, fnOnAfterSave, fnOnError)
1029
+ .then(function (sAppStateKey) {
1030
+ /* Note that _sapAppState may return 'undefined' in case that the parsing has failed. In this case, we should not trigger the replacement
1031
+ * of the App Hash with the generated key, as the container was not written before. Note as well that the error handling has already
1032
+ * happened before by making the oMyDeferred promise fail (see fnOnError above).
1033
+ */
1034
+ if (sAppStateKey !== undefined) {
1035
+ // replace inner app hash with new appStateKey in url
1036
+ // note: we do not wait for the save to be completed: this asynchronously behaviour is necessary if
1037
+ // this method is called e.g. in a onLinkPressed event with no possibility to wait for the promise resolution
1038
+ if (!bSkipHashReplace && bImmediateHashReplace) {
1039
+ fnReplaceHash(sAppStateKey);
1040
+ }
1041
+ }
1042
+ })
1043
+ .catch(function () {
1044
+ Log.error("NavigationHandler._saveAppStateAsync failed");
1045
+ });
1007
1046
 
1008
1047
  return oMyDeferred.promise();
1009
1048
  },
1010
1049
 
1011
1050
  /**
1012
1051
  * Changes the URL according to the current app state and stores the app state for later retrieval.
1052
+ *
1013
1053
  * @param {object} mInnerAppData Object containing the current state of the app
1014
1054
  * @param {string} mInnerAppData.selectionVariant Stringified JSON object as returned, for example, from getDataSuiteFormat() of the
1015
1055
  * SmartFilterBar control
@@ -1051,13 +1091,19 @@ sap.ui.define(
1051
1091
  * });
1052
1092
  * </code>
1053
1093
  * @public
1094
+ * @deprecated as of version 1.104. Use the {@link sap.fe.navigation.NavigationHandler.storeInnerAppState} instead.
1054
1095
  */
1055
1096
  storeInnerAppStateWithImmediateReturn: function (mInnerAppData, bImmediateHashReplace) {
1097
+ Log.error(
1098
+ "Deprecated API call of 'sap.fe.navigation.NavigationHandler.storeInnerAppStateWithImmediateReturn'. Please use 'storeInnerAppState' instead",
1099
+ null,
1100
+ "sap.fe.navigation.NavigationHandler"
1101
+ );
1056
1102
  if (typeof bImmediateHashReplace !== "boolean") {
1057
1103
  bImmediateHashReplace = false; // default
1058
1104
  }
1059
1105
 
1060
- var that = this;
1106
+ var oNavHandler = this;
1061
1107
  var oAppStatePromise = jQuery.Deferred();
1062
1108
 
1063
1109
  // in case mInnerAppState is empty, do not overwrite the last saved state
@@ -1087,12 +1133,12 @@ sap.ui.define(
1087
1133
  var fnOnAfterSave = function (sAppStateKey) {
1088
1134
  // replace inner app hash with new appStateKey in url
1089
1135
  if (!bImmediateHashReplace) {
1090
- that.replaceHash(sAppStateKey);
1136
+ oNavHandler.replaceHash(sAppStateKey);
1091
1137
  }
1092
1138
 
1093
1139
  // remember last saved state
1094
- that._oLastSavedInnerAppData.oAppData = mInnerAppData;
1095
- that._oLastSavedInnerAppData.sAppStateKey = sAppStateKey;
1140
+ oNavHandler._oLastSavedInnerAppData.oAppData = mInnerAppData;
1141
+ oNavHandler._oLastSavedInnerAppData.sAppStateKey = sAppStateKey;
1096
1142
  oAppStatePromise.resolve(sAppStateKey);
1097
1143
  };
1098
1144
 
@@ -1133,6 +1179,9 @@ sap.ui.define(
1133
1179
  * <li>The method <code>oTableEventParameters.open()</code> is called. Note that this does not really open the popover, but the SmartLink
1134
1180
  * control proceeds with firing the event <code>navigationTargetsObtained</code>.</li>
1135
1181
  * </ul>.
1182
+ * <br>
1183
+ * <b>Node:</b> If the <code>oExternalAppData</code> parameter is not supplied, the external app data will be calculated based on
1184
+ * the <code>mInnerAppData</code> data.<br>.
1136
1185
  *
1137
1186
  * @param {object} oTableEventParameters The parameters made available by the SmartTable control when the SmartLink control has been clicked,
1138
1187
  * an instance of a PopOver object
@@ -1155,9 +1204,7 @@ sap.ui.define(
1155
1204
  * @returns {object} A Promise object to monitor when all actions of the function have been executed; if the execution is successful, the
1156
1205
  * modified oTableEventParameters is returned; if an error occurs, an error object of type
1157
1206
  * {@link sap.fe.navigation.NavError} is returned
1158
- * @public <br>
1159
- * <b>Node:</b> If the <code>oExternalAppData</code> parameter is not supplied, the external app data will be calculated based on
1160
- * the <code>mInnerAppData</code> data.<br>
1207
+ * @public
1161
1208
  * @example <code>
1162
1209
  * sap.ui.define(["sap/fe/navigation/NavigationHandler", "sap/fe/navigation/SelectionVariant"], function (NavigationHandler, SelectionVariant) {
1163
1210
  * //event handler for the smart link event "beforePopoverOpens"
@@ -1205,9 +1252,9 @@ sap.ui.define(
1205
1252
  oXAppDataObj = oExternalAppData;
1206
1253
  }
1207
1254
 
1208
- var fnStoreXappAndCallOpen = function (mSemanticAttributes, sSelectionVariant) {
1255
+ var fnStoreXappAndCallOpen = function (mSubSemanticAttributes, sSubSelectionVariant) {
1209
1256
  // mix the semantic attributes (e.g. from the row line) with the selection variant (e.g. from the filter bar)
1210
- sSelectionVariant = oXAppDataObj.selectionVariant || sSelectionVariant || "{}";
1257
+ sSubSelectionVariant = oXAppDataObj.selectionVariant || sSubSelectionVariant || "{}";
1211
1258
 
1212
1259
  var iSuppressionBehavior = SuppressionBehavior.raiseErrorOnNull | SuppressionBehavior.raiseErrorOnUndefined;
1213
1260
  /*
@@ -1218,11 +1265,11 @@ sap.ui.define(
1218
1265
  */
1219
1266
 
1220
1267
  var oMixedSelVar = oNavHandler.mixAttributesAndSelectionVariant(
1221
- mSemanticAttributes,
1222
- sSelectionVariant,
1268
+ mSubSemanticAttributes,
1269
+ sSubSelectionVariant,
1223
1270
  iSuppressionBehavior
1224
1271
  );
1225
- sSelectionVariant = oMixedSelVar.toJSONString();
1272
+ sSubSelectionVariant = oMixedSelVar.toJSONString();
1226
1273
 
1227
1274
  // enrich the semantic attributes with single selections from the selection variant
1228
1275
  var oTmpData = {};
@@ -1232,17 +1279,17 @@ sap.ui.define(
1232
1279
 
1233
1280
  oTmpData = oNavHandler._checkIsPotentiallySensitive(oTmpData);
1234
1281
 
1235
- mSemanticAttributes = oTmpData.selectionVariant
1282
+ mSubSemanticAttributes = oTmpData.selectionVariant
1236
1283
  ? oNavHandler._getURLParametersFromSelectionVariant(new SelectionVariant(oTmpData.selectionVariant))
1237
1284
  : {};
1238
1285
 
1239
1286
  var fnOnContainerSave = function (sAppStateKey) {
1240
1287
  if (oTableEventParameters === undefined) {
1241
1288
  // If oTableEventParameters is undefined, return both semanticAttributes and appStatekey
1242
- oMyDeferred.resolve(mSemanticAttributes, sAppStateKey);
1289
+ oMyDeferred.resolve(mSubSemanticAttributes, sAppStateKey);
1243
1290
  } else {
1244
1291
  // set the stored data in popover and call open()
1245
- oTableEventParameters.setSemanticAttributes(mSemanticAttributes);
1292
+ oTableEventParameters.setSemanticAttributes(mSubSemanticAttributes);
1246
1293
  oTableEventParameters.setAppStateKey(sAppStateKey);
1247
1294
  oTableEventParameters.open(); // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Note that "open" does not open the popover, but proceeds
1248
1295
  // with firing the onNavTargetsObtained event.
@@ -1254,11 +1301,11 @@ sap.ui.define(
1254
1301
  oMyDeferred.reject(oError);
1255
1302
  };
1256
1303
 
1257
- oXAppDataObj.selectionVariant = sSelectionVariant;
1304
+ oXAppDataObj.selectionVariant = sSubSelectionVariant;
1258
1305
 
1259
1306
  oXAppDataObj = oNavHandler._removeMeasureBasedInformation(oXAppDataObj);
1260
1307
 
1261
- oNavHandler._saveAppState(oXAppDataObj, fnOnContainerSave, fnOnError);
1308
+ oNavHandler._saveAppStateAsync(oXAppDataObj, fnOnContainerSave, fnOnError);
1262
1309
  };
1263
1310
 
1264
1311
  if (mInnerAppData) {
@@ -1282,6 +1329,7 @@ sap.ui.define(
1282
1329
 
1283
1330
  /**
1284
1331
  * Processes selectionVariant string and returns a Promise object (semanticAttributes and AppStateKey).
1332
+ *
1285
1333
  * @param {string} sSelectionVariant Stringified JSON object
1286
1334
  * @returns {object} A Promise object to monitor when all actions of the function have been executed; if the execution is successful, the
1287
1335
  * semanticAttributes as well as the appStateKey are returned; if an error occurs, an error object of type
@@ -1378,9 +1426,10 @@ sap.ui.define(
1378
1426
  * overriding existing properties in the selection variant. The new selection variant does not contain any parameters. All parameters are
1379
1427
  * merged into select options. The output of this function, converted to a JSON string, can be used for the
1380
1428
  * {@link #.navigate NavigationHandler.navigate} method.
1429
+ *
1381
1430
  * @param {object|Array} vSemanticAttributes Object/(Array of Objects) containing key/value pairs
1382
1431
  * @param {string} sSelectionVariant The selection variant in string format as provided by the SmartFilterBar control
1383
- * @param {int} [iSuppressionBehavior=sap.fe.navigation.SuppressionBehavior.standard] Indicates whether semantic
1432
+ * @param {number} [iSuppressionBehavior=sap.fe.navigation.SuppressionBehavior.standard] Indicates whether semantic
1384
1433
  * attributes with special values (see {@link sap.fe.navigation.SuppressionBehavior suppression behavior}) must be
1385
1434
  * suppressed before they are combined with the selection variant; several
1386
1435
  * {@link sap.fe.navigation.SuppressionBehavior suppression behaviors} can be combined with the bitwise OR operator
@@ -1407,7 +1456,7 @@ sap.ui.define(
1407
1456
  mixAttributesAndSelectionVariant: function (vSemanticAttributes, sSelectionVariant, iSuppressionBehavior) {
1408
1457
  var oSelectionVariant = new SelectionVariant(sSelectionVariant);
1409
1458
  var oNewSelVariant = new SelectionVariant();
1410
- var that = this;
1459
+ var oNavHandler = this;
1411
1460
 
1412
1461
  if (oSelectionVariant.getFilterContextUrl()) {
1413
1462
  oNewSelVariant.setFilterContextUrl(oSelectionVariant.getFilterContextUrl());
@@ -1417,7 +1466,7 @@ sap.ui.define(
1417
1466
  }
1418
1467
  if (Array.isArray(vSemanticAttributes)) {
1419
1468
  vSemanticAttributes.forEach(function (mSemanticAttributes) {
1420
- that._mixAttributesToSelVariant(mSemanticAttributes, oNewSelVariant, iSuppressionBehavior);
1469
+ oNavHandler._mixAttributesToSelVariant(mSemanticAttributes, oNewSelVariant, iSuppressionBehavior);
1421
1470
  });
1422
1471
  } else {
1423
1472
  this._mixAttributesToSelVariant(vSemanticAttributes, oNewSelVariant, iSuppressionBehavior);
@@ -1425,7 +1474,8 @@ sap.ui.define(
1425
1474
 
1426
1475
  // add parameters that are not part of the oNewSelVariant yet
1427
1476
  var aParameters = oSelectionVariant.getParameterNames();
1428
- for (var i = 0; i < aParameters.length; i++) {
1477
+ var i;
1478
+ for (i = 0; i < aParameters.length; i++) {
1429
1479
  if (!oNewSelVariant.getSelectOption(aParameters[i])) {
1430
1480
  oNewSelVariant.addSelectOption(aParameters[i], "I", "EQ", oSelectionVariant.getParameter(aParameters[i]));
1431
1481
  }
@@ -1472,32 +1522,56 @@ sap.ui.define(
1472
1522
 
1473
1523
  return vConvertedSelectionVariant;
1474
1524
  },
1525
+ _fnHandleAppStatePromise: function (oReturn, fnOnAfterSave, fnOnError) {
1526
+ oReturn.promise.done(function () {
1527
+ if (fnOnAfterSave) {
1528
+ fnOnAfterSave(oReturn.appStateKey);
1529
+ }
1530
+ });
1531
+
1532
+ if (fnOnError) {
1533
+ var oNavHandler = this;
1534
+ oReturn.promise.fail(function () {
1535
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.AppStateSave.failed");
1536
+ fnOnError(oError);
1537
+ });
1538
+ }
1539
+ },
1540
+ _saveAppStateAsync: function (oAppData, fnOnAfterSave, fnOnError) {
1541
+ var oNavHandler = this;
1542
+ return this._fnSaveAppStateAsync(oAppData, fnOnError).then(function (oReturn) {
1543
+ if (oReturn) {
1544
+ oNavHandler._fnHandleAppStatePromise(oReturn, fnOnAfterSave, fnOnError);
1545
+ return oReturn.appStateKey;
1546
+ }
1475
1547
 
1548
+ return undefined;
1549
+ });
1550
+ },
1476
1551
  _saveAppState: function (oAppData, fnOnAfterSave, fnOnError) {
1477
1552
  var oReturn = this._saveAppStateWithImmediateReturn(oAppData, fnOnError);
1478
1553
  if (oReturn) {
1479
- oReturn.promise.done(function () {
1480
- if (fnOnAfterSave) {
1481
- fnOnAfterSave(oReturn.appStateKey);
1482
- }
1483
- });
1484
-
1485
- if (fnOnError) {
1486
- var oNavHandler = this;
1487
- oReturn.promise.fail(function () {
1488
- var oError = oNavHandler._createTechnicalError("NavigationHandler.AppStateSave.failed");
1489
- fnOnError(oError);
1490
- });
1491
- }
1554
+ this._fnHandleAppStatePromise(oReturn, fnOnAfterSave, fnOnError);
1492
1555
  return oReturn.appStateKey;
1493
1556
  }
1494
1557
 
1495
1558
  return undefined;
1496
1559
  },
1497
-
1498
- _saveAppStateWithImmediateReturn: function (oAppData, fnOnError) {
1499
- var oAppState = this.oCrossAppNavService.createEmptyAppState(this.oComponent);
1560
+ _fnSaveAppStateWithImmediateReturn: function (oAppData, oAppState, fnOnError) {
1500
1561
  var sAppStateKey = oAppState.getKey();
1562
+ var oAppDataForSave = this._fetchAppDataForSave(oAppData, fnOnError);
1563
+ if (!oAppDataForSave) {
1564
+ return undefined;
1565
+ }
1566
+ oAppState.setData(oAppDataForSave);
1567
+ var oSavePromise = oAppState.save();
1568
+
1569
+ return {
1570
+ appStateKey: sAppStateKey,
1571
+ promise: oSavePromise.promise()
1572
+ };
1573
+ },
1574
+ _fetchAppDataForSave: function (oAppData, fnOnError) {
1501
1575
  var oAppDataForSave = {};
1502
1576
 
1503
1577
  if (oAppData.hasOwnProperty("selectionVariant")) {
@@ -1552,92 +1626,110 @@ sap.ui.define(
1552
1626
  oAppDataForSave = merge(oAppDataClone, oAppDataForSave);
1553
1627
  }
1554
1628
  oAppDataForSave = this._checkIsPotentiallySensitive(oAppDataForSave);
1555
- oAppState.setData(oAppDataForSave);
1556
- var oSavePromise = oAppState.save();
1557
-
1558
- return {
1559
- appStateKey: sAppStateKey,
1560
- promise: oSavePromise.promise()
1561
- };
1629
+ return oAppDataForSave;
1630
+ },
1631
+ _fnSaveAppStateAsync: function (oAppData, fnOnError) {
1632
+ var oNavHandler = this;
1633
+ return this._getAppNavigationServiceAsync().then(function (oCrossAppNavService) {
1634
+ return oCrossAppNavService
1635
+ .createEmptyAppStateAsync(oNavHandler.oComponent)
1636
+ .then(function (oAppState) {
1637
+ return oNavHandler._fnSaveAppStateWithImmediateReturn(oAppData, oAppState, fnOnError);
1638
+ })
1639
+ .catch(function (oError) {
1640
+ if (fnOnError) {
1641
+ fnOnError(oError);
1642
+ }
1643
+ });
1644
+ });
1645
+ },
1646
+ _saveAppStateWithImmediateReturn: function (oAppData, fnOnError) {
1647
+ var oAppState = this._getAppNavigationService().createEmptyAppState(this.oComponent);
1648
+ return this._fnSaveAppStateWithImmediateReturn(oAppData, oAppState, fnOnError);
1562
1649
  },
1563
1650
 
1564
1651
  _loadAppState: function (sAppStateKey, oDeferred) {
1565
- var oAppStatePromise = this.oCrossAppNavService.getAppState(this.oComponent, sAppStateKey);
1566
1652
  var oNavHandler = this;
1567
-
1568
- oAppStatePromise.done(function (oAppState) {
1569
- var oAppData = {};
1570
- var oAppDataLoaded = oAppState.getData();
1571
-
1572
- if (typeof oAppDataLoaded === "undefined") {
1573
- var oError = oNavHandler._createTechnicalError("NavigationHandler.getDataFromAppState.failed");
1574
- oDeferred.reject(oError, {}, NavType.iAppState);
1575
- } else {
1576
- if (oNavHandler._sMode === Mode.ODataV2) {
1577
- oAppData = {
1578
- selectionVariant: "{}",
1579
- oSelectionVariant: new SelectionVariant(),
1580
- oDefaultedSelectionVariant: new SelectionVariant(),
1581
- bNavSelVarHasDefaultsOnly: false,
1582
- tableVariantId: "",
1583
- customData: {},
1584
- appStateKey: sAppStateKey,
1585
- presentationVariant: {},
1586
- valueTexts: {},
1587
- semanticDates: {}
1588
- };
1589
- if (oAppDataLoaded.selectionVariant) {
1590
- /*
1591
- * In case that we get an object from the stored AppData (=persistency), we need to stringify the JSON object.
1592
- */
1593
- oAppData.selectionVariant = oNavHandler._ensureSelectionVariantFormatString(
1594
- oAppDataLoaded.selectionVariant
1595
- );
1596
- oAppData.oSelectionVariant = new SelectionVariant(oAppData.selectionVariant);
1597
- }
1598
- if (oAppDataLoaded.tableVariantId) {
1599
- oAppData.tableVariantId = oAppDataLoaded.tableVariantId;
1600
- }
1601
- if (oAppDataLoaded.customData) {
1602
- oAppData.customData = oAppDataLoaded.customData;
1603
- }
1604
- if (oAppDataLoaded.presentationVariant) {
1605
- oAppData.presentationVariant = oAppDataLoaded.presentationVariant;
1606
- }
1607
- if (oAppDataLoaded.valueTexts) {
1608
- oAppData.valueTexts = oAppDataLoaded.valueTexts;
1609
- }
1610
- if (oAppDataLoaded.semanticDates) {
1611
- oAppData.semanticDates = oAppDataLoaded.semanticDates;
1612
- }
1613
- } else {
1614
- oAppData = merge(oAppData, oAppDataLoaded);
1615
- if (oAppDataLoaded.selectionVariant) {
1616
- /*
1617
- * In case that we get an object from the stored AppData (=persistency), we need to stringify the JSON object.
1618
- */
1619
- oAppData.selectionVariant = oNavHandler._ensureSelectionVariantFormatString(
1620
- oAppDataLoaded.selectionVariant
1621
- );
1622
- oAppData.oSelectionVariant = new SelectionVariant(oAppData.selectionVariant);
1653
+ this._getAppNavigationServiceAsync()
1654
+ .then(function (oCrossAppNavService) {
1655
+ var oAppStatePromise = oCrossAppNavService.getAppState(oNavHandler.oComponent, sAppStateKey);
1656
+ oAppStatePromise.done(function (oAppState) {
1657
+ var oAppData = {};
1658
+ var oAppDataLoaded = oAppState.getData();
1659
+
1660
+ if (typeof oAppDataLoaded === "undefined") {
1661
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.getDataFromAppState.failed");
1662
+ oDeferred.reject(oError, {}, NavType.iAppState);
1663
+ } else if (oNavHandler._sMode === Mode.ODataV2) {
1664
+ oAppData = {
1665
+ selectionVariant: "{}",
1666
+ oSelectionVariant: new SelectionVariant(),
1667
+ oDefaultedSelectionVariant: new SelectionVariant(),
1668
+ bNavSelVarHasDefaultsOnly: false,
1669
+ tableVariantId: "",
1670
+ customData: {},
1671
+ appStateKey: sAppStateKey,
1672
+ presentationVariant: {},
1673
+ valueTexts: {},
1674
+ semanticDates: {}
1675
+ };
1676
+ if (oAppDataLoaded.selectionVariant) {
1677
+ /*
1678
+ * In case that we get an object from the stored AppData (=persistency), we need to stringify the JSON object.
1679
+ */
1680
+ oAppData.selectionVariant = oNavHandler._ensureSelectionVariantFormatString(
1681
+ oAppDataLoaded.selectionVariant
1682
+ );
1683
+ oAppData.oSelectionVariant = new SelectionVariant(oAppData.selectionVariant);
1684
+ }
1685
+ if (oAppDataLoaded.tableVariantId) {
1686
+ oAppData.tableVariantId = oAppDataLoaded.tableVariantId;
1687
+ }
1688
+ if (oAppDataLoaded.customData) {
1689
+ oAppData.customData = oAppDataLoaded.customData;
1690
+ }
1691
+ if (oAppDataLoaded.presentationVariant) {
1692
+ oAppData.presentationVariant = oAppDataLoaded.presentationVariant;
1693
+ }
1694
+ if (oAppDataLoaded.valueTexts) {
1695
+ oAppData.valueTexts = oAppDataLoaded.valueTexts;
1696
+ }
1697
+ if (oAppDataLoaded.semanticDates) {
1698
+ oAppData.semanticDates = oAppDataLoaded.semanticDates;
1699
+ }
1700
+ } else {
1701
+ oAppData = merge(oAppData, oAppDataLoaded);
1702
+ if (oAppDataLoaded.selectionVariant) {
1703
+ /*
1704
+ * In case that we get an object from the stored AppData (=persistency), we need to stringify the JSON object.
1705
+ */
1706
+ oAppData.selectionVariant = oNavHandler._ensureSelectionVariantFormatString(
1707
+ oAppDataLoaded.selectionVariant
1708
+ );
1709
+ oAppData.oSelectionVariant = new SelectionVariant(oAppData.selectionVariant);
1710
+ }
1623
1711
  }
1624
- }
1625
- }
1626
1712
 
1627
- // resolve is called on passed Deferred object to trigger a call of the done method, if implemented
1628
- // the done method will receive the loaded appState and the navigation type as parameters
1629
- oDeferred.resolve(oAppData, {}, NavType.iAppState);
1630
- });
1631
- oAppStatePromise.fail(function () {
1632
- var oError = oNavHandler._createTechnicalError("NavigationHandler.getAppState.failed");
1633
- oDeferred.reject(oError, {}, NavType.iAppState);
1634
- });
1713
+ // resolve is called on passed Deferred object to trigger a call of the done method, if implemented
1714
+ // the done method will receive the loaded appState and the navigation type as parameters
1715
+ oDeferred.resolve(oAppData, {}, NavType.iAppState);
1716
+ });
1717
+ oAppStatePromise.fail(function () {
1718
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.getAppState.failed");
1719
+ oDeferred.reject(oError, {}, NavType.iAppState);
1720
+ });
1721
+ })
1722
+ .catch(function () {
1723
+ var oError = oNavHandler._createTechnicalError("NavigationHandler._getAppNavigationServiceAsync.failed");
1724
+ oDeferred.reject(oError, {}, NavType.iAppState);
1725
+ });
1635
1726
  },
1636
1727
 
1637
1728
  /**
1638
1729
  * Retrieves the parameter value of the sap-iapp-state (the internal apps) from the AppHash string. It automatically takes care about
1639
1730
  * compatibility between the old and the new approach of the sap-iapp-state. Precedence is that the new approach is favoured against the old
1640
1731
  * approach.
1732
+ *
1641
1733
  * @param {string} sAppHash The AppHash, which may contain a sap-iapp-state parameter (both old and/or new approach)
1642
1734
  * @returns {string} The value of sap-iapp-state (i.e. the name of the container to retrieve the parameters), or <code>undefined</code> in
1643
1735
  * case that no sap-iapp-state was found in <code>sAppHash</code>.
@@ -1677,6 +1769,7 @@ sap.ui.define(
1677
1769
  * Replaces (or inserts) a parameter value (an AppStateKey) for the sap-iapp-state into an existing AppHash string. Other routes/parameters
1678
1770
  * are ignored and returned without modification ("environmental agnostic" property). Only the new approach (sap-iapp-state as query parameter
1679
1771
  * in the AppHash) is being issued.
1772
+ *
1680
1773
  * @param {string} sAppHash The AppHash into which the sap-iapp-state parameter shall be made available
1681
1774
  * @param {string} sAppStateKey The key value of the AppState which shall be stored as parameter value of the sap-iapp-state property.
1682
1775
  * @returns {string} The modified sAppHash string, such that the sap-iapp-state has been set based on the new (query option-based)
@@ -1695,16 +1788,16 @@ sap.ui.define(
1695
1788
  return "?" + sNewIAppState;
1696
1789
  }
1697
1790
 
1698
- var fnAppendToQueryParameter = function (sAppHash) {
1791
+ var fnAppendToQueryParameter = function (sSubAppHash) {
1699
1792
  // there is an AppHash available, but it does not contain a sap-iapp-state parameter yet - we need to append one
1700
1793
 
1701
1794
  // new approach: we need to check, if a set of query parameters is already available
1702
- if (sAppHash.indexOf("?") !== -1) {
1795
+ if (sSubAppHash.indexOf("?") !== -1) {
1703
1796
  // there are already query parameters available - append it as another parameter
1704
- return sAppHash + "&" + sNewIAppState;
1797
+ return sSubAppHash + "&" + sNewIAppState;
1705
1798
  }
1706
1799
  // there are no a query parameters available yet; create a set with a single parameter
1707
- return sAppHash + "?" + sNewIAppState;
1800
+ return sSubAppHash + "?" + sNewIAppState;
1708
1801
  };
1709
1802
 
1710
1803
  if (!this._getInnerAppStateKey(sAppHash)) {
@@ -1721,9 +1814,9 @@ sap.ui.define(
1721
1814
 
1722
1815
  // we need to remove the old AppHash entirely and replace it with a new one.
1723
1816
 
1724
- var fnReplaceOldApproach = function (rOldApproach, sAppHash) {
1725
- sAppHash = sAppHash.replace(rOldApproach, "");
1726
- return fnAppendToQueryParameter(sAppHash);
1817
+ var fnReplaceOldApproach = function (rOldApproach, sSubAppHash) {
1818
+ sSubAppHash = sSubAppHash.replace(rOldApproach, "");
1819
+ return fnAppendToQueryParameter(sSubAppHash);
1727
1820
  };
1728
1821
 
1729
1822
  if (this._rIAppStateOld.test(sAppHash)) {
@@ -1741,9 +1834,10 @@ sap.ui.define(
1741
1834
  _getURLParametersFromSelectionVariant: function (vSelectionVariant) {
1742
1835
  var mURLParameters = {};
1743
1836
  var i = 0;
1837
+ var oSelectionVariant;
1744
1838
 
1745
1839
  if (typeof vSelectionVariant === "string") {
1746
- var oSelectionVariant = new SelectionVariant(vSelectionVariant);
1840
+ oSelectionVariant = new SelectionVariant(vSelectionVariant);
1747
1841
  } else if (typeof vSelectionVariant === "object") {
1748
1842
  oSelectionVariant = vSelectionVariant;
1749
1843
  } else {
@@ -1776,6 +1870,7 @@ sap.ui.define(
1776
1870
  /**
1777
1871
  * Sets the model that is used for verification of sensitive information. If the model is not set, the unnamed component model is used for the
1778
1872
  * verification of sensitive information.
1873
+ *
1779
1874
  * @public
1780
1875
  * @param {sap.ui.model.odata.v2.ODataModel} oModel For checking sensitive information
1781
1876
  */
@@ -2077,6 +2172,7 @@ sap.ui.define(
2077
2172
  /**
2078
2173
  * The method verifies if any of the passed parameters/filters are marked as a measure. If this is the case, they are removed from the xapp
2079
2174
  * app data. <b>Note:</b> To use this method, the metadata must be loaded first.
2175
+ *
2080
2176
  * @param {object} oData With potential sensitive information (for OData, external representation using
2081
2177
  * <code>oSelectionVariant.toJSONObject()</code> must be used), with the <code>FilterContextUrl</code> or
2082
2178
  * <code>ParameterContextUrl</code> property.
@@ -2207,9 +2303,9 @@ sap.ui.define(
2207
2303
  * @param {object} oData Selection variant
2208
2304
  * @param {boolean} bMeasure Should measures be removed
2209
2305
  * @returns {object} The selection variant after sensitive data has been removed
2210
- **/
2306
+ */
2211
2307
  _removeSensitiveDataForODataV4: function (oData, bMeasure) {
2212
- var that = this,
2308
+ var oNavHandler = this,
2213
2309
  aFilterContextPart,
2214
2310
  oSV = new SelectionVariant(oData.selectionVariant),
2215
2311
  oModel = this._getModel();
@@ -2244,7 +2340,7 @@ sap.ui.define(
2244
2340
  if (aPropertyAnnotations) {
2245
2341
  if (
2246
2342
  (bMeasure && aPropertyAnnotations["@com.sap.vocabularies.Analytics.v1.Measure"]) ||
2247
- that._checkPropertyAnnotationsForSensitiveData(aPropertyAnnotations)
2343
+ oNavHandler._checkPropertyAnnotationsForSensitiveData(aPropertyAnnotations)
2248
2344
  ) {
2249
2345
  return true;
2250
2346
  } else if (aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"]) {
@@ -2276,7 +2372,5 @@ sap.ui.define(
2276
2372
  );
2277
2373
  }
2278
2374
  });
2279
-
2280
- return NavigationHandler;
2281
2375
  }
2282
2376
  );