@openui5/sap.ui.core 1.128.0 → 1.130.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/THIRDPARTY.txt +2 -2
- package/package.json +1 -1
- package/src/jquery.sap.global.js +7 -7
- package/src/jquery.sap.properties.js +1 -1
- package/src/jquery.sap.resources.js +1 -1
- package/src/jquery.sap.script.js +1 -1
- package/src/jquery.sap.storage.js +3 -3
- package/src/jquery.sap.trace.js +18 -18
- package/src/sap/base/Event.js +1 -1
- package/src/sap/base/Eventing.js +1 -1
- package/src/sap/base/config.js +1 -1
- package/src/sap/base/future.js +10 -2
- package/src/sap/base/i18n/LanguageTag.js +1 -1
- package/src/sap/base/i18n/date/TimezoneUtils.js +1 -1
- package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
- package/src/sap/base/util/restricted/_castArray.js +1 -1
- package/src/sap/base/util/restricted/_compact.js +1 -1
- package/src/sap/base/util/restricted/_curry.js +1 -1
- package/src/sap/base/util/restricted/_debounce.js +1 -1
- package/src/sap/base/util/restricted/_difference.js +1 -1
- package/src/sap/base/util/restricted/_differenceBy.js +1 -1
- package/src/sap/base/util/restricted/_differenceWith.js +1 -1
- package/src/sap/base/util/restricted/_flatMap.js +1 -1
- package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
- package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
- package/src/sap/base/util/restricted/_flatten.js +1 -1
- package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
- package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
- package/src/sap/base/util/restricted/_intersection.js +1 -1
- package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
- package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
- package/src/sap/base/util/restricted/_isEqual.js +1 -1
- package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
- package/src/sap/base/util/restricted/_isNil.js +1 -1
- package/src/sap/base/util/restricted/_max.js +1 -1
- package/src/sap/base/util/restricted/_merge.js +1 -1
- package/src/sap/base/util/restricted/_mergeWith.js +1 -1
- package/src/sap/base/util/restricted/_min.js +1 -1
- package/src/sap/base/util/restricted/_omit.js +1 -1
- package/src/sap/base/util/restricted/_pick.js +1 -1
- package/src/sap/base/util/restricted/_pickBy.js +1 -1
- package/src/sap/base/util/restricted/_throttle.js +1 -1
- package/src/sap/base/util/restricted/_toArray.js +1 -1
- package/src/sap/base/util/restricted/_union.js +1 -1
- package/src/sap/base/util/restricted/_unionBy.js +1 -1
- package/src/sap/base/util/restricted/_unionWith.js +1 -1
- package/src/sap/base/util/restricted/_uniq.js +1 -1
- package/src/sap/base/util/restricted/_uniqBy.js +1 -1
- package/src/sap/base/util/restricted/_uniqWith.js +1 -1
- package/src/sap/base/util/restricted/_without.js +1 -1
- package/src/sap/base/util/restricted/_xor.js +1 -1
- package/src/sap/base/util/restricted/_xorBy.js +1 -1
- package/src/sap/base/util/restricted/_xorWith.js +1 -1
- package/src/sap/base/util/restricted/_zipObject.js +1 -1
- package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
- package/src/sap/ui/Device.js +3 -3
- package/src/sap/ui/Global.js +3 -3
- package/src/sap/ui/base/BindingParser.js +1 -3
- package/src/sap/ui/base/Event.js +1 -1
- package/src/sap/ui/base/EventProvider.js +1 -1
- package/src/sap/ui/base/Interface.js +1 -1
- package/src/sap/ui/base/ManagedObject.js +4 -9
- package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
- package/src/sap/ui/base/Metadata.js +1 -1
- package/src/sap/ui/base/Object.js +1 -1
- package/src/sap/ui/base/ObjectPool.js +1 -1
- package/src/sap/ui/core/.library +2 -2
- package/src/sap/ui/core/BusyIndicator.js +1 -1
- package/src/sap/ui/core/Component.js +46 -122
- package/src/sap/ui/core/ComponentContainer.js +2 -2
- package/src/sap/ui/core/ComponentHooks.js +174 -0
- package/src/sap/ui/core/ComponentMetadata.js +1 -1
- package/src/sap/ui/core/ComponentSupport.js +1 -1
- package/src/sap/ui/core/Configuration.js +1 -1
- package/src/sap/ui/core/Control.js +1 -1
- package/src/sap/ui/core/Core.js +8 -3
- package/src/sap/ui/core/CustomData.js +1 -1
- package/src/sap/ui/core/DeclarativeSupport.js +1 -1
- package/src/sap/ui/core/Element.js +6 -2
- package/src/sap/ui/core/ElementMetadata.js +1 -1
- package/src/sap/ui/core/EnabledPropagator.js +1 -1
- package/src/sap/ui/core/EventBus.js +1 -1
- package/src/sap/ui/core/Fragment.js +6 -5
- package/src/sap/ui/core/HTML.js +1 -1
- package/src/sap/ui/core/History.js +1 -1
- package/src/sap/ui/core/Icon.js +2 -2
- package/src/sap/ui/core/IndicationColorSupport.js +1 -1
- package/src/sap/ui/core/IntervalTrigger.js +1 -1
- package/src/sap/ui/core/InvisibleMessage.js +1 -1
- package/src/sap/ui/core/InvisibleRenderer.js +1 -1
- package/src/sap/ui/core/InvisibleText.js +1 -1
- package/src/sap/ui/core/Item.js +1 -1
- package/src/sap/ui/core/LabelEnablement.js +2 -15
- package/src/sap/ui/core/LayoutData.js +1 -1
- package/src/sap/ui/core/ListItem.js +1 -1
- package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
- package/src/sap/ui/core/Locale.js +1 -1
- package/src/sap/ui/core/LocaleData.js +43 -37
- package/src/sap/ui/core/Manifest.js +2 -2
- package/src/sap/ui/core/Message.js +1 -1
- package/src/sap/ui/core/RenderManager.js +41 -32
- package/src/sap/ui/core/Renderer.js +1 -1
- package/src/sap/ui/core/ResizeHandler.js +1 -1
- package/src/sap/ui/core/ScrollBar.js +1 -1
- package/src/sap/ui/core/SeparatorItem.js +1 -1
- package/src/sap/ui/core/StaticArea.js +0 -1
- package/src/sap/ui/core/Title.js +1 -1
- package/src/sap/ui/core/TooltipBase.js +1 -1
- package/src/sap/ui/core/UIArea.js +1 -1
- package/src/sap/ui/core/UIComponent.js +3 -3
- package/src/sap/ui/core/UIComponentMetadata.js +1 -1
- package/src/sap/ui/core/ValueStateSupport.js +1 -1
- package/src/sap/ui/core/VariantLayoutData.js +1 -1
- package/src/sap/ui/core/XMLComposite.js +1 -1
- package/src/sap/ui/core/XMLCompositeMetadata.js +4 -4
- package/src/sap/ui/core/XMLTemplateProcessor.js +3 -3
- package/src/sap/ui/core/_IconRegistry.js +1 -1
- package/src/sap/ui/core/cldr/ar.json +5 -1
- package/src/sap/ui/core/cldr/ar_EG.json +5 -1
- package/src/sap/ui/core/cldr/ar_SA.json +5 -1
- package/src/sap/ui/core/cldr/bg.json +4 -0
- package/src/sap/ui/core/cldr/ca.json +4 -0
- package/src/sap/ui/core/cldr/cnr.json +4 -0
- package/src/sap/ui/core/cldr/cs.json +4 -0
- package/src/sap/ui/core/cldr/cy.json +4 -0
- package/src/sap/ui/core/cldr/da.json +4 -0
- package/src/sap/ui/core/cldr/de.json +4 -0
- package/src/sap/ui/core/cldr/de_AT.json +4 -0
- package/src/sap/ui/core/cldr/de_CH.json +4 -0
- package/src/sap/ui/core/cldr/el.json +4 -0
- package/src/sap/ui/core/cldr/el_CY.json +4 -0
- package/src/sap/ui/core/cldr/en.json +4 -0
- package/src/sap/ui/core/cldr/en_AU.json +4 -0
- package/src/sap/ui/core/cldr/en_GB.json +4 -0
- package/src/sap/ui/core/cldr/en_HK.json +5 -1
- package/src/sap/ui/core/cldr/en_IE.json +4 -0
- package/src/sap/ui/core/cldr/en_IN.json +5 -1
- package/src/sap/ui/core/cldr/en_NZ.json +4 -0
- package/src/sap/ui/core/cldr/en_PG.json +4 -0
- package/src/sap/ui/core/cldr/en_SG.json +5 -1
- package/src/sap/ui/core/cldr/en_ZA.json +4 -0
- package/src/sap/ui/core/cldr/es.json +4 -0
- package/src/sap/ui/core/cldr/es_AR.json +4 -0
- package/src/sap/ui/core/cldr/es_BO.json +4 -0
- package/src/sap/ui/core/cldr/es_CL.json +4 -0
- package/src/sap/ui/core/cldr/es_CO.json +4 -0
- package/src/sap/ui/core/cldr/es_MX.json +4 -0
- package/src/sap/ui/core/cldr/es_PE.json +4 -0
- package/src/sap/ui/core/cldr/es_UY.json +4 -0
- package/src/sap/ui/core/cldr/es_VE.json +4 -0
- package/src/sap/ui/core/cldr/et.json +4 -0
- package/src/sap/ui/core/cldr/fa.json +6 -3
- package/src/sap/ui/core/cldr/fi.json +4 -0
- package/src/sap/ui/core/cldr/fr.json +4 -0
- package/src/sap/ui/core/cldr/fr_BE.json +4 -0
- package/src/sap/ui/core/cldr/fr_CA.json +4 -0
- package/src/sap/ui/core/cldr/fr_CH.json +4 -0
- package/src/sap/ui/core/cldr/fr_LU.json +4 -0
- package/src/sap/ui/core/cldr/he.json +6 -3
- package/src/sap/ui/core/cldr/hi.json +5 -1
- package/src/sap/ui/core/cldr/hr.json +4 -0
- package/src/sap/ui/core/cldr/hu.json +4 -0
- package/src/sap/ui/core/cldr/id.json +5 -1
- package/src/sap/ui/core/cldr/it.json +4 -0
- package/src/sap/ui/core/cldr/it_CH.json +4 -0
- package/src/sap/ui/core/cldr/ja.json +5 -1
- package/src/sap/ui/core/cldr/kk.json +4 -0
- package/src/sap/ui/core/cldr/ko.json +5 -1
- package/src/sap/ui/core/cldr/lt.json +4 -0
- package/src/sap/ui/core/cldr/lv.json +4 -0
- package/src/sap/ui/core/cldr/mk.json +4 -0
- package/src/sap/ui/core/cldr/ms.json +5 -1
- package/src/sap/ui/core/cldr/nb.json +5 -2
- package/src/sap/ui/core/cldr/nl.json +4 -0
- package/src/sap/ui/core/cldr/nl_BE.json +4 -0
- package/src/sap/ui/core/cldr/pl.json +4 -0
- package/src/sap/ui/core/cldr/pt.json +4 -0
- package/src/sap/ui/core/cldr/pt_PT.json +4 -0
- package/src/sap/ui/core/cldr/ro.json +4 -0
- package/src/sap/ui/core/cldr/ru.json +4 -0
- package/src/sap/ui/core/cldr/ru_UA.json +4 -0
- package/src/sap/ui/core/cldr/sk.json +4 -0
- package/src/sap/ui/core/cldr/sl.json +4 -0
- package/src/sap/ui/core/cldr/sr.json +4 -0
- package/src/sap/ui/core/cldr/sr_Latn.json +6 -2
- package/src/sap/ui/core/cldr/sv.json +4 -0
- package/src/sap/ui/core/cldr/th.json +5 -1
- package/src/sap/ui/core/cldr/tr.json +5 -1
- package/src/sap/ui/core/cldr/uk.json +4 -0
- package/src/sap/ui/core/cldr/vi.json +4 -0
- package/src/sap/ui/core/cldr/zh_CN.json +5 -1
- package/src/sap/ui/core/cldr/zh_HK.json +6 -3
- package/src/sap/ui/core/cldr/zh_SG.json +6 -3
- package/src/sap/ui/core/cldr/zh_TW.json +5 -1
- package/src/sap/ui/core/date/UI5Date.js +1 -1
- package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
- package/src/sap/ui/core/delegate/ScrollEnablement.js +1 -1
- package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
- package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
- package/src/sap/ui/core/dnd/DragInfo.js +1 -1
- package/src/sap/ui/core/dnd/DropInfo.js +1 -1
- package/src/sap/ui/core/fieldhelp/FieldHelp.js +8 -10
- package/src/sap/ui/core/fieldhelp/FieldHelpCustomData.js +88 -0
- package/src/sap/ui/core/fieldhelp/FieldHelpUtil.js +22 -26
- package/src/sap/ui/core/format/FormatUtils.js +1 -1
- package/src/sap/ui/core/format/NumberFormat.js +17 -24
- package/src/sap/ui/core/format/TimezoneUtil.js +1 -1
- package/src/sap/ui/core/getCompatibilityVersion.js +1 -1
- package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
- package/src/sap/ui/core/library.js +5 -7
- package/src/sap/ui/core/library.support.js +10 -1
- package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
- package/src/sap/ui/core/message/Message.js +1 -1
- package/src/sap/ui/core/message/MessageManager.js +1 -1
- package/src/sap/ui/core/message/MessageParser.js +1 -1
- package/src/sap/ui/core/message/MessageProcessor.js +1 -1
- package/src/sap/ui/core/messagebundle.properties +6 -12
- package/src/sap/ui/core/messagebundle_ar.properties +3 -6
- package/src/sap/ui/core/messagebundle_bg.properties +3 -6
- package/src/sap/ui/core/messagebundle_ca.properties +3 -6
- package/src/sap/ui/core/messagebundle_cnr.properties +3 -6
- package/src/sap/ui/core/messagebundle_cs.properties +3 -6
- package/src/sap/ui/core/messagebundle_cy.properties +3 -6
- package/src/sap/ui/core/messagebundle_da.properties +3 -6
- package/src/sap/ui/core/messagebundle_de.properties +3 -6
- package/src/sap/ui/core/messagebundle_el.properties +3 -6
- package/src/sap/ui/core/messagebundle_en.properties +3 -6
- package/src/sap/ui/core/messagebundle_en_GB.properties +3 -6
- package/src/sap/ui/core/messagebundle_en_US_saprigi.properties +3 -6
- package/src/sap/ui/core/messagebundle_es.properties +3 -6
- package/src/sap/ui/core/messagebundle_es_MX.properties +3 -6
- package/src/sap/ui/core/messagebundle_et.properties +3 -6
- package/src/sap/ui/core/messagebundle_fi.properties +3 -6
- package/src/sap/ui/core/messagebundle_fr.properties +3 -6
- package/src/sap/ui/core/messagebundle_fr_CA.properties +3 -6
- package/src/sap/ui/core/messagebundle_hi.properties +3 -6
- package/src/sap/ui/core/messagebundle_hr.properties +3 -6
- package/src/sap/ui/core/messagebundle_hu.properties +3 -6
- package/src/sap/ui/core/messagebundle_id.properties +3 -6
- package/src/sap/ui/core/messagebundle_it.properties +53 -56
- package/src/sap/ui/core/messagebundle_iw.properties +3 -6
- package/src/sap/ui/core/messagebundle_ja.properties +3 -6
- package/src/sap/ui/core/messagebundle_kk.properties +3 -6
- package/src/sap/ui/core/messagebundle_ko.properties +3 -6
- package/src/sap/ui/core/messagebundle_lt.properties +3 -6
- package/src/sap/ui/core/messagebundle_lv.properties +3 -6
- package/src/sap/ui/core/messagebundle_mk.properties +3 -6
- package/src/sap/ui/core/messagebundle_ms.properties +3 -6
- package/src/sap/ui/core/messagebundle_nl.properties +3 -6
- package/src/sap/ui/core/messagebundle_no.properties +4 -7
- package/src/sap/ui/core/messagebundle_pl.properties +3 -6
- package/src/sap/ui/core/messagebundle_pt.properties +3 -6
- package/src/sap/ui/core/messagebundle_pt_PT.properties +3 -6
- package/src/sap/ui/core/messagebundle_ro.properties +3 -6
- package/src/sap/ui/core/messagebundle_ru.properties +3 -6
- package/src/sap/ui/core/messagebundle_sh.properties +3 -6
- package/src/sap/ui/core/messagebundle_sk.properties +3 -6
- package/src/sap/ui/core/messagebundle_sl.properties +3 -6
- package/src/sap/ui/core/messagebundle_sr.properties +3 -6
- package/src/sap/ui/core/messagebundle_sv.properties +3 -6
- package/src/sap/ui/core/messagebundle_th.properties +3 -6
- package/src/sap/ui/core/messagebundle_tr.properties +3 -6
- package/src/sap/ui/core/messagebundle_uk.properties +3 -6
- package/src/sap/ui/core/messagebundle_vi.properties +3 -6
- package/src/sap/ui/core/messagebundle_zh_CN.properties +3 -6
- package/src/sap/ui/core/messagebundle_zh_TW.properties +3 -6
- package/src/sap/ui/core/mvc/Controller.js +2 -2
- package/src/sap/ui/core/mvc/HTMLView.js +1 -1
- package/src/sap/ui/core/mvc/JSONView.js +1 -1
- package/src/sap/ui/core/mvc/JSView.js +1 -1
- package/src/sap/ui/core/mvc/TemplateView.js +1 -1
- package/src/sap/ui/core/mvc/View.js +3 -3
- package/src/sap/ui/core/mvc/XMLView.js +2 -2
- package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
- package/src/sap/ui/core/plugin/LessSupport.js +1 -1
- package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
- package/src/sap/ui/core/postmessage/Bus.js +1 -1
- package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
- package/src/sap/ui/core/routing/Route.js +4 -4
- package/src/sap/ui/core/routing/Router.js +5 -5
- package/src/sap/ui/core/routing/Targets.js +3 -3
- package/src/sap/ui/core/routing/async/Target.js +1 -1
- package/src/sap/ui/core/routing/async/Targets.js +2 -2
- package/src/sap/ui/core/rules/App.support.js +13 -2
- package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
- package/src/sap/ui/core/search/SearchProvider.js +1 -1
- package/src/sap/ui/core/service/Service.js +1 -1
- package/src/sap/ui/core/service/ServiceFactory.js +1 -1
- package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
- package/src/sap/ui/core/support/Plugin.js +1 -1
- package/src/sap/ui/core/support/Support.js +1 -1
- package/src/sap/ui/core/support/ToolsAPI.js +4 -2
- package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
- package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
- package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
- package/src/sap/ui/core/support/plugins/Performance.js +1 -1
- package/src/sap/ui/core/support/plugins/Selector.js +1 -1
- package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
- package/src/sap/ui/core/support/plugins/Trace.js +1 -1
- package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
- package/src/sap/ui/core/themes/base/base.less +4238 -122
- package/src/sap/ui/core/themes/base/global.less +460 -7
- package/src/sap/ui/core/themes/base/skeleton.less +454 -3
- package/src/sap/ui/core/themes/sap_hcb/global.less +493 -40
- package/src/sap/ui/core/theming/Parameters.js +6 -6
- package/src/sap/ui/core/theming/ThemeHelper.js +16 -13
- package/src/sap/ui/core/theming/ThemeManager.js +1 -1
- package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
- package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
- package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
- package/src/sap/ui/core/tmpl/Template.js +1 -1
- package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
- package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
- package/src/sap/ui/core/util/Export.js +1 -1
- package/src/sap/ui/core/util/ExportCell.js +1 -1
- package/src/sap/ui/core/util/ExportColumn.js +1 -1
- package/src/sap/ui/core/util/ExportRow.js +1 -1
- package/src/sap/ui/core/util/ExportType.js +1 -1
- package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
- package/src/sap/ui/core/util/File.js +1 -1
- package/src/sap/ui/core/util/LibraryInfo.js +1 -1
- package/src/sap/ui/core/util/MockServer.js +1 -1
- package/src/sap/ui/core/util/PasteHelper.js +1 -1
- package/src/sap/ui/core/util/reflection/BaseTreeModifier.js +134 -148
- package/src/sap/ui/core/util/reflection/JsControlTreeModifier.js +165 -202
- package/src/sap/ui/core/util/reflection/XmlTreeModifier.js +365 -468
- package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
- package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
- package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
- package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
- package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
- package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
- package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
- package/src/sap/ui/core/webc/WebComponent.js +1 -1
- package/src/sap/ui/core/webc/WebComponentMetadata.js +1 -1
- package/src/sap/ui/core/ws/ReadyState.js +1 -1
- package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
- package/src/sap/ui/core/ws/WebSocket.js +1 -1
- package/src/sap/ui/debug/ControlTree.js +1 -1
- package/src/sap/ui/debug/DebugEnv.js +1 -1
- package/src/sap/ui/debug/PropertyList.js +1 -1
- package/src/sap/ui/dom/findTabbable.js +13 -6
- package/src/sap/ui/model/ClientModel.js +1 -1
- package/src/sap/ui/model/CompositeDataState.js +11 -12
- package/src/sap/ui/model/CompositeType.js +1 -1
- package/src/sap/ui/model/Context.js +0 -2
- package/src/sap/ui/model/DataState.js +33 -5
- package/src/sap/ui/model/ListBinding.js +19 -0
- package/src/sap/ui/model/MetaModel.js +1 -1
- package/src/sap/ui/model/Model.js +1 -1
- package/src/sap/ui/model/SelectionModel.js +1 -1
- package/src/sap/ui/model/SimpleType.js +1 -1
- package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
- package/src/sap/ui/model/Type.js +1 -1
- package/src/sap/ui/model/_Helper.js +3 -1
- package/src/sap/ui/model/json/JSONModel.js +12 -1
- package/src/sap/ui/model/message/MessageModel.js +1 -1
- package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
- package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
- package/src/sap/ui/model/odata/ODataMetaModel.js +116 -35
- package/src/sap/ui/model/odata/ODataMetadata.js +1 -1
- package/src/sap/ui/model/odata/ODataModel.js +1 -1
- package/src/sap/ui/model/odata/ODataTreeBindingFlat.js +106 -19
- package/src/sap/ui/model/odata/type/Boolean.js +1 -1
- package/src/sap/ui/model/odata/type/Byte.js +1 -1
- package/src/sap/ui/model/odata/type/Currency.js +1 -1
- package/src/sap/ui/model/odata/type/Date.js +1 -1
- package/src/sap/ui/model/odata/type/DateTime.js +1 -1
- package/src/sap/ui/model/odata/type/DateTimeBase.js +1 -1
- package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
- package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +1 -1
- package/src/sap/ui/model/odata/type/Decimal.js +1 -1
- package/src/sap/ui/model/odata/type/Double.js +1 -1
- package/src/sap/ui/model/odata/type/Guid.js +1 -1
- package/src/sap/ui/model/odata/type/Int.js +1 -1
- package/src/sap/ui/model/odata/type/Int16.js +1 -1
- package/src/sap/ui/model/odata/type/Int32.js +1 -1
- package/src/sap/ui/model/odata/type/Int64.js +1 -1
- package/src/sap/ui/model/odata/type/ODataType.js +1 -1
- package/src/sap/ui/model/odata/type/Raw.js +1 -1
- package/src/sap/ui/model/odata/type/SByte.js +1 -1
- package/src/sap/ui/model/odata/type/Single.js +1 -1
- package/src/sap/ui/model/odata/type/Stream.js +1 -1
- package/src/sap/ui/model/odata/type/String.js +1 -1
- package/src/sap/ui/model/odata/type/Time.js +1 -1
- package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
- package/src/sap/ui/model/odata/type/Unit.js +1 -1
- package/src/sap/ui/model/odata/type/UnitMixin.js +14 -9
- package/src/sap/ui/model/odata/v2/Context.js +1 -1
- package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
- package/src/sap/ui/model/odata/v2/ODataListBinding.js +21 -6
- package/src/sap/ui/model/odata/v2/ODataModel.js +109 -8
- package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +1 -1
- package/src/sap/ui/model/odata/v4/Context.js +63 -14
- package/src/sap/ui/model/odata/v4/ODataBinding.js +10 -0
- package/src/sap/ui/model/odata/v4/ODataContextBinding.js +1 -1
- package/src/sap/ui/model/odata/v4/ODataListBinding.js +135 -98
- package/src/sap/ui/model/odata/v4/ODataMetaModel.js +20 -10
- package/src/sap/ui/model/odata/v4/ODataModel.js +62 -4
- package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +1 -1
- package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +141 -51
- package/src/sap/ui/model/odata/v4/lib/_AggregationHelper.js +53 -19
- package/src/sap/ui/model/odata/v4/lib/_Cache.js +152 -37
- package/src/sap/ui/model/odata/v4/lib/_Helper.js +70 -9
- package/src/sap/ui/model/odata/v4/lib/_Requestor.js +44 -7
- package/src/sap/ui/model/odata/v4/lib/_TreeState.js +57 -40
- package/src/sap/ui/model/resource/ResourceModel.js +1 -1
- package/src/sap/ui/model/type/Boolean.js +1 -1
- package/src/sap/ui/model/type/Currency.js +1 -1
- package/src/sap/ui/model/type/Date.js +3 -2
- package/src/sap/ui/model/type/DateInterval.js +3 -2
- package/src/sap/ui/model/type/DateTime.js +1 -1
- package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
- package/src/sap/ui/model/type/FileSize.js +1 -1
- package/src/sap/ui/model/type/Float.js +1 -1
- package/src/sap/ui/model/type/Integer.js +1 -1
- package/src/sap/ui/model/type/String.js +1 -1
- package/src/sap/ui/model/type/Time.js +1 -1
- package/src/sap/ui/model/type/TimeInterval.js +1 -1
- package/src/sap/ui/model/type/Unit.js +1 -1
- package/src/sap/ui/model/xml/XMLModel.js +1 -1
- package/src/sap/ui/performance/trace/FESR.js +19 -10
- package/src/sap/ui/performance/trace/Interaction.js +45 -659
- package/src/sap/ui/performance/trace/_InteractionImpl.js +705 -0
- package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
- package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
- package/src/sap/ui/test/TestUtils.js +51 -24
- package/src/sap/ui/test/generic/TestBase.js +1 -1
- package/src/sap/ui/test/gherkin/opa5TestHarness.js +6 -2
- package/src/sap/ui/util/Storage.js +1 -1
- package/src/sap/ui/util/_enforceNoReturnValue.js +1 -1
- package/src/ui5loader.js +1 -1
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* OpenUI5
|
|
3
|
+
* (c) Copyright 2009-2024 SAP SE or an SAP affiliate company.
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/*global HTMLScriptElement */
|
|
8
|
+
sap.ui.define([
|
|
9
|
+
"sap/ui/performance/Measurement",
|
|
10
|
+
"sap/ui/performance/XHRInterceptor",
|
|
11
|
+
"sap/ui/performance/trace/FESRHelper",
|
|
12
|
+
"sap/base/util/LoaderExtensions",
|
|
13
|
+
"sap/base/util/now",
|
|
14
|
+
"sap/base/util/uid",
|
|
15
|
+
"sap/base/Log",
|
|
16
|
+
"sap/ui/thirdparty/URI"
|
|
17
|
+
], function(Measurement, XHRInterceptor, FESRHelper, LoaderExtensions, now, uid, Log, URI) {
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
let bIsNavigation = false,
|
|
22
|
+
iResetCurrentBrowserEventTimer = false,
|
|
23
|
+
aInteractions = [],
|
|
24
|
+
oPendingInteraction,
|
|
25
|
+
oCurrentBrowserEvent,
|
|
26
|
+
bPerfectMatch = false,
|
|
27
|
+
bMatched = false,
|
|
28
|
+
iInteractionStepTimer,
|
|
29
|
+
iInteractionCounter = 0,
|
|
30
|
+
bIdle = false,
|
|
31
|
+
bInteractionActive = false,
|
|
32
|
+
FESR;
|
|
33
|
+
|
|
34
|
+
const mCompressedMimeTypes = {
|
|
35
|
+
"application/zip": true,
|
|
36
|
+
"application/vnd.rar": true,
|
|
37
|
+
"application/gzip": true,
|
|
38
|
+
"application/x-tar": true,
|
|
39
|
+
"application/java-archive": true,
|
|
40
|
+
"image/jpeg": true,
|
|
41
|
+
"application/pdf": true
|
|
42
|
+
},
|
|
43
|
+
sCompressedExtensions = "zip,rar,arj,z,gz,tar,lzh,cab,hqx,ace,jar,ear,war,jpg,jpeg,pdf,gzip";
|
|
44
|
+
|
|
45
|
+
function isCORSRequest(sUrl) {
|
|
46
|
+
var sHost = new URI(sUrl.toString()).host();
|
|
47
|
+
// url is relative or with same host
|
|
48
|
+
return sHost && sHost !== window.location.host;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function hexToAscii(sValue) {
|
|
52
|
+
var hex = sValue.toString();
|
|
53
|
+
var str = '';
|
|
54
|
+
for (var n = 0; n < hex.length; n += 2) {
|
|
55
|
+
str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
|
|
56
|
+
}
|
|
57
|
+
return str.trim();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function createMeasurement(iTime) {
|
|
61
|
+
return {
|
|
62
|
+
event: "startup", // event which triggered interaction - default is startup interaction
|
|
63
|
+
trigger: "undetermined", // control which triggered interaction
|
|
64
|
+
component: "undetermined", // component or app identifier
|
|
65
|
+
appVersion: "undetermined", // application version as from app descriptor
|
|
66
|
+
start: iTime || performance.timeOrigin, // interaction start - page timeOrigin if initial
|
|
67
|
+
end: 0, // interaction end
|
|
68
|
+
navigation: 0, // sum over all navigation times
|
|
69
|
+
roundtrip: 0, // time from first request sent to last received response end - without gaps and ignored overlap
|
|
70
|
+
processing: 0, // client processing time
|
|
71
|
+
duration: 0, // interaction duration
|
|
72
|
+
requests: [], // Performance API requests during interaction
|
|
73
|
+
measurements: [], // Measurements
|
|
74
|
+
sapStatistics: [], // SAP Statistics for OData
|
|
75
|
+
requestTime: 0, // sum over all requests in the interaction (oPendingInteraction.requests[0].responseEnd-oPendingInteraction.requests[0].requestStart)
|
|
76
|
+
networkTime: 0, // request time minus server time from the header
|
|
77
|
+
bytesSent: 0, // sum over all requests bytes
|
|
78
|
+
bytesReceived: 0, // sum over all response bytes
|
|
79
|
+
requestCompression: "X", // ok per default, if compression does not match SAP rules we report an empty string
|
|
80
|
+
busyDuration: 0, // summed GlobalBusyIndicator duration during this interaction
|
|
81
|
+
id: uid(), //Interaction ID
|
|
82
|
+
passportAction: "undetermined_startup_0", //default PassportAction for startup
|
|
83
|
+
rootId: undefined // root context ID
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
*
|
|
89
|
+
* @param {module:sap/ui/performance/Measurement} oMeasurement The Measurement to check for completeness.
|
|
90
|
+
* @returns {module:sap/ui/performance/Measurement | undefined} The checked Measurement if completed, otherwise undefined
|
|
91
|
+
*/
|
|
92
|
+
function isCompleteMeasurement(oMeasurement) {
|
|
93
|
+
if (oMeasurement.start > oPendingInteraction.start && oMeasurement.end < oPendingInteraction.end) {
|
|
94
|
+
return oMeasurement;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Check if request is initiated by XHR, comleted and timeframe of request is within timeframe of current interaction
|
|
100
|
+
*
|
|
101
|
+
* @param {object} oRequestTiming PerformanceResourceTiming as retrieved by performance.getEntryByType("resource")
|
|
102
|
+
* @return {boolean} true if the request is a completed XHR with started and ended within the current interaction
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
function isValidInteractionXHR(oRequestTiming) {
|
|
106
|
+
// if the request has been completed it has complete timing figures)
|
|
107
|
+
var bComplete = oRequestTiming.startTime > 0 &&
|
|
108
|
+
oRequestTiming.startTime <= oRequestTiming.requestStart &&
|
|
109
|
+
oRequestTiming.requestStart <= oRequestTiming.responseEnd;
|
|
110
|
+
|
|
111
|
+
var bPartOfInteraction = oPendingInteraction.start <= (performance.timeOrigin + oRequestTiming.requestStart) &&
|
|
112
|
+
oPendingInteraction.end >= (performance.timeOrigin + oRequestTiming.responseEnd);
|
|
113
|
+
|
|
114
|
+
return bPartOfInteraction && bComplete && oRequestTiming.initiatorType === "xmlhttprequest";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function aggregateRequestTiming(oRequest) {
|
|
118
|
+
// aggregate navigation and roundtrip with respect to requests overlapping and times w/o requests (gaps)
|
|
119
|
+
this.end = oRequest.responseEnd > this.end ? oRequest.responseEnd : this.end;
|
|
120
|
+
// sum up request time as a grand total over all requests
|
|
121
|
+
oPendingInteraction.requestTime += (oRequest.responseEnd - oRequest.startTime);
|
|
122
|
+
|
|
123
|
+
// if there is a gap between requests we add the times to the aggrgate and shift the lower limits
|
|
124
|
+
if (this.roundtripHigherLimit <= oRequest.startTime) {
|
|
125
|
+
oPendingInteraction.navigation += (this.navigationHigherLimit - this.navigationLowerLimit);
|
|
126
|
+
oPendingInteraction.roundtrip += (this.roundtripHigherLimit - this.roundtripLowerLimit);
|
|
127
|
+
this.navigationLowerLimit = oRequest.startTime;
|
|
128
|
+
this.roundtripLowerLimit = oRequest.startTime;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// shift the limits if this request was completed later than the earlier requests
|
|
132
|
+
if (oRequest.responseEnd > this.roundtripHigherLimit) {
|
|
133
|
+
this.roundtripHigherLimit = oRequest.responseEnd;
|
|
134
|
+
}
|
|
135
|
+
if (oRequest.requestStart > this.navigationHigherLimit) {
|
|
136
|
+
this.navigationHigherLimit = oRequest.requestStart;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function aggregateRequestTimings(aRequests) {
|
|
141
|
+
var oTimings = {
|
|
142
|
+
start: aRequests[0].startTime,
|
|
143
|
+
end: aRequests[0].responseEnd,
|
|
144
|
+
navigationLowerLimit: aRequests[0].startTime,
|
|
145
|
+
navigationHigherLimit: aRequests[0].requestStart,
|
|
146
|
+
roundtripLowerLimit: aRequests[0].startTime,
|
|
147
|
+
roundtripHigherLimit: aRequests[0].responseEnd
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// aggregate all timings by operating on the oTimings object
|
|
151
|
+
aRequests.forEach(aggregateRequestTiming, oTimings);
|
|
152
|
+
oPendingInteraction.navigation += (oTimings.navigationHigherLimit - oTimings.navigationLowerLimit);
|
|
153
|
+
oPendingInteraction.roundtrip += (oTimings.roundtripHigherLimit - oTimings.roundtripLowerLimit);
|
|
154
|
+
|
|
155
|
+
// calculate average network time per request
|
|
156
|
+
if (oPendingInteraction.networkTime) {
|
|
157
|
+
var iTotalNetworkTime = oPendingInteraction.requestTime - oPendingInteraction.networkTime;
|
|
158
|
+
oPendingInteraction.networkTime = iTotalNetworkTime / aRequests.length;
|
|
159
|
+
} else {
|
|
160
|
+
oPendingInteraction.networkTime = 0;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function finalizeInteraction(iTime) {
|
|
165
|
+
if (oPendingInteraction) {
|
|
166
|
+
var aAllRequestTimings = performance.getEntriesByType("resource");
|
|
167
|
+
var oFinshedInteraction;
|
|
168
|
+
oPendingInteraction.end = iTime;
|
|
169
|
+
oPendingInteraction.processing = iTime - oPendingInteraction.start;
|
|
170
|
+
oPendingInteraction.duration = oPendingInteraction.processing;
|
|
171
|
+
oPendingInteraction.requests = aAllRequestTimings.filter(isValidInteractionXHR);
|
|
172
|
+
oPendingInteraction.completeRoundtrips = 0;
|
|
173
|
+
oPendingInteraction.measurements = Measurement.filterMeasurements(isCompleteMeasurement, true);
|
|
174
|
+
if (oPendingInteraction.requests.length > 0) {
|
|
175
|
+
aggregateRequestTimings(oPendingInteraction.requests);
|
|
176
|
+
}
|
|
177
|
+
oPendingInteraction.completeRoundtrips = oPendingInteraction.requests.length;
|
|
178
|
+
|
|
179
|
+
// calculate real processing time if any processing took place
|
|
180
|
+
// cannot be negative as then requests took longer than processing
|
|
181
|
+
var iProcessing = oPendingInteraction.processing - oPendingInteraction.navigation - oPendingInteraction.roundtrip;
|
|
182
|
+
oPendingInteraction.processing = iProcessing > -1 ? iProcessing : 0;
|
|
183
|
+
|
|
184
|
+
oPendingInteraction.completed = true;
|
|
185
|
+
|
|
186
|
+
// Duration threshold 2 in order to filter not performance relevant aInteractions such as liveChange
|
|
187
|
+
if (oPendingInteraction.semanticStepName || oPendingInteraction.duration >= 2 || oPendingInteraction.requests.length > 0 || bIsNavigation) {
|
|
188
|
+
aInteractions.push(oPendingInteraction);
|
|
189
|
+
oFinshedInteraction = aInteractions[aInteractions.length - 1];
|
|
190
|
+
if (Log.isLoggable()) {
|
|
191
|
+
Log.debug("Interaction step finished: trigger: " + oPendingInteraction.trigger + "; duration: " + oPendingInteraction.duration + "; requests: " + oPendingInteraction.requests.length, "_InteractionImpl.js");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Execute onInteractionFinished always in case function exist to enable cleanup in FESR independent of filtering
|
|
195
|
+
if (FESR?.onInteractionFinished) {
|
|
196
|
+
FESR.onInteractionFinished(oFinshedInteraction);
|
|
197
|
+
}
|
|
198
|
+
Object.freeze(oPendingInteraction);
|
|
199
|
+
oPendingInteraction = null;
|
|
200
|
+
oCurrentBrowserEvent = null;
|
|
201
|
+
bIsNavigation = false;
|
|
202
|
+
bMatched = false;
|
|
203
|
+
bPerfectMatch = false;
|
|
204
|
+
clearTimeout(iResetCurrentBrowserEventTimer);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// component determination - heuristic
|
|
209
|
+
function createOwnerComponentInfo(oSrcElement) {
|
|
210
|
+
var sId, sVersion;
|
|
211
|
+
if (oSrcElement) {
|
|
212
|
+
var Component, oComponent;
|
|
213
|
+
Component = sap.ui.require("sap/ui/core/Component");
|
|
214
|
+
if (Component) {
|
|
215
|
+
while (oSrcElement && oSrcElement.getParent) {
|
|
216
|
+
oComponent = Component.getOwnerComponentFor(oSrcElement);
|
|
217
|
+
if (oComponent || oSrcElement instanceof Component) {
|
|
218
|
+
oComponent = oComponent || oSrcElement;
|
|
219
|
+
var oApp = oComponent.getManifestEntry("sap.app");
|
|
220
|
+
// get app id or module name for FESR
|
|
221
|
+
sId = oApp && oApp.id || oComponent.getMetadata().getName();
|
|
222
|
+
sVersion = oApp && oApp.applicationVersion && oApp.applicationVersion.version;
|
|
223
|
+
}
|
|
224
|
+
oSrcElement = oSrcElement.getParent();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
id: sId ? sId : "undetermined",
|
|
230
|
+
version: sVersion ? sVersion : ""
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* As UI5 resources gets also loaded via script tags we need to
|
|
235
|
+
* intercept this kind of loading as well. We assume that changing the
|
|
236
|
+
* 'src' property indicates a resource loading via a script tag. In some cases
|
|
237
|
+
* the src property will be updated multiple times, so we should intercept
|
|
238
|
+
* the same script tag only once (dataset.sapUiCoreInteractionHandled)
|
|
239
|
+
*/
|
|
240
|
+
function interceptScripts() {
|
|
241
|
+
const descScriptSrc = Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, "src");
|
|
242
|
+
Object.defineProperty(HTMLScriptElement.prototype, "src", {
|
|
243
|
+
set: function(val) {
|
|
244
|
+
var fnDone;
|
|
245
|
+
|
|
246
|
+
if (!this.dataset.sapUiCoreInteractionHandled) {
|
|
247
|
+
fnDone = _InteractionImpl.notifyAsyncStep();
|
|
248
|
+
this.addEventListener("load", function() {
|
|
249
|
+
fnDone();
|
|
250
|
+
});
|
|
251
|
+
this.addEventListener("error" , function() {
|
|
252
|
+
fnDone();
|
|
253
|
+
});
|
|
254
|
+
this.dataset.sapUiCoreInteractionHandled = "true";
|
|
255
|
+
}
|
|
256
|
+
descScriptSrc.set.call(this, val);
|
|
257
|
+
},
|
|
258
|
+
get: descScriptSrc.get
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function registerXHROverrides() {
|
|
263
|
+
// store the byte size of the body
|
|
264
|
+
XHRInterceptor.register("INTERACTION", "send" ,function() {
|
|
265
|
+
if (this.oPendingInteraction) {
|
|
266
|
+
// double string length for byte length as in js characters are stored as 16 bit ints
|
|
267
|
+
this.oPendingInteraction.bytesSent += arguments[0] ? arguments[0].length : 0;
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// store request header size
|
|
272
|
+
XHRInterceptor.register("INTERACTION", "setRequestHeader", function(sHeader, sValue) {
|
|
273
|
+
// count request header length consistent to what getAllResponseHeaders().length would return
|
|
274
|
+
if (!this.requestHeaderLength) {
|
|
275
|
+
this.requestHeaderLength = 0;
|
|
276
|
+
}
|
|
277
|
+
// assume request header byte size
|
|
278
|
+
this.requestHeaderLength += (sHeader + "").length + (sValue + "").length;
|
|
279
|
+
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// register the response handler for data collection
|
|
283
|
+
XHRInterceptor.register("INTERACTION", "open", function (sMethod, sUrl, bAsync) {
|
|
284
|
+
var sEpp,
|
|
285
|
+
sAction,
|
|
286
|
+
sRootContextID;
|
|
287
|
+
|
|
288
|
+
function handleInteraction(fnDone) {
|
|
289
|
+
if (this.readyState === 4) {
|
|
290
|
+
fnDone();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// we only need to take care of requests when we have a running interaction
|
|
294
|
+
if (oPendingInteraction) {
|
|
295
|
+
var bIsNoCorsRequest = !isCORSRequest(sUrl);
|
|
296
|
+
// only use Interaction for non CORS requests
|
|
297
|
+
if (bIsNoCorsRequest) {
|
|
298
|
+
//only track if FESR.clientID == EPP.Action && FESR.rootContextID == EPP.rootContextID
|
|
299
|
+
sEpp = FESR?.passportHeader.get(this);
|
|
300
|
+
if (sEpp && sEpp.length >= 370) {
|
|
301
|
+
sAction = hexToAscii(sEpp.substring(150, 230));
|
|
302
|
+
if (parseInt(sEpp.substring(8, 10), 16) > 2) { // version number > 2 --> extended passport
|
|
303
|
+
sRootContextID = sEpp.substring(372, 404);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
if (!sEpp || sAction && sRootContextID && oPendingInteraction.passportAction.endsWith(sAction)) {
|
|
307
|
+
this.addEventListener("readystatechange", handleResponse.bind(this, oPendingInteraction.id));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// arguments at position 2 is indicatior whether request is async or not
|
|
311
|
+
// readystatechange must not be used for sync CORS request since it does not work properly
|
|
312
|
+
// this is especially necessary in case request was not started by LoaderExtension
|
|
313
|
+
// bAsync is by default true, therefore we need to check eplicitly for value 'false'
|
|
314
|
+
if (bIsNoCorsRequest || bAsync !== false) {
|
|
315
|
+
// notify async step for all XHRs (even CORS requests)
|
|
316
|
+
this.addEventListener("readystatechange", handleInteraction.bind(this, _InteractionImpl.notifyAsyncStep()));
|
|
317
|
+
}
|
|
318
|
+
// assign the current interaction to the xhr for later response header retrieval.
|
|
319
|
+
this.oPendingInteraction = oPendingInteraction;
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// check if SAP compression rules are fulfilled
|
|
326
|
+
function checkCompression(sURL, sContentEncoding, sContentType, sContentLength) {
|
|
327
|
+
//remove hashes and queries + find extension (last . segment)
|
|
328
|
+
var fileExtension = sURL.split('.').pop().split(/\#|\?/)[0];
|
|
329
|
+
|
|
330
|
+
if (sContentEncoding === 'gzip' ||
|
|
331
|
+
sContentEncoding === 'br' ||
|
|
332
|
+
sContentType in mCompressedMimeTypes ||
|
|
333
|
+
(fileExtension && sCompressedExtensions.indexOf(fileExtension) !== -1) ||
|
|
334
|
+
sContentLength < 1024) {
|
|
335
|
+
return true;
|
|
336
|
+
} else {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// response handler which uses the custom properties we added to the xhr to retrieve information from the response headers
|
|
342
|
+
function handleResponse(sId) {
|
|
343
|
+
if (this.readyState === 4) {
|
|
344
|
+
if (this.oPendingInteraction && !this.oPendingInteraction.completed && oPendingInteraction.id === sId) {
|
|
345
|
+
// enrich interaction with information
|
|
346
|
+
var sContentLength = this.getResponseHeader("content-length"),
|
|
347
|
+
bCompressed = checkCompression(this.responseURL, this.getResponseHeader("content-encoding"), this.getResponseHeader("content-type"), sContentLength),
|
|
348
|
+
sFesrec = this.getResponseHeader("sap-perf-fesrec");
|
|
349
|
+
this.oPendingInteraction.bytesReceived += sContentLength ? parseInt(sContentLength) : 0;
|
|
350
|
+
this.oPendingInteraction.bytesReceived += this.getAllResponseHeaders().length;
|
|
351
|
+
this.oPendingInteraction.bytesSent += this.requestHeaderLength || 0;
|
|
352
|
+
// this should be true only if all responses are compressed
|
|
353
|
+
this.oPendingInteraction.requestCompression = bCompressed && (this.oPendingInteraction.requestCompression !== false);
|
|
354
|
+
// sap-perf-fesrec header contains milliseconds
|
|
355
|
+
this.oPendingInteraction.networkTime += sFesrec ? Math.round(parseFloat(sFesrec, 10) / 1000) : 0;
|
|
356
|
+
var sSapStatistics = this.getResponseHeader("sap-statistics");
|
|
357
|
+
if (sSapStatistics) {
|
|
358
|
+
var aTimings = performance.getEntriesByType("resource");
|
|
359
|
+
this.oPendingInteraction.sapStatistics.push({
|
|
360
|
+
// add response url for mapping purposes
|
|
361
|
+
url: this.responseURL,
|
|
362
|
+
statistics: sSapStatistics,
|
|
363
|
+
timing: aTimings ? aTimings[aTimings.length - 1] : undefined
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
delete this.requestHeaderLength;
|
|
367
|
+
delete this.oPendingInteraction;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
var _InteractionImpl = {
|
|
373
|
+
getAll : function(bFinalize) {
|
|
374
|
+
if (bFinalize) {
|
|
375
|
+
// force the finalization of the currently pending interaction
|
|
376
|
+
_InteractionImpl.end(true);
|
|
377
|
+
}
|
|
378
|
+
return aInteractions;
|
|
379
|
+
},
|
|
380
|
+
|
|
381
|
+
filter : function(fnFilter) {
|
|
382
|
+
var aFilteredInteractions = [];
|
|
383
|
+
if (fnFilter) {
|
|
384
|
+
for (var i = 0, l = aInteractions.length; i < l; i++) {
|
|
385
|
+
if (fnFilter(aInteractions[i])) {
|
|
386
|
+
aFilteredInteractions.push(aInteractions[i]);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return aFilteredInteractions;
|
|
391
|
+
},
|
|
392
|
+
|
|
393
|
+
getPending : function() {
|
|
394
|
+
return oPendingInteraction;
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
clear : function() {
|
|
398
|
+
aInteractions = [];
|
|
399
|
+
},
|
|
400
|
+
|
|
401
|
+
start : function(sType, oSrcElement) {
|
|
402
|
+
var iTime = now();
|
|
403
|
+
|
|
404
|
+
if (oPendingInteraction) {
|
|
405
|
+
finalizeInteraction(iTime);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
//reset async counter/timer
|
|
409
|
+
if (iInteractionStepTimer) {
|
|
410
|
+
clearTimeout(iInteractionStepTimer);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
iInteractionCounter = 0;
|
|
414
|
+
|
|
415
|
+
// clear request timings for new interaction
|
|
416
|
+
if (performance.clearResourceTimings) {
|
|
417
|
+
performance.clearResourceTimings();
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
var oComponentInfo = createOwnerComponentInfo(oSrcElement);
|
|
421
|
+
|
|
422
|
+
// setup new pending interaction
|
|
423
|
+
oPendingInteraction = createMeasurement(iTime);
|
|
424
|
+
oPendingInteraction.event = sType;
|
|
425
|
+
oPendingInteraction.component = oComponentInfo.id;
|
|
426
|
+
oPendingInteraction.appVersion = oComponentInfo.version;
|
|
427
|
+
if (oSrcElement && oSrcElement.getId) {
|
|
428
|
+
oPendingInteraction.trigger = oSrcElement.getId();
|
|
429
|
+
oPendingInteraction.semanticStepName = FESRHelper.getSemanticStepname(oSrcElement, sType);
|
|
430
|
+
}
|
|
431
|
+
/*eslint-disable no-console */
|
|
432
|
+
if (Log.isLoggable(null, "sap.ui.Performance")) {
|
|
433
|
+
console.time("INTERACTION: " + oPendingInteraction.trigger + " - " + oPendingInteraction.event);
|
|
434
|
+
}
|
|
435
|
+
/*eslint-enable no-console */
|
|
436
|
+
if (Log.isLoggable()) {
|
|
437
|
+
Log.debug("Interaction step started: trigger: " + oPendingInteraction.trigger + "; type: " + oPendingInteraction.event, "_InteractionImpl.js");
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
|
|
441
|
+
end : function(bForce) {
|
|
442
|
+
if (oPendingInteraction) {
|
|
443
|
+
if (bForce) {
|
|
444
|
+
/*eslint-disable no-console */
|
|
445
|
+
if (Log.isLoggable(null, "sap.ui.Performance")) {
|
|
446
|
+
console.timeEnd("INTERACTION: " + oPendingInteraction.trigger + " - " + oPendingInteraction.event);
|
|
447
|
+
}
|
|
448
|
+
/*eslint-enable no-console */
|
|
449
|
+
finalizeInteraction(oPendingInteraction.preliminaryEnd || now());
|
|
450
|
+
if (Log.isLoggable()) {
|
|
451
|
+
Log.debug("Interaction ended...");
|
|
452
|
+
}
|
|
453
|
+
} else {
|
|
454
|
+
// set provisionary processing time from start to end and calculate later
|
|
455
|
+
oPendingInteraction.preliminaryEnd = now();
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
|
|
460
|
+
notifyNavigation: function() {
|
|
461
|
+
bIsNavigation = true;
|
|
462
|
+
},
|
|
463
|
+
|
|
464
|
+
notifyShowBusyIndicator : function(oControl) {
|
|
465
|
+
oControl._sapui_fesr_fDelayedStartTime = now() + oControl.getBusyIndicatorDelay();
|
|
466
|
+
},
|
|
467
|
+
|
|
468
|
+
notifyHideBusyIndicator : function(oControl) {
|
|
469
|
+
if (oControl._sapui_fesr_fDelayedStartTime) {
|
|
470
|
+
// The busy indicator shown duration d is calculated with:
|
|
471
|
+
// d = "time busy indicator was hidden" - "time busy indicator was requested" - "busy indicator delay"
|
|
472
|
+
var fBusyIndicatorShownDuration = now() - oControl._sapui_fesr_fDelayedStartTime;
|
|
473
|
+
_InteractionImpl.addBusyDuration((fBusyIndicatorShownDuration > 0) ? fBusyIndicatorShownDuration : 0);
|
|
474
|
+
delete oControl._sapui_fesr_fDelayedStartTime;
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
|
|
478
|
+
notifyStepStart : function(sEventId, oElement, bForce) {
|
|
479
|
+
if (bInteractionActive) {
|
|
480
|
+
let sType,
|
|
481
|
+
elem,
|
|
482
|
+
sClosestSemanticStepName,
|
|
483
|
+
oBrowserElement;
|
|
484
|
+
|
|
485
|
+
if ((!oPendingInteraction && oCurrentBrowserEvent) || bForce) {
|
|
486
|
+
if (bForce) {
|
|
487
|
+
sType = "startup";
|
|
488
|
+
} else {
|
|
489
|
+
sType = sEventId;
|
|
490
|
+
}
|
|
491
|
+
_InteractionImpl.start(sType, oElement);
|
|
492
|
+
oPendingInteraction = _InteractionImpl.getPending();
|
|
493
|
+
|
|
494
|
+
// update pending interaction infos
|
|
495
|
+
if (oPendingInteraction && !oPendingInteraction.completed && FESR?.onInteractionStarted) {
|
|
496
|
+
oPendingInteraction.passportAction = FESR.onInteractionStarted(oPendingInteraction, bForce);
|
|
497
|
+
}
|
|
498
|
+
// _InteractionImpl.start will delete oCurrentBrowserEvent in case there is an oPendingInteraction
|
|
499
|
+
// (notifyStepStart is called with parameter bForce)
|
|
500
|
+
// Conscious decision to not move the coding because this shouldn't be a productive scenario
|
|
501
|
+
if (oCurrentBrowserEvent) {
|
|
502
|
+
oBrowserElement = oCurrentBrowserEvent.srcControl;
|
|
503
|
+
}
|
|
504
|
+
// if browser event matches the first control event we take it for trigger/event determination (step name)
|
|
505
|
+
sClosestSemanticStepName = FESRHelper.getSemanticStepname(oBrowserElement, sEventId);
|
|
506
|
+
if (oElement && oElement.getId && oBrowserElement && oElement.getId() === oBrowserElement.getId()) {
|
|
507
|
+
bPerfectMatch = true;
|
|
508
|
+
} else if (sClosestSemanticStepName) {
|
|
509
|
+
oPendingInteraction.trigger = oBrowserElement.getId();
|
|
510
|
+
oPendingInteraction.semanticStepName = sClosestSemanticStepName;
|
|
511
|
+
bPerfectMatch = true;
|
|
512
|
+
} else {
|
|
513
|
+
elem = oBrowserElement;
|
|
514
|
+
while (elem && elem.getParent()) {
|
|
515
|
+
elem = elem.getParent();
|
|
516
|
+
if (oElement.getId() === elem.getId()) {
|
|
517
|
+
// Stop looking for better fitting control in case the current browser event source control
|
|
518
|
+
// is already child of the control event which triggers the interaction because all other
|
|
519
|
+
// control events most likely does not suit better.
|
|
520
|
+
// Example: Click on image of an button will not pass the previous if
|
|
521
|
+
// (oElement.getId() !== oBrowserElement.getId() ==> btn !== btn-img).
|
|
522
|
+
// In case the button is part of an popover and the click on the button closes the popover,
|
|
523
|
+
// the coding below overwrites the button control id with the popover control id in case we
|
|
524
|
+
// don't stop here.
|
|
525
|
+
// Only look for better fitting control in case browser and control event does not fit at all
|
|
526
|
+
bMatched = true;
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
oCurrentBrowserEvent = null;
|
|
532
|
+
bIsNavigation = false;
|
|
533
|
+
iResetCurrentBrowserEventTimer = setTimeout(function() {
|
|
534
|
+
//cleanup internal registry after actual call stack.
|
|
535
|
+
oCurrentBrowserEvent = null;
|
|
536
|
+
}, 0);
|
|
537
|
+
bIdle = false;
|
|
538
|
+
_InteractionImpl.notifyStepEnd(true); // Start timer to end Interaction in case there is no timing relevant action e.g. rendering, request
|
|
539
|
+
} else if (oPendingInteraction && oBrowserElement && !bPerfectMatch) {
|
|
540
|
+
// if browser event matches one of the next control events we take it for trigger/event determination (step name)
|
|
541
|
+
elem = oBrowserElement;
|
|
542
|
+
sClosestSemanticStepName = FESRHelper.getSemanticStepname(oBrowserElement, sEventId);
|
|
543
|
+
if (elem && oElement.getId() === elem.getId()) {
|
|
544
|
+
oPendingInteraction.trigger = oElement.getId();
|
|
545
|
+
oPendingInteraction.semanticStepName = sClosestSemanticStepName;
|
|
546
|
+
oPendingInteraction.event = sEventId;
|
|
547
|
+
bPerfectMatch = true;
|
|
548
|
+
} else if (sClosestSemanticStepName) {
|
|
549
|
+
oPendingInteraction.trigger = oBrowserElement.getId();
|
|
550
|
+
oPendingInteraction.semanticStepName = sClosestSemanticStepName;
|
|
551
|
+
bPerfectMatch = true;
|
|
552
|
+
} else if (!bMatched) {
|
|
553
|
+
while (elem && elem.getParent()) {
|
|
554
|
+
elem = elem.getParent();
|
|
555
|
+
if (oElement.getId() === elem.getId()) {
|
|
556
|
+
oPendingInteraction.trigger = oElement.getId();
|
|
557
|
+
oPendingInteraction.semanticStepName = FESRHelper.getSemanticStepname(oElement, sEventId);
|
|
558
|
+
oPendingInteraction.event = sEventId;
|
|
559
|
+
//if we find no direct match we consider the last control event for the trigger/event (step name)
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
|
|
568
|
+
notifyAsyncStep : function(sStepName) {
|
|
569
|
+
if (oPendingInteraction) {
|
|
570
|
+
/*eslint-disable no-console */
|
|
571
|
+
if (Log.isLoggable(null, "sap.ui.Performance") && sStepName) {
|
|
572
|
+
console.time(sStepName);
|
|
573
|
+
}
|
|
574
|
+
/*eslint-enable no-console */
|
|
575
|
+
var sInteractionId = oPendingInteraction.id;
|
|
576
|
+
delete oPendingInteraction.preliminaryEnd; // Delete prelimanry end to force current timestamp of finalization
|
|
577
|
+
_InteractionImpl.notifyAsyncStepStart();
|
|
578
|
+
return function() {
|
|
579
|
+
_InteractionImpl.notifyAsyncStepEnd(sInteractionId);
|
|
580
|
+
/*eslint-disable no-console */
|
|
581
|
+
if (Log.isLoggable(null, "sap.ui.Performance") && sStepName) {
|
|
582
|
+
console.timeEnd(sStepName);
|
|
583
|
+
}
|
|
584
|
+
/*eslint-enable no-console */
|
|
585
|
+
};
|
|
586
|
+
} else {
|
|
587
|
+
return function() {};
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
|
|
591
|
+
notifyAsyncStepStart : function() {
|
|
592
|
+
if (oPendingInteraction) {
|
|
593
|
+
iInteractionCounter++;
|
|
594
|
+
clearTimeout(iInteractionStepTimer);
|
|
595
|
+
bIdle = false;
|
|
596
|
+
if (Log.isLoggable()) {
|
|
597
|
+
Log.debug("Interaction relevant step started - Number of pending steps: " + iInteractionCounter);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
|
|
602
|
+
notifyAsyncStepEnd : function(sId) {
|
|
603
|
+
if (oPendingInteraction && sId === oPendingInteraction.id) {
|
|
604
|
+
iInteractionCounter--;
|
|
605
|
+
_InteractionImpl.notifyStepEnd(true);
|
|
606
|
+
if (Log.isLoggable()) {
|
|
607
|
+
Log.debug("Interaction relevant step stopped - Number of pending steps: " + iInteractionCounter);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
},
|
|
611
|
+
|
|
612
|
+
notifyStepEnd : function(bCheckIdle) {
|
|
613
|
+
if (bInteractionActive) {
|
|
614
|
+
if (iInteractionCounter === 0 || !bCheckIdle) {
|
|
615
|
+
if (bIdle || !bCheckIdle) {
|
|
616
|
+
_InteractionImpl.end(true);
|
|
617
|
+
if (Log.isLoggable()) {
|
|
618
|
+
Log.debug("Interaction stopped");
|
|
619
|
+
}
|
|
620
|
+
bIdle = false;
|
|
621
|
+
} else {
|
|
622
|
+
_InteractionImpl.end(); //set preliminary end time
|
|
623
|
+
bIdle = true;
|
|
624
|
+
if (iInteractionStepTimer) {
|
|
625
|
+
clearTimeout(iInteractionStepTimer);
|
|
626
|
+
}
|
|
627
|
+
// There are control events using a debouncing mechanism for e.g. suggest event (see sap.m.Input)
|
|
628
|
+
// A common debounce treshhold (also used by sap.m.Input) is 300ms therefore we use setTimeout
|
|
629
|
+
// with 301ms to end the Interaction after execution of the debounced event
|
|
630
|
+
iInteractionStepTimer = setTimeout(_InteractionImpl.notifyStepEnd, 301);
|
|
631
|
+
if (Log.isLoggable()) {
|
|
632
|
+
Log.debug("Interaction check for bIdle time - Number of pending steps: " + iInteractionCounter);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
},
|
|
638
|
+
|
|
639
|
+
notifyEventStart : function(oEvent) {
|
|
640
|
+
oCurrentBrowserEvent = bInteractionActive ? oEvent : null;
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
notifyScrollEvent : function(oEvent) {
|
|
644
|
+
/* Scrolling is disabled as it does not work properly for non user triggered scrolling */
|
|
645
|
+
},
|
|
646
|
+
|
|
647
|
+
notifyEventEnd : function() {
|
|
648
|
+
if (oCurrentBrowserEvent) {
|
|
649
|
+
// End interaction when a new potential interaction starts
|
|
650
|
+
if (oCurrentBrowserEvent.type.match(/^(mousedown|touchstart|keydown)$/)) {
|
|
651
|
+
_InteractionImpl.end(/*bForce*/true);
|
|
652
|
+
}
|
|
653
|
+
// Clean up oCurrentBrowserEvent at the end to prevent dangling events
|
|
654
|
+
// Since oCurrentBrowser event is prerequisite to start an event we need to
|
|
655
|
+
// clean dangling browser events to avoid creating aInteractions based on these events
|
|
656
|
+
// e.g. The user clicks first somewhere on the UI on a control without press handler.
|
|
657
|
+
// After that the user scrolls in a table and triggers implicit requests via paging.
|
|
658
|
+
// This combination will create an interaction based on the first browser event,
|
|
659
|
+
// created and not cleaned up by the first click within the UI
|
|
660
|
+
if (this.eventEndTimer) {
|
|
661
|
+
clearTimeout(this.eventEndTimer);
|
|
662
|
+
}
|
|
663
|
+
this.eventEndTimer = setTimeout(function() {
|
|
664
|
+
oCurrentBrowserEvent = null;
|
|
665
|
+
delete this.eventEndTimer;
|
|
666
|
+
// There are events fired within a timeout with delay. Cleanup after 10ms
|
|
667
|
+
// to hopefully prevent cleaning up to early (before control event was fired)
|
|
668
|
+
}.bind(this), 10);
|
|
669
|
+
}
|
|
670
|
+
},
|
|
671
|
+
|
|
672
|
+
setStepComponent : function(sComponentName) {
|
|
673
|
+
if (bInteractionActive && oPendingInteraction && sComponentName && !oPendingInteraction.stepComponent) {
|
|
674
|
+
oPendingInteraction.stepComponent = sComponentName;
|
|
675
|
+
}
|
|
676
|
+
},
|
|
677
|
+
|
|
678
|
+
addBusyDuration : function (iDuration) {
|
|
679
|
+
if (bInteractionActive && oPendingInteraction) {
|
|
680
|
+
if (!oPendingInteraction.busyDuration) {
|
|
681
|
+
oPendingInteraction.busyDuration = 0;
|
|
682
|
+
}
|
|
683
|
+
oPendingInteraction.busyDuration += iDuration;
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
|
|
687
|
+
_setActive: function(bActive) {
|
|
688
|
+
bInteractionActive = bActive;
|
|
689
|
+
if (bActive) {
|
|
690
|
+
_InteractionImpl.notifyStepStart("startup", "startup", true);
|
|
691
|
+
}
|
|
692
|
+
},
|
|
693
|
+
|
|
694
|
+
_setFESR: function(oFESR) {
|
|
695
|
+
FESR = oFESR;
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
|
|
699
|
+
registerXHROverrides();
|
|
700
|
+
interceptScripts();
|
|
701
|
+
|
|
702
|
+
LoaderExtensions.notifyResourceLoading = _InteractionImpl.notifyAsyncStep;
|
|
703
|
+
|
|
704
|
+
return _InteractionImpl;
|
|
705
|
+
});
|