@sapui5/sap.fe.navigation 1.103.0 → 1.106.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.
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@sapui5/sap.fe.navigation",
3
- "version": "1.103.0",
3
+ "version": "1.106.0",
4
4
  "description": "SAPUI5 Library sap.fe.navigation",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "author": "SAP SE (https://www.sap.com)",
7
7
  "homepage": "https://sap.github.io/ui5-tooling/pages/SAPUI5/",
8
8
  "scripts": {
9
9
  "build": "echo 'nothing to do'",
10
- "prepare-npm-sources": "babel target/npm-sources/src --out-dir target/npm-sources/src --extensions \".ts\" --config-file ../../.babelrc",
10
+ "prepare-npm-sources": "echo 'nothing to do'",
11
11
  "prepare-ts-class-doc": "echo 'nothing to do'",
12
12
  "prepare-ui5-build-sources": "echo 'nothing to do'",
13
13
  "test": "echo 'nothing to do'"
@@ -18,7 +18,6 @@
18
18
  ],
19
19
  "devDependencies": {
20
20
  "@babel/cli": "^7.14.8",
21
- "@ui5/cli": "^2.14.0",
22
- "mkdirp": "^1.0.4"
21
+ "@ui5/cli": "^2.14.0"
23
22
  }
24
23
  }
@@ -6,7 +6,7 @@
6
6
  <copyright>SAP UI development toolkit for HTML5 (SAPUI5)
7
7
  (c) Copyright 2009-2021 SAP SE. All rights reserved
8
8
  </copyright>
9
- <version>1.103.0</version>
9
+ <version>1.106.0</version>
10
10
 
11
11
  <documentation>UI5 library: sap.fe.navigation</documentation>
12
12
 
