@openui5/sap.ui.documentation 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 (75) hide show
  1. package/REUSE.toml +40 -16
  2. package/THIRDPARTY.txt +28 -7
  3. package/package.json +7 -7
  4. package/src/sap/ui/documentation/.library +1 -1
  5. package/src/sap/ui/documentation/LightTable.js +20 -46
  6. package/src/sap/ui/documentation/Row.js +146 -7
  7. package/src/sap/ui/documentation/library.js +2 -2
  8. package/src/sap/ui/documentation/messagebundle.properties +2 -2
  9. package/src/sap/ui/documentation/messagebundle_ar.properties +2 -2
  10. package/src/sap/ui/documentation/messagebundle_bg.properties +2 -2
  11. package/src/sap/ui/documentation/messagebundle_ca.properties +2 -2
  12. package/src/sap/ui/documentation/messagebundle_cnr.properties +2 -2
  13. package/src/sap/ui/documentation/messagebundle_cs.properties +2 -2
  14. package/src/sap/ui/documentation/messagebundle_cy.properties +2 -2
  15. package/src/sap/ui/documentation/messagebundle_da.properties +2 -2
  16. package/src/sap/ui/documentation/messagebundle_de.properties +3 -3
  17. package/src/sap/ui/documentation/messagebundle_el.properties +2 -2
  18. package/src/sap/ui/documentation/messagebundle_en_GB.properties +2 -2
  19. package/src/sap/ui/documentation/messagebundle_en_US_sappsd.properties +2 -2
  20. package/src/sap/ui/documentation/messagebundle_en_US_saprigi.properties +2 -2
  21. package/src/sap/ui/documentation/messagebundle_en_US_saptrc.properties +2 -2
  22. package/src/sap/ui/documentation/messagebundle_es.properties +2 -2
  23. package/src/sap/ui/documentation/messagebundle_es_MX.properties +2 -2
  24. package/src/sap/ui/documentation/messagebundle_et.properties +2 -2
  25. package/src/sap/ui/documentation/messagebundle_fi.properties +2 -2
  26. package/src/sap/ui/documentation/messagebundle_fr.properties +2 -2
  27. package/src/sap/ui/documentation/messagebundle_fr_CA.properties +2 -2
  28. package/src/sap/ui/documentation/messagebundle_hi.properties +2 -2
  29. package/src/sap/ui/documentation/messagebundle_hr.properties +2 -2
  30. package/src/sap/ui/documentation/messagebundle_hu.properties +2 -2
  31. package/src/sap/ui/documentation/messagebundle_id.properties +2 -2
  32. package/src/sap/ui/documentation/messagebundle_it.properties +5 -5
  33. package/src/sap/ui/documentation/messagebundle_iw.properties +2 -2
  34. package/src/sap/ui/documentation/messagebundle_ja.properties +2 -2
  35. package/src/sap/ui/documentation/messagebundle_kk.properties +2 -2
  36. package/src/sap/ui/documentation/messagebundle_ko.properties +2 -2
  37. package/src/sap/ui/documentation/messagebundle_lt.properties +2 -2
  38. package/src/sap/ui/documentation/messagebundle_lv.properties +2 -2
  39. package/src/sap/ui/documentation/messagebundle_mk.properties +2 -2
  40. package/src/sap/ui/documentation/messagebundle_ms.properties +2 -2
  41. package/src/sap/ui/documentation/messagebundle_nl.properties +2 -2
  42. package/src/sap/ui/documentation/messagebundle_no.properties +2 -2
  43. package/src/sap/ui/documentation/messagebundle_pl.properties +2 -2
  44. package/src/sap/ui/documentation/messagebundle_pt.properties +2 -2
  45. package/src/sap/ui/documentation/messagebundle_pt_PT.properties +2 -2
  46. package/src/sap/ui/documentation/messagebundle_ro.properties +2 -2
  47. package/src/sap/ui/documentation/messagebundle_ru.properties +2 -2
  48. package/src/sap/ui/documentation/messagebundle_sh.properties +2 -2
  49. package/src/sap/ui/documentation/messagebundle_sk.properties +2 -2
  50. package/src/sap/ui/documentation/messagebundle_sl.properties +2 -2
  51. package/src/sap/ui/documentation/messagebundle_sr.properties +2 -2
  52. package/src/sap/ui/documentation/messagebundle_sv.properties +2 -2
  53. package/src/sap/ui/documentation/messagebundle_th.properties +2 -2
  54. package/src/sap/ui/documentation/messagebundle_tr.properties +2 -2
  55. package/src/sap/ui/documentation/messagebundle_uk.properties +2 -2
  56. package/src/sap/ui/documentation/messagebundle_vi.properties +2 -2
  57. package/src/sap/ui/documentation/messagebundle_zh_CN.properties +2 -2
  58. package/src/sap/ui/documentation/messagebundle_zh_TW.properties +2 -2
  59. package/src/sap/ui/documentation/sdk/controller/App.controller.js +1 -1
  60. package/src/sap/ui/documentation/sdk/controller/Code.controller.js +2 -0
  61. package/src/sap/ui/documentation/sdk/controller/ErrorHandler.js +1 -0
  62. package/src/sap/ui/documentation/sdk/controller/Sample.controller.js +18 -7
  63. package/src/sap/ui/documentation/sdk/controller/SubApiDetail.controller.js +487 -17
  64. package/src/sap/ui/documentation/sdk/controller/util/ConfigUtil.js +1 -0
  65. package/src/sap/ui/documentation/sdk/controller/util/CookiesConsentManager.js +1 -0
  66. package/src/sap/ui/documentation/sdk/controller/util/UsageTracker.js +7 -2
  67. package/src/sap/ui/documentation/sdk/cookieSettingsDialog/controller/CookieSettingsDialog.controller.js +1 -0
  68. package/src/sap/ui/documentation/sdk/thirdparty/highlight.js/highlight.js +3 -3
  69. package/src/sap/ui/documentation/sdk/util/DocumentationRouter.js +5 -0
  70. package/src/sap/ui/documentation/sdk/view/FooterMaster.fragment.xml +1 -1
  71. package/src/sap/ui/documentation/sdk/view/SubApiDetail.view.xml +10 -24
  72. package/src/sap/ui/documentation/themes/base/Documentation.less +4 -4
  73. package/src/sap/ui/documentation/themes/base/LightTable.less +29 -0
  74. package/src/sap/ui/documentation/themes/sap_belize_base/Documentation.less +4 -4
  75. package/src/sap/ui/documentation/themes/sap_horizon_dark/Documentation.less +1 -1