@@ -76,14 +76,15 @@ sap.ui.define(
76
76
  * <td>Indicates that the input parameter is invalid</td>
77
77
  * </tr>
78
78
  * </table>
79
- * @alias sap.fe.navigation.NavigationHandler
79
+ * @name sap.fe.navigation.NavigationHandler
80
80
  */
81
- return 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 */, {
82
82
  metadata: {
83
83
  publicMethods: [
84
84
  "navigate",
85
85
  "parseNavigation",
86
86
  "storeInnerAppState",
87
+ "storeInnerAppStateAsync",
87
88
  "storeInnerAppStateWithImmediateReturn",
88
89
  "processBeforeSmartLinkPopoverOpens",
89
90
  "processBeforeSemanticLinkPopoverOpens",
@@ -126,17 +127,6 @@ sap.ui.define(
126
127
  throw new NavError("NavigationHandler.INVALID_INPUT");
127
128
  }
128
129
 
129
- try {
130
- this.oCrossAppNavService = this._getAppNavigationService();
131
- if (!this.oCrossAppNavService) {
132
- Log.error("NavigationHandler: CrossApplicationNavigation is not available.");
133
- throw new NavError("NavigationHandler.NO.XAPPSERVICE");
134
- }
135
- } catch (ex) {
136
- Log.error("NavigationHandler: UShell service API for CrossApplicationNavigation is not available.");
137
- // throw new NavError("NavigationHandler.NO.SHELL");
138
- }
139
-
140
130
  this.IAPP_STATE = "sap-iapp-state";
141
131
  this.sDefaultedParamProp = "sap-ushell-defaultedParameterNames";
142
132
  this.sSAPSystemProp = "sap-system";
@@ -196,6 +186,23 @@ sap.ui.define(
196
186
  return sap.ushell.Container.getService("CrossApplicationNavigation");
197
187
  },
198
188
 
189
+ /**
190
+ * Retrieves the shell navigation service.
191
+ *
192
+ * @returns {object} The Navigation service
193
+ * @private
194
+ */
195
+ _getAppNavigationServiceAsync: function () {
196
+ return sap.ushell.Container.getServiceAsync("CrossApplicationNavigation")
197
+ .then(function (oCrossAppNavService) {
198
+ return oCrossAppNavService;
199
+ })
200
+ .catch(function () {
201
+ Log.error("NavigationHandler: CrossApplicationNavigation is not available.");
202
+ throw new NavError("NavigationHandler.NO.XAPPSERVICE");
203
+ });
204
+ },
205
+
199
206
  /**
200
207
  * Retrieves the reference to the router object for navigation for this given Controller.
201
208
  *
@@ -387,31 +394,26 @@ sap.ui.define(
387
394
  params: mParameters || {}
388
395
  };
389
396
 
390
- if (sNavMode) {
391
- oNavArguments.params["sap-ushell-navmode"] = bExPlace ? "explace" : "inplace";
392
- }
393
-
394
- var oSupportedPromise = oNavHandler.oCrossAppNavService.isNavigationSupported([oNavArguments], oNavHandler.oComponent);
395
- oSupportedPromise.done(function (oTargets) {
396
- if (oTargets[0].supported) {
397
- var oReturn;
398
-
399
- if (!bExPlace) {
400
- oReturn = oNavHandler.storeInnerAppStateWithImmediateReturn(oInnerAppData, true);
401
- if (oReturn && oReturn.appStateKey) {
402
- oNavHandler.replaceHash(oReturn.appStateKey);
403
- }
404
- }
405
-
406
- if (!oXAppDataObj.selectionVariant) {
407
- oXAppDataObj.selectionVariant = sSelectionVariant;
408
- }
397
+ var fnNavigate = function (oCrossAppNavService) {
398
+ if (!oXAppDataObj.selectionVariant) {
399
+ oXAppDataObj.selectionVariant = sSelectionVariant;
400
+ }
409
401
 
410
- oXAppDataObj = oNavHandler._removeMeasureBasedInformation(oXAppDataObj);
402
+ var fnNavExplace = function () {
403
+ var sNewHrefPromise = oCrossAppNavService.hrefForExternalAsync(oNavArguments, oNavHandler.oComponent);
404
+ sNewHrefPromise
405
+ .then(function (sNewHref) {
406
+ openWindow(sNewHref);
407
+ })
408
+ .catch(function (oError) {
409
+ Log.error("Error while retireving hrefForExternal : " + oError);
410
+ });
411
+ };
411
412
 
412
- oReturn = oNavHandler._saveAppStateWithImmediateReturn(oXAppDataObj, fnOnError);
413
- if (oReturn) {
414
- oNavArguments.appStateKey = oReturn.appStateKey;
413
+ oXAppDataObj = oNavHandler._removeMeasureBasedInformation(oXAppDataObj);
414
+ return oNavHandler._fnSaveAppStateAsync(oXAppDataObj, fnOnError).then(function (oSaveAppStateReturn) {
415
+ if (oSaveAppStateReturn) {
416
+ oNavArguments.appStateKey = oSaveAppStateReturn.appStateKey;
415
417
 
416
418
  // Remark:
417
419
  // The Cross App Service takes care of encoding parameter keys and values. Example:
@@ -421,39 +423,64 @@ sap.ui.define(
421
423
  // toExternal sets sap-xapp-state in the URL if appStateKey is provided in oNavArguments
422
424
  // toExternal has issues on sticky apps FIORITECHP1-14400, temp fix using hrefForExternal
423
425
  if (sNavMode == "explace") {
424
- var sNewHrefPromise = oNavHandler.oCrossAppNavService.hrefForExternalAsync(
425
- oNavArguments,
426
- oNavHandler.oComponent
427
- );
428
- sNewHrefPromise
429
- .then(function (sNewHref) {
430
- openWindow(sNewHref);
431
- })
432
- .catch(function (oError) {
433
- Log.error("Error while retireving hrefForExternal : " + oError);
434
- });
426
+ fnNavExplace();
435
427
  } else {
436
- var ptoExt = oNavHandler.oCrossAppNavService.toExternal(oNavArguments, oNavHandler.oComponent);
428
+ var ptoExt = oCrossAppNavService.toExternal(oNavArguments, oNavHandler.oComponent);
437
429
  // TODO: This is just a temporary solution to allow FE V2 to use toExternal promise.
438
430
  if (oNavHandler._navigateCallback) {
439
431
  oNavHandler._navigateCallback(ptoExt);
440
432
  }
441
433
  }
442
434
  } // else : error was already reported
443
- } else if (fnOnError) {
444
- // intent is not supported
445
- var oError = new NavError("NavigationHandler.isIntentSupported.notSupported");
446
- fnOnError(oError);
447
- }
448
- });
435
+ });
436
+ };
437
+ var fnStoreAndNavigate = function (oCrossAppNavService) {
438
+ oNavHandler
439
+ .storeInnerAppStateAsync(oInnerAppData, true)
440
+ .then(function (sAppStateKey) {
441
+ if (sAppStateKey) {
442
+ oNavHandler.replaceHash(sAppStateKey);
443
+ }
444
+ return fnNavigate(oCrossAppNavService);
445
+ })
446
+ .catch(function (oError) {
447
+ if (fnOnError) {
448
+ fnOnError(oError);
449
+ }
450
+ });
451
+ };
452
+ if (sNavMode) {
453
+ oNavArguments.params["sap-ushell-navmode"] = bExPlace ? "explace" : "inplace";
454
+ }
455
+ oNavHandler
456
+ ._getAppNavigationServiceAsync()
457
+ .then(function (oCrossAppNavService) {
458
+ var oSupportedPromise = oCrossAppNavService.isNavigationSupported([oNavArguments], oNavHandler.oComponent);
459
+ oSupportedPromise.done(function (oTargets) {
460
+ if (oTargets[0].supported) {
461
+ if (!bExPlace) {
462
+ fnStoreAndNavigate(oCrossAppNavService);
463
+ } else {
464
+ fnNavigate(oCrossAppNavService);
465
+ }
466
+ } else if (fnOnError) {
467
+ // intent is not supported
468
+ var oError = new NavError("NavigationHandler.isIntentSupported.notSupported");
469
+ fnOnError(oError);
470
+ }
471
+ });
449
472
 
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");
473
+ if (fnOnError) {
474
+ oSupportedPromise.fail(function () {
475
+ // technical error: could not determine if intent is supported
476
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.isIntentSupported.failed");
477
+ fnOnError(oError);
478
+ });
479
+ }
480
+ })
481
+ .catch(function (oError) {
454
482
  fnOnError(oError);
455
483
  });
456
- }
457
484
  },
458
485
 
459
486
  /**
@@ -485,7 +512,7 @@ sap.ui.define(
485
512
  * <li><code>oAppData.tableVariantId</code></li>
486
513
  * <li><code>oAppData.customData</code></li>
487
514
  * </ul>
488
- * which return the inner app data as stored in {@link #.navigate navigate} or {@link #.storeInnerAppState storeInnerAppState}.
515
+ * which return the inner app data as stored in {@link #.navigate navigate} or {@link #.storeInnerAppStateAsync storeInnerAppStateAsync}.
489
516
  * <code>oAppData.oDefaultedSelectionVariant</code> is an empty selection variant and
490
517
  * <code>oAppData.bNavSelVarHasDefaultsOnly</code> is <code>false</code> in this case.<br>
491
518
  * <b>Note:</b> If the navigation type is {@link sap.fe.navigation.NavType.initial} oAppData is an empty object!<br>
@@ -579,49 +606,56 @@ sap.ui.define(
579
606
  // no back navigation
580
607
  var bIsXappStateNavigation = oComponentData["sap-xapp-state"] !== undefined;
581
608
  if (bIsXappStateNavigation) {
609
+ var that = this;
582
610
  // inner app state was not found in the AppHash, but xapp state => try to read the xapp state
583
- var oStartupPromise = this.oCrossAppNavService.getStartupAppState(this.oComponent);
584
-
585
- oStartupPromise.done(function (oAppState) {
586
- // get app state from sap-xapp-state,
587
- // create a copy, not only a reference, because we want to modify the object
588
- var oAppStateData = oAppState.getData();
589
- var oError;
590
- if (oAppStateData) {
591
- try {
592
- oAppStateData = JSON.parse(JSON.stringify(oAppStateData));
593
- } catch (x) {
594
- oError = oNavHandler._createTechnicalError("NavigationHandler.AppStateData.parseError");
595
- oMyDeferred.reject(oError, oStartupParameters, NavType.xAppState);
596
- return oMyDeferred.promise();
597
- }
598
- }
599
-
600
- if (oAppStateData) {
601
- var oSelVar = new SelectionVariant(oAppStateData.selectionVariant);
611
+ this._getAppNavigationServiceAsync()
612
+ .then(function (oCrossAppNavService) {
613
+ var oStartupPromise = oCrossAppNavService.getStartupAppState(that.oComponent);
614
+ oStartupPromise.done(function (oAppState) {
615
+ // get app state from sap-xapp-state,
616
+ // create a copy, not only a reference, because we want to modify the object
617
+ var oAppStateData = oAppState.getData();
618
+ var oError;
619
+ if (oAppStateData) {
620
+ try {
621
+ oAppStateData = JSON.parse(JSON.stringify(oAppStateData));
622
+ } catch (x) {
623
+ oError = oNavHandler._createTechnicalError("NavigationHandler.AppStateData.parseError");
624
+ oMyDeferred.reject(oError, oStartupParameters, NavType.xAppState);
625
+ return oMyDeferred.promise();
626
+ }
627
+ }
602
628
 
603
- var oSelVars = oNavHandler._splitInboundNavigationParameters(
604
- oSelVar,
605
- oStartupParameters,
606
- aDefaultedParameters
607
- );
608
- oAppStateData.selectionVariant = oSelVars.oNavigationSelVar.toJSONString();
609
- oAppStateData.oSelectionVariant = oSelVars.oNavigationSelVar;
610
- oAppStateData.oDefaultedSelectionVariant = oSelVars.oDefaultedSelVar;
611
- oAppStateData.bNavSelVarHasDefaultsOnly = oSelVars.bNavSelVarHasDefaultsOnly;
612
- oMyDeferred.resolve(oAppStateData, oStartupParameters, NavType.xAppState);
613
- } else if (oStartupParameters) {
614
- parseUrlParams(oStartupParameters, aDefaultedParameters, oMyDeferred, NavType.xAppState);
615
- } else {
616
- // sap-xapp-state navigation, but ID has already expired, but URL parameters available
617
- oError = oNavHandler._createTechnicalError("NavigationHandler.getDataFromAppState.failed");
618
- oMyDeferred.reject(oError, oStartupParameters || {}, NavType.xAppState);
619
- }
620
- });
621
- oStartupPromise.fail(function () {
622
- var oError = oNavHandler._createTechnicalError("NavigationHandler.getStartupState.failed");
623
- oMyDeferred.reject(oError, {}, NavType.xAppState);
624
- });
629
+ if (oAppStateData) {
630
+ var oSelVar = new SelectionVariant(oAppStateData.selectionVariant);
631
+
632
+ var oSelVars = oNavHandler._splitInboundNavigationParameters(
633
+ oSelVar,
634
+ oStartupParameters,
635
+ aDefaultedParameters
636
+ );
637
+ oAppStateData.selectionVariant = oSelVars.oNavigationSelVar.toJSONString();
638
+ oAppStateData.oSelectionVariant = oSelVars.oNavigationSelVar;
639
+ oAppStateData.oDefaultedSelectionVariant = oSelVars.oDefaultedSelVar;
640
+ oAppStateData.bNavSelVarHasDefaultsOnly = oSelVars.bNavSelVarHasDefaultsOnly;
641
+ oMyDeferred.resolve(oAppStateData, oStartupParameters, NavType.xAppState);
642
+ } else if (oStartupParameters) {
643
+ parseUrlParams(oStartupParameters, aDefaultedParameters, oMyDeferred, NavType.xAppState);
644
+ } else {
645
+ // sap-xapp-state navigation, but ID has already expired, but URL parameters available
646
+ oError = oNavHandler._createTechnicalError("NavigationHandler.getDataFromAppState.failed");
647
+ oMyDeferred.reject(oError, oStartupParameters || {}, NavType.xAppState);
648
+ }
649
+ });
650
+ oStartupPromise.fail(function () {
651
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.getStartupState.failed");
652
+ oMyDeferred.reject(oError, {}, NavType.xAppState);
653
+ });
654
+ })
655
+ .catch(function () {
656
+ var oError = oNavHandler._createTechnicalError("NavigationHandler._getAppNavigationServiceAsync.failed");
657
+ oMyDeferred.reject(oError, {}, NavType.xAppState);
658
+ });
625
659
  } else if (oStartupParameters) {
626
660
  // no sap-xapp-state
627
661
  parseUrlParams(oStartupParameters, aDefaultedParameters, oMyDeferred, NavType.URLParams);
@@ -894,6 +928,126 @@ sap.ui.define(
894
928
  oHashChanger.replaceHash(sAppHashNew);
895
929
  },
896
930
 
931
+ /**
932
+ * Changes the URL according to the current app state and stores the app state for later retrieval.
933
+ *
934
+ * @param {object} mInnerAppData Object containing the current state of the app
935
+ * @param {string} mInnerAppData.selectionVariant Stringified JSON object as returned, for example, from getDataSuiteFormat() of the
936
+ * SmartFilterBar control
937
+ * @param {string} [mInnerAppData.tableVariantId] ID of the SmartTable variant
938
+ * @param {object} [mInnerAppData.customData] Object that can be used to store additional app-specific data
939
+ * @param {object} [mInnerAppData.presentationVariant] Object containing the current ui state of the app
940
+ * @param {object} [mInnerAppData.valueTexts] Object containing value descriptions
941
+ * @param {object} [mInnerAppData.semanticDates] Object containing semanticDates filter information
942
+ * @param {boolean} [bImmediateHashReplace=true] If set to false, the inner app hash will not be replaced until storing is successful; do not
943
+ * set to false if you cannot react to the resolution of the Promise, for example, when calling the beforeLinkPressed event
944
+ * @param {boolean} [bSkipHashReplace=false] If set to true, the inner app hash will not be replaced in the storeInnerAppStateAsync. Also the bImmediateHashReplace
945
+ * will be ignored.
946
+ * @returns {object} A Promise object to monitor when all the actions of the function have been executed; if the execution is successful, the
947
+ * app state key is returned; if an error occurs, an object of type {@link sap.fe.navigation.NavError} is
948
+ * returned
949
+ * @public
950
+ * @example <code>
951
+ * sap.ui.define(["sap/fe/navigation/NavigationHandler"], function (NavigationHandler) {
952
+ * var oNavigationHandler = new NavigationHandler(oController);
953
+ * var mInnerAppData = {
954
+ * selectionVariant : oSmartFilterBar.getDataSuiteFormat(),
955
+ * tableVariantId : oSmartTable.getCurrentVariantId(),
956
+ * customData : oMyCustomData
957
+ * };
958
+ *
959
+ * var oStoreInnerAppStatePromise = oNavigationHandler.storeInnerAppStateAsync(mInnerAppData);
960
+ *
961
+ * oStoreInnerAppStatePromise.done(function(sAppStateKey){
962
+ * //your inner app state is saved now, sAppStateKey was added to URL
963
+ * //perform actions that must run after save
964
+ * });
965
+ *
966
+ * oStoreInnerAppStatePromise.fail(function(oError){
967
+ * //some error handling
968
+ * });
969
+ * });
970
+ * </code>
971
+ */
972
+ storeInnerAppStateAsync: function (mInnerAppData, bImmediateHashReplace, bSkipHashReplace) {
973
+ if (typeof bImmediateHashReplace !== "boolean") {
974
+ bImmediateHashReplace = true; // default
975
+ }
976
+ var oNavHandler = this;
977
+ var oMyDeferred = jQuery.Deferred();
978
+
979
+ var fnReplaceHash = function (sAppStateKey) {
980
+ var oHashChanger = oNavHandler.oRouter.oHashChanger ? oNavHandler.oRouter.oHashChanger : HashChanger.getInstance();
981
+ var sAppHashOld = oHashChanger.getHash();
982
+ /*
983
+ * use .getHash() here instead of .getAppHash() to also be able dealing with environments where only SAPUI5 is loaded and the UShell
984
+ * is not initialized properly.
985
+ */
986
+ var sAppHashNew = oNavHandler._replaceInnerAppStateKey(sAppHashOld, sAppStateKey);
987
+ oHashChanger.replaceHash(sAppHashNew);
988
+ };
989
+
990
+ // in case mInnerAppState is empty, do not overwrite the last saved state
991
+ if (isEmptyObject(mInnerAppData)) {
992
+ oMyDeferred.resolve("");
993
+ return oMyDeferred.promise();
994
+ }
995
+
996
+ // check if we already saved the same data
997
+ var sAppStateKeyCached = this._oLastSavedInnerAppData.sAppStateKey;
998
+
999
+ var bInnerAppDataEqual = JSON.stringify(mInnerAppData) === JSON.stringify(this._oLastSavedInnerAppData.oAppData);
1000
+ if (bInnerAppDataEqual && sAppStateKeyCached) {
1001
+ // passed inner app state found in cache
1002
+ this._oLastSavedInnerAppData.iCacheHit++;
1003
+
1004
+ // replace inner app hash with cached appStateKey in url (just in case the app has changed the hash in meantime)
1005
+ fnReplaceHash(sAppStateKeyCached);
1006
+ oMyDeferred.resolve(sAppStateKeyCached);
1007
+ return oMyDeferred.promise();
1008
+ }
1009
+
1010
+ // passed inner app state not found in cache
1011
+ this._oLastSavedInnerAppData.iCacheMiss++;
1012
+
1013
+ var fnOnAfterSave = function (sAppStateKey) {
1014
+ // replace inner app hash with new appStateKey in url
1015
+ if (!bSkipHashReplace && !bImmediateHashReplace) {
1016
+ fnReplaceHash(sAppStateKey);
1017
+ }
1018
+
1019
+ // remember last saved state
1020
+ oNavHandler._oLastSavedInnerAppData.oAppData = mInnerAppData;
1021
+ oNavHandler._oLastSavedInnerAppData.sAppStateKey = sAppStateKey;
1022
+ oMyDeferred.resolve(sAppStateKey);
1023
+ };
1024
+
1025
+ var fnOnError = function (oError) {
1026
+ oMyDeferred.reject(oError);
1027
+ };
1028
+
1029
+ this._saveAppStateAsync(mInnerAppData, fnOnAfterSave, fnOnError)
1030
+ .then(function (sAppStateKey) {
1031
+ /* Note that _sapAppState may return 'undefined' in case that the parsing has failed. In this case, we should not trigger the replacement
1032
+ * of the App Hash with the generated key, as the container was not written before. Note as well that the error handling has already
1033
+ * happened before by making the oMyDeferred promise fail (see fnOnError above).
1034
+ */
1035
+ if (sAppStateKey !== undefined) {
1036
+ // replace inner app hash with new appStateKey in url
1037
+ // note: we do not wait for the save to be completed: this asynchronously behaviour is necessary if
1038
+ // this method is called e.g. in a onLinkPressed event with no possibility to wait for the promise resolution
1039
+ if (!bSkipHashReplace && bImmediateHashReplace) {
1040
+ fnReplaceHash(sAppStateKey);
1041
+ }
1042
+ }
1043
+ })
1044
+ .catch(function () {
1045
+ Log.error("NavigationHandler._saveAppStateAsync failed");
1046
+ });
1047
+
1048
+ return oMyDeferred.promise();
1049
+ },
1050
+
897
1051
  /**
898
1052
  * Changes the URL according to the current app state and stores the app state for later retrieval.
899
1053
  *
@@ -932,8 +1086,15 @@ sap.ui.define(
932
1086
  * });
933
1087
  * });
934
1088
  * </code>
1089
+ * @deprecated as of version 1.104. Use the {@link sap.fe.navigation.NavigationHandler.storeInnerAppStateAsync} instead.
935
1090
  */
1091
+
936
1092
  storeInnerAppState: function (mInnerAppData, bImmediateHashReplace) {
1093
+ Log.error(
1094
+ "Deprecated API call of 'sap.fe.navigation.NavigationHandler.storeInnerAppState'. Please use 'storeInnerAppStateAsync' instead",
1095
+ null,
1096
+ "sap.fe.navigation.NavigationHandler"
1097
+ );
937
1098
  if (typeof bImmediateHashReplace !== "boolean") {
938
1099
  bImmediateHashReplace = true; // default
939
1100
  }
@@ -1052,8 +1213,14 @@ sap.ui.define(
1052
1213
  * });
1053
1214
  * </code>
1054
1215
  * @public
1216
+ * @deprecated as of version 1.104. Use the {@link sap.fe.navigation.NavigationHandler.storeInnerAppStateAsync} instead.
1055
1217
  */
1056
1218
  storeInnerAppStateWithImmediateReturn: function (mInnerAppData, bImmediateHashReplace) {
1219
+ Log.error(
1220
+ "Deprecated API call of 'sap.fe.navigation.NavigationHandler.storeInnerAppStateWithImmediateReturn'. Please use 'storeInnerAppStateAsync' instead",
1221
+ null,
1222
+ "sap.fe.navigation.NavigationHandler"
1223
+ );
1057
1224
  if (typeof bImmediateHashReplace !== "boolean") {
1058
1225
  bImmediateHashReplace = false; // default
1059
1226
  }
@@ -1260,11 +1427,11 @@ sap.ui.define(
1260
1427
 
1261
1428
  oXAppDataObj = oNavHandler._removeMeasureBasedInformation(oXAppDataObj);
1262
1429
 
1263
- oNavHandler._saveAppState(oXAppDataObj, fnOnContainerSave, fnOnError);
1430
+ oNavHandler._saveAppStateAsync(oXAppDataObj, fnOnContainerSave, fnOnError);
1264
1431
  };
1265
1432
 
1266
1433
  if (mInnerAppData) {
1267
- var oStoreInnerAppStatePromise = this.storeInnerAppState(mInnerAppData, true);
1434
+ var oStoreInnerAppStatePromise = this.storeInnerAppStateAsync(mInnerAppData, true);
1268
1435
 
1269
1436
  // if the inner app state was successfully stored, store also the xapp-state
1270
1437
  oStoreInnerAppStatePromise.done(function () {
@@ -1477,32 +1644,56 @@ sap.ui.define(
1477
1644
 
1478
1645
  return vConvertedSelectionVariant;
1479
1646
  },
1647
+ _fnHandleAppStatePromise: function (oReturn, fnOnAfterSave, fnOnError) {
1648
+ oReturn.promise.done(function () {
1649
+ if (fnOnAfterSave) {
1650
+ fnOnAfterSave(oReturn.appStateKey);
1651
+ }
1652
+ });
1480
1653
 
1654
+ if (fnOnError) {
1655
+ var oNavHandler = this;
1656
+ oReturn.promise.fail(function () {
1657
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.AppStateSave.failed");
1658
+ fnOnError(oError);
1659
+ });
1660
+ }
1661
+ },
1662
+ _saveAppStateAsync: function (oAppData, fnOnAfterSave, fnOnError) {
1663
+ var oNavHandler = this;
1664
+ return this._fnSaveAppStateAsync(oAppData, fnOnError).then(function (oReturn) {
1665
+ if (oReturn) {
1666
+ oNavHandler._fnHandleAppStatePromise(oReturn, fnOnAfterSave, fnOnError);
1667
+ return oReturn.appStateKey;
1668
+ }
1669
+
1670
+ return undefined;
1671
+ });
1672
+ },
1481
1673
  _saveAppState: function (oAppData, fnOnAfterSave, fnOnError) {
1482
1674
  var oReturn = this._saveAppStateWithImmediateReturn(oAppData, fnOnError);
1483
1675
  if (oReturn) {
1484
- oReturn.promise.done(function () {
1485
- if (fnOnAfterSave) {
1486
- fnOnAfterSave(oReturn.appStateKey);
1487
- }
1488
- });
1489
-
1490
- if (fnOnError) {
1491
- var oNavHandler = this;
1492
- oReturn.promise.fail(function () {
1493
- var oError = oNavHandler._createTechnicalError("NavigationHandler.AppStateSave.failed");
1494
- fnOnError(oError);
1495
- });
1496
- }
1676
+ this._fnHandleAppStatePromise(oReturn, fnOnAfterSave, fnOnError);
1497
1677
  return oReturn.appStateKey;
1498
1678
  }
1499
1679
 
1500
1680
  return undefined;
1501
1681
  },
1502
-
1503
- _saveAppStateWithImmediateReturn: function (oAppData, fnOnError) {
1504
- var oAppState = this.oCrossAppNavService.createEmptyAppState(this.oComponent);
1682
+ _fnSaveAppStateWithImmediateReturn: function (oAppData, oAppState, fnOnError) {
1505
1683
  var sAppStateKey = oAppState.getKey();
1684
+ var oAppDataForSave = this._fetchAppDataForSave(oAppData, fnOnError);
1685
+ if (!oAppDataForSave) {
1686
+ return undefined;
1687
+ }
1688
+ oAppState.setData(oAppDataForSave);
1689
+ var oSavePromise = oAppState.save();
1690
+
1691
+ return {
1692
+ appStateKey: sAppStateKey,
1693
+ promise: oSavePromise.promise()
1694
+ };
1695
+ },
1696
+ _fetchAppDataForSave: function (oAppData, fnOnError) {
1506
1697
  var oAppDataForSave = {};
1507
1698
 
1508
1699
  if (oAppData.hasOwnProperty("selectionVariant")) {
@@ -1557,80 +1748,103 @@ sap.ui.define(
1557
1748
  oAppDataForSave = merge(oAppDataClone, oAppDataForSave);
1558
1749
  }
1559
1750
  oAppDataForSave = this._checkIsPotentiallySensitive(oAppDataForSave);
1560
- oAppState.setData(oAppDataForSave);
1561
- var oSavePromise = oAppState.save();
1562
-
1563
- return {
1564
- appStateKey: sAppStateKey,
1565
- promise: oSavePromise.promise()
1566
- };
1751
+ return oAppDataForSave;
1752
+ },
1753
+ _fnSaveAppStateAsync: function (oAppData, fnOnError) {
1754
+ var oNavHandler = this;
1755
+ return this._getAppNavigationServiceAsync()
1756
+ .then(function (oCrossAppNavService) {
1757
+ return oCrossAppNavService.createEmptyAppStateAsync(oNavHandler.oComponent);
1758
+ })
1759
+ .then(function (oAppState) {
1760
+ return oNavHandler._fnSaveAppStateWithImmediateReturn(oAppData, oAppState, fnOnError);
1761
+ })
1762
+ .catch(function (oError) {
1763
+ if (fnOnError) {
1764
+ fnOnError(oError);
1765
+ }
1766
+ });
1767
+ },
1768
+ _saveAppStateWithImmediateReturn: function (oAppData, fnOnError) {
1769
+ var oAppState = this._getAppNavigationService().createEmptyAppState(this.oComponent);
1770
+ return this._fnSaveAppStateWithImmediateReturn(oAppData, oAppState, fnOnError);
1567
1771
  },
1568
1772
 
1569
1773
  _loadAppState: function (sAppStateKey, oDeferred) {
1570
- var oAppStatePromise = this.oCrossAppNavService.getAppState(this.oComponent, sAppStateKey);
1571
1774
  var oNavHandler = this;
1775
+ this._getAppNavigationServiceAsync()
1776
+ .then(function (oCrossAppNavService) {
1777
+ var oAppStatePromise = oCrossAppNavService.getAppState(oNavHandler.oComponent, sAppStateKey);
1778
+ oAppStatePromise.done(function (oAppState) {
1779
+ var oAppData = {};
1780
+ var oAppDataLoaded = oAppState.getData();
1781
+
1782
+ if (typeof oAppDataLoaded === "undefined") {
1783
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.getDataFromAppState.failed");
1784
+ oDeferred.reject(oError, {}, NavType.iAppState);
1785
+ } else if (oNavHandler._sMode === Mode.ODataV2) {
1786
+ oAppData = {
1787
+ selectionVariant: "{}",
1788
+ oSelectionVariant: new SelectionVariant(),
1789
+ oDefaultedSelectionVariant: new SelectionVariant(),
1790
+ bNavSelVarHasDefaultsOnly: false,
1791
+ tableVariantId: "",
1792
+ customData: {},
1793
+ appStateKey: sAppStateKey,
1794
+ presentationVariant: {},
1795
+ valueTexts: {},
1796
+ semanticDates: {}
1797
+ };
1798
+ if (oAppDataLoaded.selectionVariant) {
1799
+ /*
1800
+ * In case that we get an object from the stored AppData (=persistency), we need to stringify the JSON object.
1801
+ */
1802
+ oAppData.selectionVariant = oNavHandler._ensureSelectionVariantFormatString(
1803
+ oAppDataLoaded.selectionVariant
1804
+ );
1805
+ oAppData.oSelectionVariant = new SelectionVariant(oAppData.selectionVariant);
1806
+ }
1807
+ if (oAppDataLoaded.tableVariantId) {
1808
+ oAppData.tableVariantId = oAppDataLoaded.tableVariantId;
1809
+ }
1810
+ if (oAppDataLoaded.customData) {
1811
+ oAppData.customData = oAppDataLoaded.customData;
1812
+ }
1813
+ if (oAppDataLoaded.presentationVariant) {
1814
+ oAppData.presentationVariant = oAppDataLoaded.presentationVariant;
1815
+ }
1816
+ if (oAppDataLoaded.valueTexts) {
1817
+ oAppData.valueTexts = oAppDataLoaded.valueTexts;
1818
+ }
1819
+ if (oAppDataLoaded.semanticDates) {
1820
+ oAppData.semanticDates = oAppDataLoaded.semanticDates;
1821
+ }
1822
+ } else {
1823
+ oAppData = merge(oAppData, oAppDataLoaded);
1824
+ if (oAppDataLoaded.selectionVariant) {
1825
+ /*
1826
+ * In case that we get an object from the stored AppData (=persistency), we need to stringify the JSON object.
1827
+ */
1828
+ oAppData.selectionVariant = oNavHandler._ensureSelectionVariantFormatString(
1829
+ oAppDataLoaded.selectionVariant
1830
+ );
1831
+ oAppData.oSelectionVariant = new SelectionVariant(oAppData.selectionVariant);
1832
+ }
1833
+ }
1572
1834
 
1573
- oAppStatePromise.done(function (oAppState) {
1574
- var oAppData = {};
1575
- var oAppDataLoaded = oAppState.getData();
1576
-
1577
- if (typeof oAppDataLoaded === "undefined") {
1578
- var oError = oNavHandler._createTechnicalError("NavigationHandler.getDataFromAppState.failed");
1835
+ // resolve is called on passed Deferred object to trigger a call of the done method, if implemented
1836
+ // the done method will receive the loaded appState and the navigation type as parameters
1837
+ oDeferred.resolve(oAppData, {}, NavType.iAppState);
1838
+ });
1839
+ oAppStatePromise.fail(function () {
1840
+ var oError = oNavHandler._createTechnicalError("NavigationHandler.getAppState.failed");
1841
+ oDeferred.reject(oError, {}, NavType.iAppState);
1842
+ });
1843
+ })
1844
+ .catch(function () {
1845
+ var oError = oNavHandler._createTechnicalError("NavigationHandler._getAppNavigationServiceAsync.failed");
1579
1846
  oDeferred.reject(oError, {}, NavType.iAppState);
1580
- } else if (oNavHandler._sMode === Mode.ODataV2) {
1581
- oAppData = {
1582
- selectionVariant: "{}",
1583
- oSelectionVariant: new SelectionVariant(),
1584
- oDefaultedSelectionVariant: new SelectionVariant(),
1585
- bNavSelVarHasDefaultsOnly: false,
1586
- tableVariantId: "",
1587
- customData: {},
1588
- appStateKey: sAppStateKey,
1589
- presentationVariant: {},
1590
- valueTexts: {},
1591
- semanticDates: {}
1592
- };
1593
- if (oAppDataLoaded.selectionVariant) {
1594
- /*
1595
- * In case that we get an object from the stored AppData (=persistency), we need to stringify the JSON object.
1596
- */
1597
- oAppData.selectionVariant = oNavHandler._ensureSelectionVariantFormatString(oAppDataLoaded.selectionVariant);
1598
- oAppData.oSelectionVariant = new SelectionVariant(oAppData.selectionVariant);
1599
- }
1600
- if (oAppDataLoaded.tableVariantId) {
1601
- oAppData.tableVariantId = oAppDataLoaded.tableVariantId;
1602
- }
1603
- if (oAppDataLoaded.customData) {
1604
- oAppData.customData = oAppDataLoaded.customData;
1605
- }
1606
- if (oAppDataLoaded.presentationVariant) {
1607
- oAppData.presentationVariant = oAppDataLoaded.presentationVariant;
1608
- }
1609
- if (oAppDataLoaded.valueTexts) {
1610
- oAppData.valueTexts = oAppDataLoaded.valueTexts;
1611
- }
1612
- if (oAppDataLoaded.semanticDates) {
1613
- oAppData.semanticDates = oAppDataLoaded.semanticDates;
1614
- }
1615
- } else {
1616
- oAppData = merge(oAppData, oAppDataLoaded);
1617
- if (oAppDataLoaded.selectionVariant) {
1618
- /*
1619
- * In case that we get an object from the stored AppData (=persistency), we need to stringify the JSON object.
1620
- */
1621
- oAppData.selectionVariant = oNavHandler._ensureSelectionVariantFormatString(oAppDataLoaded.selectionVariant);
1622
- oAppData.oSelectionVariant = new SelectionVariant(oAppData.selectionVariant);
1623
- }
1624
- }
1625
-
1626
- // resolve is called on passed Deferred object to trigger a call of the done method, if implemented
1627
- // the done method will receive the loaded appState and the navigation type as parameters
1628
- oDeferred.resolve(oAppData, {}, NavType.iAppState);
1629
- });
1630
- oAppStatePromise.fail(function () {
1631
- var oError = oNavHandler._createTechnicalError("NavigationHandler.getAppState.failed");
1632
- oDeferred.reject(oError, {}, NavType.iAppState);
1633
- });
1847
+ });
1634
1848
  },
1635
1849
 
1636
1850
  /**
@@ -19,7 +19,7 @@ sap.ui.define(
19
19
  * @class
20
20
  * @public
21
21
  * @since 1.83.0
22
- * @alias sap.fe.navigation.PresentationVariant
22
+ * @name sap.fe.navigation.PresentationVariant
23
23
  * @param {string|object} [vPresentationVariant] If of type <code>string</code>, the selection variant is JSON-formatted;
24
24
  * if of type <code>object</code>, the object represents a selection variant
25
25
  * @throws An instance of {@link sap.fe.navigation.NavError} in case of input errors. Valid error codes are:
@@ -36,7 +36,7 @@ sap.ui.define(
36
36
  */
37
37
  return BaseObject.extend(
38
38
  "sap.fe.navigation.PresentationVariant",
39
- /** @lends sap.fe.navigation.PresentationVariant */ {
39
+ /** @lends sap.fe.navigation.PresentationVariant.prototype */ {
40
40
  constructor: function (vPresentationVariant) {
41
41
  this._sId = "";
42
42
 
@@ -19,7 +19,7 @@ sap.ui.define(
19
19
  * @class
20
20
  * @public
21
21
  * @since 1.83.0
22
- * @alias sap.fe.navigation.SelectionVariant
22
+ * @name sap.fe.navigation.SelectionVariant
23
23
  * @param {string|object} [vSelectionVariant] If of type <code>string</code>, the selection variant is JSON-formatted;
24
24
  * if of type <code>object</code>, the object represents a selection variant
25
25
  * @throws An instance of {@link sap.fe.navigation.NavError} in case of input errors. Valid error codes are:
@@ -36,7 +36,7 @@ sap.ui.define(
36
36
  */
37
37
  return BaseObject.extend(
38
38
  "sap.fe.navigation.SelectionVariant",
39
- /** @lends sap.fe.navigation.SelectionVariant */
39
+ /** @lends sap.fe.navigation.SelectionVariant.prototype */
40
40
  {
41
41
  _rVALIDATE_SIGN: new RegExp("[E|I]"),
42
42
  _rVALIDATE_OPTION: new RegExp("EQ|NE|LE|GE|LT|GT|BT|CP"),
@@ -307,8 +307,8 @@ sap.ui.define(
307
307
  * (ABAP-styled pattern matching with the asterisk as wildcard)
308
308
  * @param {string} sLow The single value or the lower boundary of the interval; the <code>null</code> value is not allowed
309
309
  * @param {string} [sHigh] Set only if sOption is <b>BT</b>: the upper boundary of the interval;
310
- * @param {string} [sText] Text representing the SelectOption. This is an optional parameter, consumption of this parameter is
311
- * completely decided by the consumer. For an example in most Fiori applications fetch the Text based on the ID and doesn't
310
+ * @param {string} [sText] Text representing the SelectOption. This is an optional parameter, consumption of this parameter is
311
+ * completely decided by the consumer. For an example in most Fiori applications fetch the Text based on the ID and doesn't
312
312
  * consider this text property
313
313
  * must be <code>undefined</code> or <code>null</code> in all other cases
314
314
  * @returns {object} This instance to allow method chaining.
@@ -324,7 +324,7 @@ sap.ui.define(
324
324
  * <tr><td>SelectionVariant.PARAMETER_SELOPT_COLLISION</td><td>Indicates that another parameter with the same name as the property name already exists</td></tr>
325
325
  * </table>
326
326
  */
327
- addSelectOption: function(sPropertyName, sSign, sOption, sLow, sHigh, sText) {
327
+ addSelectOption: function (sPropertyName, sSign, sOption, sLow, sHigh, sText) {
328
328
  /* {string} sLow The single value or the lower boundary of the interval; the <code>null</code> value is not allowed
329
329
  * (see specification "Selection Variants for UI Navigation in Fiori", section 2.4.2.1)
330
330
  */
@@ -378,7 +378,7 @@ sap.ui.define(
378
378
  };
379
379
 
380
380
  if (sText) {
381
- // Add Text property only in case it is passed by the consumer of the API.
381
+ // Add Text property only in case it is passed by the consumer of the API.
382
382
  // Otherwise keep the structure as is.
383
383
  oEntry.Text = sText;
384
384
  }
@@ -730,6 +730,9 @@ sap.ui.define(
730
730
  },
731
731
 
732
732
  _parseFromObject: function (oInput) {
733
+ if (!oInput) {
734
+ oInput = {};
735
+ }
733
736
  if (oInput.SelectionVariantID === undefined) {
734
737
  // Do not throw an error, but only write a warning into the log.
735
738
  // The SelectionVariantID is mandatory according to the specification document version 1.0,
@@ -26,7 +26,7 @@ sap.ui.define(
26
26
  var thisLib = sap.ui.getCore().initLibrary({
27
27
  name: "sap.fe.navigation",
28
28
  // eslint-disable-next-line no-template-curly-in-string
29
- version: "1.103.0",
29
+ version: "1.106.0",
30
30
  dependencies: ["sap.ui.core"],
31
31
  types: ["sap.fe.navigation.NavType", "sap.fe.navigation.ParamHandlingMode", "sap.fe.navigation.SuppressionBehavior"],
32
32
  interfaces: [],