@@ -1477,7 +1477,7 @@ sap.ui.define([
1477
1477
  // Handle the case when the user deletes the query and the search picker is open
1478
1478
  // Only on desktop, because on mobile we don't want to close the picker
1479
1479
  if (!sQuery && Device.system.desktop) {
1480
- if (this.oPicker.isOpen()) {
1480
+ if (this.oPicker && this.oPicker.isOpen()) {
1481
1481
  this.oPicker.close();
1482
1482
  }
1483
1483
 
@@ -35,6 +35,7 @@ sap.ui.define(
35
35
 
36
36
  return SampleController.extend("sap.ui.documentation.sdk.controller.Code", {
37
37
  constructor: function () {
38
+ SampleController.apply(this, arguments);
38
39
  this.onFileEditorFileChangeDebounced = _debounce(this.onFileEditorFileChangeDebounced, 500);
39
40
  },
40
41
 
@@ -54,6 +55,7 @@ sap.ui.define(
54
55
  },
55
56
 
56
57
  onExit: function () {
58
+ SampleController.prototype.onExit.call(this);
57
59
  this._deregisterResize();
58
60
  },
59
61
 
@@ -20,6 +20,7 @@ sap.ui.define([
20
20
  * @alias sap.ui.documentation.sdk.controller.ErrorHandler
21
21
  */
22
22
  constructor : function (oComponent) {
23
+ UI5Object.call(this);
23
24
  this._oComponent = oComponent;
24
25
  this._oModel = oComponent.getModel();
25
26
  this._bMessageOpen = false;
@@ -97,6 +97,8 @@ sap.ui.define([
97
97
  this.bus = EventBus.getInstance();
98
98
  this.setDefaultSampleTheme();
99
99
 
100
+ this._fnOnMessage = this.onMessage.bind(this);
101
+
100
102
  this.getOwnerComponent()._sSampleIframeOrigin = ResourcesUtil.getConfig() !== "." ? ResourcesUtil.getResourceOrigin() : window.origin;
101
103
  },
102
104
 
@@ -407,10 +409,13 @@ sap.ui.define([
407
409
  });
408
410
 
409
411
  var fnLoadSettings = function(eMessage) {
412
+ if (!this._isMessageFromSampleIframe(eMessage)) {
413
+ return;
414
+ }
410
415
  fnCallback(eMessage);
411
416
  window.removeEventListener("message", fnLoadSettings);
412
417
  resolve();
413
- };
418
+ }.bind(this);
414
419
 
415
420
  window.addEventListener("message", fnLoadSettings);
416
421
 
@@ -647,7 +652,7 @@ sap.ui.define([
647
652
  * @private
648
653
  */
649
654
  _onBeforeIframeRendering: function() {
650
- window.removeEventListener("message", this.onMessage.bind(this));
655
+ window.removeEventListener("message", this._fnOnMessage);
651
656
  },
652
657
 
653
658
  /**
@@ -663,7 +668,7 @@ sap.ui.define([
663
668
  this.fResolve({});
664
669
  }.bind(this), CONSTANTS.EXTERNAL_SAMPLE_RENDERING_DELAY);
665
670
  } else {
666
- window.addEventListener("message", this.onMessage.bind(this));
671
+ window.addEventListener("message", this._fnOnMessage);
667
672
  }
668
673
  },
669
674
 
@@ -678,6 +683,11 @@ sap.ui.define([
678
683
  return this.byId("page");
679
684
  },
680
685
 
686
+ _isMessageFromSampleIframe: function(eMessage) {
687
+ return eMessage.origin === this.getOwnerComponent()._sSampleIframeOrigin &&
688
+ eMessage.source === this._oHtmlControl.getDomRef().contentWindow;
689
+ },
690
+
681
691
  onMessage: function(eMessage) {
682
692
  var oModelData = this.oModel.getData();
683
693
 
@@ -685,10 +695,7 @@ sap.ui.define([
685
695
  return;
686
696
  }
687
697
 
688
- if (eMessage.origin !== this.getOwnerComponent()._sSampleIframeOrigin) {
689
- return;
690
- }
691
- if (eMessage.source !== this._oHtmlControl.getDomRef().contentWindow) {
698
+ if (!this._isMessageFromSampleIframe(eMessage)) {
692
699
  return;
693
700
  }
694
701
 
@@ -854,6 +861,10 @@ sap.ui.define([
854
861
 
855
862
  this.oRouter.myNavToWithoutHash("sap.ui.documentation.sdk.view.SampleNotFound", "XML", false);
856
863
  setTimeout(this.appendPageTitle.bind(this, sNotFoundTitle));
864
+ },
865
+
866
+ onExit: function() {
867
+ window.removeEventListener("message", this._fnOnMessage);
857
868
  }
858
869
  });
859
870
  }
@@ -6,10 +6,16 @@
6
6
 
7
7
  sap.ui.define([
8
8
  "sap/ui/thirdparty/jquery",
9
+ "sap/base/Log",
9
10
  "sap/ui/core/Fragment",
11
+ "sap/ui/documentation/sdk/controller/util/APIInfo",
10
12
  "sap/ui/documentation/sdk/controller/BaseController",
11
13
  "sap/ui/documentation/sdk/util/ToggleFullScreenHandler",
12
14
  "sap/ui/documentation/sdk/model/formatter",
15
+ "sap/ui/documentation/Row",
16
+ "sap/ui/documentation/ParamText",
17
+ "sap/ui/documentation/JSDocType",
18
+ "sap/ui/documentation/JSDocText",
13
19
  "sap/m/Image",
14
20
  "sap/m/Label",
15
21
  "sap/m/Link",
@@ -23,10 +29,14 @@ sap.ui.define([
23
29
  "sap/m/CustomListItem",
24
30
  "sap/m/List",
25
31
  "sap/ui/dom/includeStylesheet",
26
- "sap/ui/dom/includeScript"
27
- ], function (jQuery, Fragment, BaseController, ToggleFullScreenHandler,
28
- formatter, Image, Label, Link, Text, HBox, ObjectAttribute, ObjectStatus, Popover,
29
- library, coreLibrary, CustomListItem, List, includeStylesheet, includeScript) {
32
+ "sap/ui/dom/includeScript",
33
+ "sap/uxap/ObjectPageSection",
34
+ "sap/ui/documentation/ObjectPageSubSection",
35
+ "sap/ui/core/HTML"
36
+ ], function (jQuery, Log, Fragment, APIInfo, BaseController, ToggleFullScreenHandler,
37
+ formatter, Row, ParamText, JSDocType, JSDocText, Image, Label, Link, Text, HBox, ObjectAttribute, ObjectStatus, Popover,
38
+ library, coreLibrary, CustomListItem, List, includeStylesheet, includeScript,
39
+ ObjectPageSection, ObjectPageSubSection, HTML) {
30
40
  "use strict";
31
41
 
32
42
  // shortcut for sap.m.FlexWrap
@@ -122,21 +132,56 @@ sap.ui.define([
122
132
  this._oModel.setProperty("/ui5-metadata/associations", bHasSelfAssoc ? this._selfAssociations : this._allAssociations);
123
133
  }
124
134
 
125
- if (this._oModel.getProperty("/hasFAQ")) {
126
- var sLibName = this._oEntityData.lib,
127
- sLibPath = sLibName.replace(/\./g, '/'),
128
- sFile = this._oEntityData.name.replace(sLibName, "").replace(/^[.]/, "").replace(/\./g, '/') + ".html";
129
- jQuery.ajax({
130
- type: "GET",
131
- url: './docs/api/' + sLibPath +
132
- '/demokit/faq/' + sFile,
133
- success: function (data) {
134
- this._oModel.setProperty("/faqContent", data);
135
- }.bind(this)
135
+ var sLibName = this._oEntityData.lib,
136
+ sLibPath = sLibName.replace(/\./g, '/'),
137
+ sComponentPath = this._oEntityData.name.replace(sLibName, "").replace(/^[.]/, "").replace(/\./g, '/'),
138
+ aSectionTypes = (this._oControlData.customSections || []).map(function(section) {
139
+ var sType = typeof section === 'string' ? section : section.name;
140
+ return {
141
+ type: sType,
142
+ property: sType + "Content",
143
+ displayTitle: sType.charAt(0).toUpperCase() + sType.slice(1),
144
+ sectionId: sType.toLowerCase(),
145
+ hasSubsections: section.hasSubsections || false,
146
+ subsections: section.subsections || null
147
+ };
136
148
  });
137
- }
138
149
 
139
- // Attach the model to the view
150
+ var fnLoadContent = function(sUrl, sProperty) {
151
+ return new Promise(function(resolve) {
152
+ jQuery.ajax({
153
+ url: sUrl,
154
+ success: function(data) {
155
+ this._oModel.setProperty("/" + sProperty, data);
156
+ resolve(true);
157
+ }.bind(this),
158
+ error: function() { resolve(false); }
159
+ });
160
+ }.bind(this));
161
+ }.bind(this);
162
+
163
+ var aContentPromises = aSectionTypes.map(function(oSection) {
164
+ var aPromises = [];
165
+ var sBaseUrl = './docs/api/' + sLibPath + '/demokit/sections/' + sComponentPath + '/';
166
+
167
+ if (oSection.hasSubsections) {
168
+ // Load main + subsections
169
+ aPromises.push(fnLoadContent(sBaseUrl + oSection.type + '.html', oSection.type + "_mainContent"));
170
+ oSection.subsections.forEach(function(sub) {
171
+ aPromises.push(fnLoadContent(sBaseUrl + oSection.type + '/' + sub + '.html', oSection.type + "_" + sub + "Content"));
172
+ });
173
+ } else {
174
+ // Load single section
175
+ aPromises.push(fnLoadContent(sBaseUrl + oSection.type + '.html', oSection.property));
176
+ }
177
+
178
+ return Promise.all(aPromises).then(function() { return oSection; });
179
+ });
180
+
181
+ Promise.all(aContentPromises).then(function(aSections) {
182
+ aSections.forEach(this._createAndAddSection, this);
183
+ }.bind(this));
184
+
140
185
  this.setModel(this._oModel);
141
186
 
142
187
  // Build needed resources and pre-process data
@@ -305,6 +350,40 @@ sap.ui.define([
305
350
  }
306
351
  },
307
352
 
353
+ /**
354
+ * Applies syntax highlighting to a LightTable after it is re-rendered.
355
+ * Attaches an onAfterRendering delegate to the LightTable, applies highlighting,
356
+ * and then removes the delegate.
357
+ * @param {sap.ui.documentation.LightTable} oLightTable The LightTable control to apply highlighting to
358
+ * @private
359
+ */
360
+ _applyHljsToLightTable: function(oLightTable) {
361
+ if (!oLightTable || !window.hljs) {
362
+ return;
363
+ }
364
+
365
+ var oDelegate = {
366
+ onAfterRendering: function() {
367
+ // Find unprocessed pre elements within the LightTable's DOM
368
+ var oDomRef = oLightTable.getDomRef();
369
+ if (oDomRef) {
370
+ var aPreElements = oDomRef.querySelectorAll('pre:not(.hljs)');
371
+ if (aPreElements.length > 0) {
372
+ aPreElements.forEach(function(oElement) {
373
+ oElement.classList.add('hljs');
374
+ window.hljs.highlightElement(oElement);
375
+ });
376
+ }
377
+ }
378
+ // Remove the delegate after execution
379
+ oLightTable.removeEventDelegate(oDelegate);
380
+ }
381
+ };
382
+
383
+ // Attach the delegate to the LightTable
384
+ oLightTable.addEventDelegate(oDelegate);
385
+ },
386
+
308
387
  scrollToEntity: function (sSectionId, sEntityId) {
309
388
 
310
389
  var aFilteredSubSections,
@@ -657,6 +736,366 @@ sap.ui.define([
657
736
  return this._oPopover;
658
737
  },
659
738
 
739
+ /**
740
+ * Handles the typedef toggle event
741
+ * @param {sap.ui.base.Event} oEvent The event object
742
+ */
743
+ onTypedefToggle: function(oEvent) {
744
+ var oRow = oEvent.getSource(),
745
+ oLightTable = this._findParentLightTable(oRow),
746
+ sTypedefName = oRow?.getTypedefName();
747
+
748
+ if (!sTypedefName || !oLightTable) {
749
+ return;
750
+ }
751
+
752
+ if (oRow.getExpanded()) {
753
+ oRow.setExpanded(false);
754
+
755
+ oLightTable.invalidate();
756
+ this._applyHljsToLightTable(oLightTable);
757
+
758
+ return;
759
+ }
760
+
761
+ if (oRow.getSubRows().length > 0) {
762
+ // Already loaded typedef properties, just expand
763
+ oRow.setExpanded(true);
764
+
765
+ oLightTable.invalidate();
766
+ this._applyHljsToLightTable(oLightTable);
767
+
768
+ return;
769
+ }
770
+
771
+ // Find the typedef entity in the API index first
772
+ var oTypedefInfo = this._findTypedefInApiIndex(sTypedefName);
773
+
774
+ if (oTypedefInfo) {
775
+ // Fetch complete typedef data from API.json including inherited properties
776
+ this._collectTypedefPropertiesWithInheritance(oTypedefInfo)
777
+ .then(function(aTypedefProperties) {
778
+ // Add Row controls to the LightTable for each typedef property
779
+ if (aTypedefProperties && aTypedefProperties.length > 0) {
780
+ this._addTypedefSubRows(oRow, aTypedefProperties);
781
+
782
+ oRow.setExpanded(true);
783
+ oLightTable.invalidate();
784
+ this._applyHljsToLightTable(oLightTable);
785
+ }
786
+ }.bind(this))
787
+ .catch(function(oError) {
788
+ // Handle error silently
789
+ Log.error("Error loading typedef data: " + oError);
790
+ });
791
+ }
792
+ },
793
+
794
+ /**
795
+ * Collects typedef properties including inherited properties from base typedefs.
796
+ * Traverses the inheritance chain and concatenates all properties.
797
+ * @param {object} oTypedefInfo Initial typedef info from API index
798
+ * @returns {Promise} Promise that resolves with array of all typedef properties (own + inherited)
799
+ * @private
800
+ */
801
+ _collectTypedefPropertiesWithInheritance: function(oTypedefInfo) {
802
+ var aInheritanceChain = [],
803
+ aRequiredLibs = [];
804
+
805
+ // Build the inheritance chain by traversing the extends property
806
+ // Also collect all required libraries for loading
807
+ return this._buildTypedefInheritanceChain(oTypedefInfo)
808
+ .then(function(oChainResult) {
809
+ aInheritanceChain = oChainResult.chain;
810
+ aRequiredLibs = oChainResult.libs;
811
+
812
+ // Generate promises for all required libraries
813
+ var aPromises = aRequiredLibs.map(function(sLibName) {
814
+ return APIInfo.getLibraryElementsJSONPromise(sLibName);
815
+ });
816
+
817
+ return Promise.all(aPromises);
818
+ })
819
+ .then(function(aLibResults) {
820
+ // Combine all library elements into one array
821
+ var aAllLibraryElements = [];
822
+ aLibResults.forEach(function(aSingleLibraryElements) {
823
+ aAllLibraryElements = aAllLibraryElements.concat(aSingleLibraryElements);
824
+ });
825
+
826
+ // Collect properties from all typedefs in the inheritance chain
827
+ var aAllProperties = [],
828
+ aPropertyNames = []; // Track property names to handle overrides
829
+
830
+ // Process inheritance chain in order (current typedef first, then base typedefs)
831
+ aInheritanceChain.forEach(function(sTypedefName, iIndex) {
832
+ var oTypedefData = this._findEntityInLibraryData(aAllLibraryElements, sTypedefName);
833
+
834
+ if (oTypedefData?.properties) {
835
+ oTypedefData.properties.forEach(function(oProperty) {
836
+ // Only add property if it's not already defined (handle overrides)
837
+ if (aPropertyNames.indexOf(oProperty.name) === -1) {
838
+ // Clone the property to avoid modifying the original
839
+ var oClone = jQuery.extend(true, {}, oProperty);
840
+ oClone.depth = 1;
841
+
842
+ // Mark inherited properties (not from the first typedef in chain)
843
+ if (iIndex > 0) {
844
+ oClone.borrowedFrom = sTypedefName;
845
+ }
846
+
847
+ aAllProperties.push(oClone);
848
+ aPropertyNames.push(oProperty.name);
849
+ }
850
+ });
851
+ }
852
+ }.bind(this));
853
+
854
+ return aAllProperties;
855
+ }.bind(this));
856
+ },
857
+
858
+ /**
859
+ * Builds the inheritance chain for a typedef by following the extends property.
860
+ * @param {object} oTypedefInfo Initial typedef info from API index
861
+ * @returns {Promise} Promise that resolves with object containing chain array and libs array
862
+ * @private
863
+ */
864
+ _buildTypedefInheritanceChain: function(oTypedefInfo) {
865
+ var aInheritanceChain = [oTypedefInfo.name],
866
+ aRequiredLibs = [];
867
+
868
+ // Add the initial library
869
+ if (oTypedefInfo.lib && aRequiredLibs.indexOf(oTypedefInfo.lib) === -1) {
870
+ aRequiredLibs.push(oTypedefInfo.lib);
871
+ }
872
+
873
+ // Load the initial typedef to get its extends property
874
+ return this._loadCompleteTypedefData(oTypedefInfo)
875
+ .then(function(oFullTypedefData) {
876
+ // Check if typedef has a base typedef (extends property)
877
+ if (!oFullTypedefData.extends) {
878
+ return {
879
+ chain: aInheritanceChain,
880
+ libs: aRequiredLibs
881
+ };
882
+ }
883
+
884
+ // Build the rest of the inheritance chain
885
+ return this._traverseTypedefInheritanceChain(
886
+ oFullTypedefData.extends,
887
+ aInheritanceChain,
888
+ aRequiredLibs
889
+ );
890
+ }.bind(this));
891
+ },
892
+
893
+ /**
894
+ * Recursively traverses the typedef inheritance chain.
895
+ * @param {string} sBaseTypedefName Name of the base typedef to process
896
+ * @param {array} aInheritanceChain Current inheritance chain array
897
+ * @param {array} aRequiredLibs Current required libraries array
898
+ * @returns {Promise} Promise that resolves with object containing chain and libs arrays
899
+ * @private
900
+ */
901
+ _traverseTypedefInheritanceChain: function(sBaseTypedefName, aInheritanceChain, aRequiredLibs) {
902
+ // Find the base typedef in the API index
903
+ var oBaseTypedefInfo = this._findTypedefInApiIndex(sBaseTypedefName);
904
+
905
+ // If base typedef not found, stop traversal
906
+ if (!oBaseTypedefInfo) {
907
+ return Promise.resolve({
908
+ chain: aInheritanceChain,
909
+ libs: aRequiredLibs
910
+ });
911
+ }
912
+
913
+ // Add to inheritance chain
914
+ aInheritanceChain.push(sBaseTypedefName);
915
+
916
+ // Add library if not already included
917
+ if (oBaseTypedefInfo.lib && aRequiredLibs.indexOf(oBaseTypedefInfo.lib) === -1) {
918
+ aRequiredLibs.push(oBaseTypedefInfo.lib);
919
+ }
920
+
921
+ // Load the base typedef to check if it also has a parent
922
+ return this._loadCompleteTypedefData(oBaseTypedefInfo)
923
+ .then(function(oBaseTypedefData) {
924
+ // If this typedef also extends another, continue traversal
925
+ if (oBaseTypedefData.extends) {
926
+ return this._traverseTypedefInheritanceChain(
927
+ oBaseTypedefData.extends,
928
+ aInheritanceChain,
929
+ aRequiredLibs
930
+ );
931
+ }
932
+
933
+ // No more parents, return the complete chain
934
+ return {
935
+ chain: aInheritanceChain,
936
+ libs: aRequiredLibs
937
+ };
938
+ }.bind(this))
939
+ .catch(function() {
940
+ // If loading fails, return what we have so far
941
+ return {
942
+ chain: aInheritanceChain,
943
+ libs: aRequiredLibs
944
+ };
945
+ });
946
+ },
947
+
948
+ /**
949
+ * Adds Row controls to the LightTable for typedef properties
950
+ * @param {sap.ui.documentation.Row} oParentRow The parent row being expanded
951
+ * @param {array} aTypedefProperties Array of typedef properties to add as rows
952
+ * @private
953
+ */
954
+ _addTypedefSubRows: function(oParentRow, aTypedefProperties) {
955
+ // Create sub-row controls for typedef properties
956
+ var aSubRows = aTypedefProperties.map(function(oProperty) {
957
+ return new Row({
958
+ content: [
959
+ new ParamText({
960
+ text: oProperty.name,
961
+ phoneText: oProperty.phoneName,
962
+ depth: oProperty.depth || 1,
963
+ optional: oProperty.optional
964
+ }),
965
+ new JSDocType({
966
+ typeInfo: oProperty.typeInfo
967
+ }),
968
+ new Text({
969
+ text: oProperty.defaultValue || "",
970
+ wrapping: false
971
+ }),
972
+ new JSDocText({
973
+ sanitizeContent: false,
974
+ text: this.formatter.escapeSettingsValue(oProperty.description)
975
+ })
976
+ ]
977
+ }).addStyleClass("subrow");
978
+ }.bind(this));
979
+
980
+ // Add sub-rows to the parent row
981
+ aSubRows.forEach(function(oSubRow) {
982
+ oParentRow.addSubRow(oSubRow);
983
+ });
984
+ },
985
+
986
+ /**
987
+ * Finds the parent LightTable control of a given control
988
+ * @param {sap.ui.core.Control} oControl - The control to find the parent LightTable for
989
+ * @returns {sap.ui.documentation.LightTable|null} The parent LightTable control or null if not found
990
+ * @private
991
+ */
992
+ _findParentLightTable: function(oControl) {
993
+ var oParent = oControl?.getParent();
994
+
995
+ while (oParent) {
996
+ if (oParent.isA("sap.ui.documentation.LightTable")) {
997
+ return oParent;
998
+ }
999
+ oParent = oParent.getParent();
1000
+ }
1001
+
1002
+ return null;
1003
+ },
1004
+
1005
+ /**
1006
+ * Finds a typedef entity in the API index
1007
+ * @param {string} sTypedefName The name of the typedef to find
1008
+ * @returns {object} The typedef entity data or null if not found
1009
+ * @private
1010
+ */
1011
+ _findTypedefInApiIndex: function(sTypedefName) {
1012
+ var oTypedefData = null;
1013
+
1014
+ // Recursive function to find the typedef in the API index
1015
+ function findSymbol(aNodes) {
1016
+ if (!aNodes) {
1017
+ return false;
1018
+ }
1019
+
1020
+ return aNodes.some(function(oNode) {
1021
+ var bFound = oNode.name === sTypedefName;
1022
+ if (bFound) {
1023
+ oTypedefData = oNode;
1024
+ return true;
1025
+ } else if (oNode.nodes && sTypedefName.startsWith(oNode.name + ".")) {
1026
+ return findSymbol(oNode.nodes);
1027
+ }
1028
+ return false;
1029
+ });
1030
+ }
1031
+
1032
+ // Search in the API index
1033
+ if (this._aApiIndex) {
1034
+ findSymbol(this._aApiIndex);
1035
+ }
1036
+
1037
+ return oTypedefData;
1038
+ },
1039
+
1040
+ /**
1041
+ * Loads complete typedef data from API.json files
1042
+ * @param {object} oTypedefInfo Initial typedef info from API index
1043
+ * @returns {Promise} Promise that resolves with the complete typedef data
1044
+ * @private
1045
+ */
1046
+ _loadCompleteTypedefData: function(oTypedefInfo) {
1047
+ // Get the library name from the typedef info
1048
+ var sLibName = oTypedefInfo.lib;
1049
+
1050
+ if (!sLibName) {
1051
+ return Promise.reject("Library name not found for typedef");
1052
+ }
1053
+
1054
+ // Use APIInfo to load the library's API.json data
1055
+ return APIInfo.getLibraryElementsJSONPromise(sLibName)
1056
+ .then(function(aLibData) {
1057
+ try {
1058
+ // Find the complete typedef data in the library elements
1059
+ var oTypedefData = this._findEntityInLibraryData(aLibData, oTypedefInfo.name);
1060
+
1061
+ if (oTypedefData) {
1062
+ return oTypedefData;
1063
+ } else {
1064
+ return Promise.reject("Typedef not found in library data");
1065
+ }
1066
+ } catch (oProcessError) {
1067
+ return Promise.reject("Error processing typedef data: " + oProcessError);
1068
+ }
1069
+ }.bind(this))
1070
+ .catch(function(oError) {
1071
+ return Promise.reject("Error loading library data: " + oError);
1072
+ });
1073
+ },
1074
+
1075
+ /**
1076
+ * Finds an entity in library data loaded from API.json
1077
+ * @param {array} aLibraryData Array of library elements from API.json
1078
+ * @param {string} sEntityName Name of the entity to find
1079
+ * @returns {object} The entity data or null if not found
1080
+ * @private
1081
+ */
1082
+ _findEntityInLibraryData: function(aLibraryData, sEntityName) {
1083
+ // Find entity in loaded libs data
1084
+ for (var i = 0, iLen = aLibraryData.length; i < iLen; i++) {
1085
+ var oLibItem = aLibraryData[i];
1086
+ if (oLibItem.name === sEntityName) {
1087
+ // Check if we are allowed to display the requested symbol
1088
+ // BCP: 1870269087 item may not have visibility info at all. In this case we show the item
1089
+ if (oLibItem.visibility === undefined || this._aAllowedMembers.indexOf(oLibItem.visibility) >= 0) {
1090
+ return oLibItem;
1091
+ } else {
1092
+ return null;
1093
+ }
1094
+ }
1095
+ }
1096
+ return null;
1097
+ },
1098
+
660
1099
  /**
661
1100
  * Builds the header layout structure.
662
1101
  * The header displays the entity data in 3 columns
@@ -727,6 +1166,37 @@ sap.ui.define([
727
1166
  }, this);
728
1167
  },
729
1168
 
1169
+ /**
1170
+ * Creates and adds a dynamic section to the ObjectPageLayout
1171
+ * @param {object} oSectionConfig Section configuration object
1172
+ * @private
1173
+ */
1174
+ _createAndAddSection: function(oSectionConfig) {
1175
+ var fnCreateSubSection = function(sProperty, sTitle) {
1176
+ var oHTML = new HTML({content: "{/" + sProperty + "}"});
1177
+ oHTML.setModel(this._oModel);
1178
+ return new ObjectPageSubSection(sTitle ? {title: sTitle, blocks: [oHTML]} : {blocks: [oHTML]});
1179
+ }.bind(this);
1180
+
1181
+ var aSubSections = [];
1182
+ if (oSectionConfig.hasSubsections) {
1183
+ aSubSections.push(fnCreateSubSection(oSectionConfig.type + "_mainContent", "Overview"));
1184
+ oSectionConfig.subsections.forEach(function(sub) {
1185
+ aSubSections.push(fnCreateSubSection(oSectionConfig.type + "_" + sub + "Content", sub));
1186
+ });
1187
+ } else {
1188
+ aSubSections.push(fnCreateSubSection(oSectionConfig.property));
1189
+ }
1190
+
1191
+ var oPageSection = new ObjectPageSection({
1192
+ id: this.createId(oSectionConfig.sectionId),
1193
+ title: oSectionConfig.displayTitle,
1194
+ titleUppercase: false,
1195
+ subSections: aSubSections
1196
+ });
1197
+ oPageSection.addStyleClass("sectionContent");
1198
+ this._objectPage.addSection(oPageSection);
1199
+ },
730
1200
  onAnnotationsLinkPress: function () {
731
1201
  this.scrollToEntity("annotations", "Summary");
732
1202
  },
@@ -34,6 +34,7 @@ sap.ui.define([
34
34
  },
35
35
 
36
36
  constructor : function (oComponent) {
37
+ BaseObject.call(this);
37
38
  this._oComponent = oComponent;
38
39
  },
39
40
 
@@ -74,6 +74,7 @@ sap.ui.define(
74
74
  "sap.ui.documentation.sdk.controller.util.DefaultConsentManager",
75
75
  {
76
76
  constructor: function (oComponent, oConfig) {
77
+ BaseObject.call(this);
77
78
  this._oCmponent = oComponent;
78
79
  this._oConfigUtil = oComponent.getConfigUtil();
79
80
  this._sConsentDialogComponentId = oConfig.defaultConsentDialogComponentId;