@openui5/sap.ui.core 1.101.0 → 1.102.2
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/.eslintrc.json +26 -5
- package/THIRDPARTY.txt +1 -1
- package/package.json +1 -1
- package/src/jquery.sap.global.js +1 -1
- 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/sap/base/assert.js +1 -1
- package/src/sap/base/strings/whitespaceReplacer.js +1 -1
- package/src/sap/base/util/restricted/_CancelablePromise.js +2 -2
- 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 +4 -4
- 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 +1 -1
- 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 -1
- package/src/sap/ui/core/BusyIndicator.js +1 -1
- package/src/sap/ui/core/CommandExecution.js +15 -12
- package/src/sap/ui/core/Component.js +31 -12
- package/src/sap/ui/core/ComponentContainer.js +1 -1
- package/src/sap/ui/core/ComponentMetadata.js +27 -12
- package/src/sap/ui/core/ComponentSupport.js +1 -1
- package/src/sap/ui/core/Configuration.js +22 -8
- package/src/sap/ui/core/Control.js +2 -3
- package/src/sap/ui/core/Core.js +95 -27
- 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 +1 -1
- 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/ExtensionPoint.js +1 -1
- package/src/sap/ui/core/FocusHandler.js +2 -3
- package/src/sap/ui/core/Fragment.js +1 -1
- 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 +1 -1
- 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 +119 -1
- package/src/sap/ui/core/Manifest.js +1 -1
- package/src/sap/ui/core/Message.js +1 -1
- package/src/sap/ui/core/Popup.js +12 -14
- package/src/sap/ui/core/RenderManager.js +1 -1
- 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 +21 -15
- package/src/sap/ui/core/SeparatorItem.js +1 -1
- package/src/sap/ui/core/ShortcutHintsMixin.js +2 -4
- 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 +3 -5
- package/src/sap/ui/core/UIComponent.js +1 -1
- 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 +1 -1
- package/src/sap/ui/core/XMLTemplateProcessor.js +512 -387
- package/src/sap/ui/core/cache/CacheManager.js +27 -0
- package/src/sap/ui/core/cache/CacheManagerNOP.js +3 -0
- package/src/sap/ui/core/cache/LRUPersistentCache.js +74 -3
- package/src/sap/ui/core/cldr/ar.json +469 -1
- package/src/sap/ui/core/cldr/ar_EG.json +469 -1
- package/src/sap/ui/core/cldr/ar_SA.json +469 -1
- package/src/sap/ui/core/cldr/bg.json +469 -1
- package/src/sap/ui/core/cldr/ca.json +469 -1
- package/src/sap/ui/core/cldr/cs.json +469 -1
- package/src/sap/ui/core/cldr/cy.json +469 -1
- package/src/sap/ui/core/cldr/da.json +469 -1
- package/src/sap/ui/core/cldr/de.json +469 -1
- package/src/sap/ui/core/cldr/de_AT.json +469 -1
- package/src/sap/ui/core/cldr/de_CH.json +469 -1
- package/src/sap/ui/core/cldr/el.json +469 -1
- package/src/sap/ui/core/cldr/el_CY.json +469 -1
- package/src/sap/ui/core/cldr/en.json +469 -1
- package/src/sap/ui/core/cldr/en_AU.json +469 -1
- package/src/sap/ui/core/cldr/en_GB.json +469 -1
- package/src/sap/ui/core/cldr/en_HK.json +469 -1
- package/src/sap/ui/core/cldr/en_IE.json +469 -1
- package/src/sap/ui/core/cldr/en_IN.json +469 -1
- package/src/sap/ui/core/cldr/en_NZ.json +469 -1
- package/src/sap/ui/core/cldr/en_PG.json +469 -1
- package/src/sap/ui/core/cldr/en_SG.json +469 -1
- package/src/sap/ui/core/cldr/en_ZA.json +469 -1
- package/src/sap/ui/core/cldr/es.json +469 -1
- package/src/sap/ui/core/cldr/es_AR.json +469 -1
- package/src/sap/ui/core/cldr/es_BO.json +469 -1
- package/src/sap/ui/core/cldr/es_CL.json +469 -1
- package/src/sap/ui/core/cldr/es_CO.json +469 -1
- package/src/sap/ui/core/cldr/es_MX.json +469 -1
- package/src/sap/ui/core/cldr/es_PE.json +469 -1
- package/src/sap/ui/core/cldr/es_UY.json +469 -1
- package/src/sap/ui/core/cldr/es_VE.json +469 -1
- package/src/sap/ui/core/cldr/et.json +469 -1
- package/src/sap/ui/core/cldr/fa.json +469 -1
- package/src/sap/ui/core/cldr/fi.json +469 -1
- package/src/sap/ui/core/cldr/fr.json +469 -1
- package/src/sap/ui/core/cldr/fr_BE.json +469 -1
- package/src/sap/ui/core/cldr/fr_CA.json +469 -1
- package/src/sap/ui/core/cldr/fr_CH.json +469 -1
- package/src/sap/ui/core/cldr/fr_LU.json +469 -1
- package/src/sap/ui/core/cldr/he.json +469 -1
- package/src/sap/ui/core/cldr/hi.json +469 -1
- package/src/sap/ui/core/cldr/hr.json +469 -1
- package/src/sap/ui/core/cldr/hu.json +469 -1
- package/src/sap/ui/core/cldr/id.json +469 -1
- package/src/sap/ui/core/cldr/it.json +469 -1
- package/src/sap/ui/core/cldr/it_CH.json +469 -1
- package/src/sap/ui/core/cldr/ja.json +469 -1
- package/src/sap/ui/core/cldr/kk.json +469 -1
- package/src/sap/ui/core/cldr/ko.json +469 -1
- package/src/sap/ui/core/cldr/lt.json +469 -1
- package/src/sap/ui/core/cldr/lv.json +469 -1
- package/src/sap/ui/core/cldr/ms.json +469 -1
- package/src/sap/ui/core/cldr/nb.json +469 -1
- package/src/sap/ui/core/cldr/nl.json +469 -1
- package/src/sap/ui/core/cldr/nl_BE.json +469 -1
- package/src/sap/ui/core/cldr/pl.json +469 -1
- package/src/sap/ui/core/cldr/pt.json +469 -1
- package/src/sap/ui/core/cldr/pt_PT.json +469 -1
- package/src/sap/ui/core/cldr/ro.json +469 -1
- package/src/sap/ui/core/cldr/ru.json +469 -1
- package/src/sap/ui/core/cldr/ru_UA.json +469 -1
- package/src/sap/ui/core/cldr/sk.json +469 -1
- package/src/sap/ui/core/cldr/sl.json +469 -1
- package/src/sap/ui/core/cldr/sr.json +469 -1
- package/src/sap/ui/core/cldr/sr_Latn.json +469 -1
- package/src/sap/ui/core/cldr/sv.json +469 -1
- package/src/sap/ui/core/cldr/th.json +469 -1
- package/src/sap/ui/core/cldr/tr.json +469 -1
- package/src/sap/ui/core/cldr/uk.json +469 -1
- package/src/sap/ui/core/cldr/vi.json +469 -1
- package/src/sap/ui/core/cldr/zh_CN.json +470 -2
- package/src/sap/ui/core/cldr/zh_HK.json +470 -2
- package/src/sap/ui/core/cldr/zh_SG.json +470 -2
- package/src/sap/ui/core/cldr/zh_TW.json +469 -1
- package/src/sap/ui/core/delegate/ItemNavigation.js +13 -14
- package/src/sap/ui/core/delegate/ScrollEnablement.js +11 -7
- package/src/sap/ui/core/dnd/DragAndDrop.js +2 -2
- 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/format/DateFormat.js +41 -26
- package/src/sap/ui/core/format/NumberFormat.js +119 -53
- package/src/sap/ui/core/format/TimezoneUtil.js +48 -16
- package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
- package/src/sap/ui/core/library.js +3 -3
- 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/mvc/HTMLView.js +1 -1
- package/src/sap/ui/core/mvc/JSONView.js +1 -1
- package/src/sap/ui/core/mvc/JSView.js +2 -2
- package/src/sap/ui/core/mvc/TemplateView.js +1 -1
- package/src/sap/ui/core/mvc/View.js +2 -1
- package/src/sap/ui/core/mvc/XMLView.js +12 -20
- package/src/sap/ui/core/mvc/XMLViewRenderer.js +81 -62
- package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
- package/src/sap/ui/core/plugin/LessSupport.js +3 -3
- 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/Router.js +1 -1
- package/src/sap/ui/core/rules/App.support.js +8 -8
- package/src/sap/ui/core/rules/Config.support.js +12 -12
- package/src/sap/ui/core/rules/Model.support.js +8 -8
- package/src/sap/ui/core/rules/Rendering.support.js +1 -1
- package/src/sap/ui/core/rules/Theming.support.js +4 -4
- package/src/sap/ui/core/rules/View.support.js +9 -9
- 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 +2 -2
- package/src/sap/ui/core/support/plugins/ControlTree.js +7 -3
- 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 +8 -22
- package/src/sap/ui/core/support/support.html +1 -1
- package/src/sap/ui/core/themes/base/LocalBusyIndicator.less +15 -1
- package/src/sap/ui/core/themes/base/base.less +4 -4
- package/src/sap/ui/core/themes/base/global.less +2 -0
- package/src/sap/ui/core/themes/sap_hcb/global.less +2 -0
- 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 +2 -2
- package/src/sap/ui/core/util/PasteHelper.js +1 -1
- 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/ws/ReadyState.js +1 -1
- package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
- package/src/sap/ui/core/ws/WebSocket.js +7 -8
- 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/model/ClientListBinding.js +127 -21
- package/src/sap/ui/model/ClientModel.js +1 -1
- package/src/sap/ui/model/CompositeDataState.js +1 -1
- package/src/sap/ui/model/CompositeType.js +1 -1
- package/src/sap/ui/model/DataState.js +1 -1
- package/src/sap/ui/model/ListBinding.js +32 -13
- 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/JSONListBinding.js +0 -58
- package/src/sap/ui/model/json/JSONModel.js +1 -1
- package/src/sap/ui/model/message/MessageListBinding.js +0 -42
- 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 +1 -1
- 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/OperationMode.js +6 -0
- 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 -2
- 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 +1 -1
- package/src/sap/ui/model/odata/v2/Context.js +13 -4
- package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
- package/src/sap/ui/model/odata/v2/ODataListBinding.js +107 -34
- package/src/sap/ui/model/odata/v2/ODataModel.js +70 -22
- package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +8 -4
- package/src/sap/ui/model/odata/v4/Context.js +25 -1
- package/src/sap/ui/model/odata/v4/ODataContextBinding.js +1 -1
- package/src/sap/ui/model/odata/v4/ODataListBinding.js +55 -26
- package/src/sap/ui/model/odata/v4/ODataMetaModel.js +13 -6
- package/src/sap/ui/model/odata/v4/ODataModel.js +111 -5
- package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +1 -1
- package/src/sap/ui/model/odata/v4/lib/_Cache.js +74 -74
- package/src/sap/ui/model/odata/v4/lib/_Helper.js +109 -39
- package/src/sap/ui/model/odata/v4/lib/_Requestor.js +60 -29
- 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 +1 -1
- package/src/sap/ui/model/type/DateInterval.js +1 -1
- 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/XMLListBinding.js +0 -53
- package/src/sap/ui/model/xml/XMLModel.js +1 -1
- 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/actions/Action.js +3 -3
- package/src/sap/ui/test/actions/Press.js +1 -1
- package/src/sap/ui/test/generic/TestBase.js +1 -1
- package/src/sap/ui/util/Storage.js +1 -1
- package/ui5.yaml +1 -1
|
@@ -125,6 +125,15 @@ function(
|
|
|
125
125
|
*/
|
|
126
126
|
var CORE_NAMESPACE = "sap.ui.core";
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* XML Namespace of the mvc relevant controls in the core library.
|
|
130
|
+
*
|
|
131
|
+
* This namespace is used to identify the view tags within the sap.ui.core.mvc namespace.
|
|
132
|
+
* @const
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
var CORE_MVC_NAMESPACE = "sap.ui.core.mvc";
|
|
136
|
+
|
|
128
137
|
/**
|
|
129
138
|
* An XML namespace that apps can use to add custom data to a control's XML element.
|
|
130
139
|
* The name of the attribute will be used as key, the value as value of a CustomData element.
|
|
@@ -168,6 +177,15 @@ function(
|
|
|
168
177
|
*/
|
|
169
178
|
var PREPROCESSOR_NAMESPACE_PREFIX = "http://schemas.sap.com/sapui5/preprocessorextension/";
|
|
170
179
|
|
|
180
|
+
/**
|
|
181
|
+
* List of attributes that are declared as "special settings" in view's metadata but can be configured on View's
|
|
182
|
+
* root tag
|
|
183
|
+
*
|
|
184
|
+
* @const
|
|
185
|
+
* @private
|
|
186
|
+
*/
|
|
187
|
+
var VIEW_SPECIAL_ATTRIBUTES = ['controllerName', 'resourceBundleName', 'resourceBundleUrl', 'resourceBundleLocale', 'resourceBundleAlias'];
|
|
188
|
+
|
|
171
189
|
/**
|
|
172
190
|
* Pattern that matches the names of all HTML void tags.
|
|
173
191
|
* @private
|
|
@@ -184,28 +202,26 @@ function(
|
|
|
184
202
|
function getHandleChildrenStrategy(bAsync, fnCallback) {
|
|
185
203
|
|
|
186
204
|
// sync strategy ensures processing order by just being sync
|
|
187
|
-
function syncStrategy(node,
|
|
188
|
-
var
|
|
189
|
-
vChild,
|
|
205
|
+
function syncStrategy(node, mOptions) {
|
|
206
|
+
var pChild,
|
|
190
207
|
aChildren = [];
|
|
191
208
|
|
|
192
|
-
for (
|
|
193
|
-
|
|
194
|
-
if (
|
|
195
|
-
aChildren.push(
|
|
209
|
+
for (var i = 0; i < node.childNodes.length; i++) {
|
|
210
|
+
pChild = fnCallback(node, node.childNodes[i], mOptions);
|
|
211
|
+
if (pChild) {
|
|
212
|
+
aChildren.push(pChild.unwrap());
|
|
196
213
|
}
|
|
197
214
|
}
|
|
198
215
|
return SyncPromise.resolve(aChildren);
|
|
199
216
|
}
|
|
200
217
|
|
|
201
218
|
// async strategy ensures processing order by chaining the callbacks
|
|
202
|
-
function asyncStrategy(node,
|
|
203
|
-
var
|
|
204
|
-
|
|
205
|
-
aChildPromises = [pRequireContext];
|
|
219
|
+
function asyncStrategy(node, mOptions) {
|
|
220
|
+
var pChain = Promise.resolve(),
|
|
221
|
+
aChildPromises = [mOptions.chain];
|
|
206
222
|
|
|
207
|
-
for (
|
|
208
|
-
pChain = pChain.then(fnCallback.bind(null, node,
|
|
223
|
+
for (var i = 0; i < node.childNodes.length; i++) {
|
|
224
|
+
pChain = pChain.then(fnCallback.bind(null, node, node.childNodes[i], mOptions));
|
|
209
225
|
aChildPromises.push(pChain);
|
|
210
226
|
}
|
|
211
227
|
return Promise.all(aChildPromises);
|
|
@@ -255,34 +271,19 @@ function(
|
|
|
255
271
|
};
|
|
256
272
|
|
|
257
273
|
/**
|
|
258
|
-
* Parses
|
|
259
|
-
*
|
|
260
|
-
*
|
|
274
|
+
* Parses special settings that are supported on the View's root tag but not declared in View's metadata. The
|
|
275
|
+
* standard properties, event handlers, aggregations and associations are parsed in the same way as the child nodes
|
|
276
|
+
* are parsed.
|
|
261
277
|
*
|
|
262
278
|
* @param {Element} xmlNode the XML element representing the View
|
|
263
279
|
* @param {sap.ui.core.mvc.XMLView} oView the View to consider when parsing the attributes
|
|
264
|
-
* @param {object} mSettings the settings object which should be enriched with the suitable attributes from the XML node
|
|
265
|
-
* @return undefined
|
|
266
280
|
*/
|
|
267
|
-
XMLTemplateProcessor.parseViewAttributes = function(xmlNode, oView
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
oView._controllerName = attr.value;
|
|
274
|
-
} else if (attr.name === 'resourceBundleName') {
|
|
275
|
-
oView._resourceBundleName = attr.value;
|
|
276
|
-
} else if (attr.name === 'resourceBundleUrl') {
|
|
277
|
-
oView._resourceBundleUrl = attr.value;
|
|
278
|
-
} else if (attr.name === 'resourceBundleLocale') {
|
|
279
|
-
oView._resourceBundleLocale = attr.value;
|
|
280
|
-
} else if (attr.name === 'resourceBundleAlias') {
|
|
281
|
-
oView._resourceBundleAlias = attr.value;
|
|
282
|
-
} else if (attr.name === 'class') {
|
|
283
|
-
oView.addStyleClass(attr.value);
|
|
284
|
-
} else if (!mSettings[attr.name] && mAllProperties[attr.name]) {
|
|
285
|
-
mSettings[attr.name] = parseScalarType(mAllProperties[attr.name].type, attr.value, attr.name, oView._oContainingView.oController);
|
|
281
|
+
XMLTemplateProcessor.parseViewAttributes = function(xmlNode, oView) {
|
|
282
|
+
var i, attr;
|
|
283
|
+
for ( i = 0; i < xmlNode.attributes.length; i++) {
|
|
284
|
+
attr = xmlNode.attributes[i];
|
|
285
|
+
if (VIEW_SPECIAL_ATTRIBUTES.includes(attr.name)) {
|
|
286
|
+
oView["_" + attr.name] = attr.value;
|
|
286
287
|
}
|
|
287
288
|
}
|
|
288
289
|
};
|
|
@@ -320,10 +321,11 @@ function(
|
|
|
320
321
|
*
|
|
321
322
|
* @param {Element} xmlNode the XML element representing the View/Fragment
|
|
322
323
|
* @param {sap.ui.core.mvc.XMLView|sap.ui.core.Fragment} oView the View/Fragment which corresponds to the parsed XML
|
|
324
|
+
* @param {object} mSettings The settings object that is given to the view's factory method
|
|
323
325
|
* @return {Array} an array containing Controls and/or plain HTML element strings
|
|
324
326
|
*/
|
|
325
|
-
XMLTemplateProcessor.parseTemplate = function(xmlNode, oView) {
|
|
326
|
-
return XMLTemplateProcessor.parseTemplatePromise(xmlNode, oView, false).unwrap();
|
|
327
|
+
XMLTemplateProcessor.parseTemplate = function(xmlNode, oView, mSettings) {
|
|
328
|
+
return XMLTemplateProcessor.parseTemplatePromise(xmlNode, oView, false, { settings: mSettings }).unwrap();
|
|
327
329
|
};
|
|
328
330
|
|
|
329
331
|
/**
|
|
@@ -339,33 +341,29 @@ function(
|
|
|
339
341
|
XMLTemplateProcessor.parseTemplatePromise = function(xmlNode, oView, bAsync, oParseConfig) {
|
|
340
342
|
return parseTemplate(xmlNode, oView, false, bAsync, oParseConfig).then(function(vResult) {
|
|
341
343
|
// vResult is the result array of the XMLTP's parsing.
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
+
// Elements in vResult can be:
|
|
345
|
+
// * RenderManager Call (Array)
|
|
346
|
+
// * Control instance (Object)
|
|
347
|
+
// * ExtensionPoint placeholder (Object)
|
|
344
348
|
|
|
345
349
|
// we only trigger Flex for ExtensionPoints inside Views
|
|
346
|
-
// A potential ExtensionPoint provider will resolve any ExtensionPoints with their correct content (or the default content, if
|
|
347
|
-
if (oView.isA("sap.ui.core.mvc.View")
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if (
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
if (vContent && vContent._isExtensionPoint) {
|
|
359
|
-
var aSpliceArgs = [i, 1].concat(vContent._aControls);
|
|
360
|
-
Array.prototype.splice.apply(vResult, aSpliceArgs);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
350
|
+
// A potential ExtensionPoint provider will resolve any ExtensionPoints with their correct content (or the default content, if no flex changes exist)
|
|
351
|
+
if (oView.isA("sap.ui.core.mvc.View")) {
|
|
352
|
+
var vContent, i;
|
|
353
|
+
// For async views all ExtensionPoints have been resolved.
|
|
354
|
+
// Their resulting content needs to be spliced into the rendering array.
|
|
355
|
+
// We loop backwards so we don't have to deal with index shifts (EPs can have more than 1 result control).
|
|
356
|
+
for (i = vResult.length - 1; i >= 0; i--) {
|
|
357
|
+
vContent = vResult[i];
|
|
358
|
+
|
|
359
|
+
if (vContent && vContent._isExtensionPoint) {
|
|
360
|
+
var aSpliceArgs = [i, 1].concat(vContent._aControls);
|
|
361
|
+
Array.prototype.splice.apply(vResult, aSpliceArgs);
|
|
363
362
|
}
|
|
364
|
-
|
|
365
|
-
});
|
|
366
|
-
} else {
|
|
367
|
-
return vResult;
|
|
363
|
+
}
|
|
368
364
|
}
|
|
365
|
+
|
|
366
|
+
return vResult;
|
|
369
367
|
});
|
|
370
368
|
};
|
|
371
369
|
|
|
@@ -395,7 +393,7 @@ function(
|
|
|
395
393
|
|
|
396
394
|
if (!oRequireContext[sKey] || typeof oRequireContext[sKey] !== "string") {
|
|
397
395
|
// The value should be a non-empty string
|
|
398
|
-
sErrorMessage = "core:require in XMLView contains
|
|
396
|
+
sErrorMessage = "core:require in XMLView contains invalid value '"
|
|
399
397
|
+ oRequireContext[sKey] + "'under key '" + sKey + "'";
|
|
400
398
|
return true;
|
|
401
399
|
}
|
|
@@ -580,14 +578,14 @@ function(
|
|
|
580
578
|
close: function(tagName) {
|
|
581
579
|
aResult.push(["close", [tagName]]);
|
|
582
580
|
},
|
|
583
|
-
renderControl: function(
|
|
584
|
-
aResult.push(
|
|
581
|
+
renderControl: function(pContent) {
|
|
582
|
+
aResult.push(pContent);
|
|
585
583
|
}
|
|
586
584
|
};
|
|
587
585
|
|
|
588
586
|
bAsync = bAsync && !!oView._sProcessingMode;
|
|
589
587
|
Log.debug("XML processing mode is " + (oView._sProcessingMode || "default") + ".", "", "XMLTemplateProcessor");
|
|
590
|
-
Log.debug("XML will be processed " + bAsync ? "asynchronously" : "synchronously" + ".", "", "XMLTemplateProcessor");
|
|
588
|
+
Log.debug("XML will be processed " + (bAsync ? "asynchronously" : "synchronously") + ".", "", "XMLTemplateProcessor");
|
|
591
589
|
|
|
592
590
|
var bDesignMode = sap.ui.getCore().getConfiguration().getDesignMode();
|
|
593
591
|
if (bDesignMode) {
|
|
@@ -599,30 +597,13 @@ function(
|
|
|
599
597
|
oView._oContainingView._sapui_declarativeSourceInfo.xmlRootNode
|
|
600
598
|
};
|
|
601
599
|
}
|
|
602
|
-
|
|
603
|
-
if (!sCurrentName) {
|
|
604
|
-
var oTopView = oView;
|
|
605
|
-
var iLoopCounter = 0; // Make sure there are not infinite loops
|
|
606
|
-
while (++iLoopCounter < 1000 && oTopView && oTopView !== oTopView._oContainingView) {
|
|
607
|
-
oTopView = oTopView._oContainingView;
|
|
608
|
-
}
|
|
609
|
-
sCurrentName = oTopView.sViewName;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
if (oView.isSubView()) {
|
|
613
|
-
parseNode(xmlNode, true, false, pResultChain);
|
|
614
|
-
} else {
|
|
615
|
-
if (xmlNode.localName === "View" && xmlNode.namespaceURI !== "sap.ui.core.mvc") {
|
|
616
|
-
// it's not <core:View>, it's <mvc:View> !!!
|
|
617
|
-
Log.warning("XMLView root node must have the 'sap.ui.core.mvc' namespace, not '" + xmlNode.namespaceURI + "'" + (sCurrentName ? " (View name: " + sCurrentName + ")" : ""));
|
|
618
|
-
}
|
|
619
|
-
|
|
600
|
+
if (!oView.isSubView()) {
|
|
620
601
|
// define internal namespace on root node
|
|
621
602
|
xmlNode.setAttributeNS(XMLNS_NAMESPACE, "xmlns:" + sInternalPrefix, UI5_INTERNAL_NAMESPACE);
|
|
622
|
-
|
|
623
|
-
parseChildren(xmlNode, false, false, pResultChain);
|
|
624
603
|
}
|
|
625
604
|
|
|
605
|
+
var bWrapped = processNode(xmlNode, pResultChain);
|
|
606
|
+
|
|
626
607
|
// iterate aResult for Promises
|
|
627
608
|
// if a Promise is found splice its resolved content at the same position in aResult
|
|
628
609
|
// then start over again starting with the position of the last extracted element
|
|
@@ -654,7 +635,20 @@ function(
|
|
|
654
635
|
// Once this Promise is resolved, we have the full view content available.
|
|
655
636
|
// The final output of the parseTemplate call will be an array containing DOM Strings and UI5 Controls.
|
|
656
637
|
// Flatten the array so that all promises are resolved and replaced.
|
|
657
|
-
return pResultChain
|
|
638
|
+
return pResultChain
|
|
639
|
+
.then(resolveResultPromises)
|
|
640
|
+
.then(function(aResult) {
|
|
641
|
+
// remove the wrapper node
|
|
642
|
+
if (bWrapped) {
|
|
643
|
+
var oWrapper = xmlNode.parentNode;
|
|
644
|
+
oWrapper.removeChild(xmlNode);
|
|
645
|
+
|
|
646
|
+
if (oWrapper.parentNode) {
|
|
647
|
+
oWrapper.parentNode.replaceChild(xmlNode, oWrapper);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
return aResult;
|
|
651
|
+
});
|
|
658
652
|
|
|
659
653
|
function identity(sId) {
|
|
660
654
|
return sId;
|
|
@@ -664,169 +658,84 @@ function(
|
|
|
664
658
|
return oView._oContainingView.createId(sId);
|
|
665
659
|
}
|
|
666
660
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
* UI5 controls will be instantiated and added as controls
|
|
671
|
-
*
|
|
672
|
-
* @param {Element} xmlNode the XML node to parse
|
|
673
|
-
* @param {boolean} bRoot whether this node is the root node
|
|
674
|
-
* @param {boolean} bIgnoreTopLevelTextNodes
|
|
675
|
-
* @param {Promise} pRequireContext Promise which resolves with the loaded modules from require context
|
|
676
|
-
* @returns {Promise} resolving with the content of the parsed node, which is a tree structure containing DOM Strings & UI5 Controls
|
|
677
|
-
*/
|
|
678
|
-
function parseNode(xmlNode, bRoot, bIgnoreTopLevelTextNodes, pRequireContext) {
|
|
679
|
-
|
|
680
|
-
if ( xmlNode.nodeType === 1 /* ELEMENT_NODE */ ) {
|
|
661
|
+
function createErrorInfo(node, vError) {
|
|
662
|
+
var sType = oView.getMetadata().isA("sap.ui.core.mvc.View") ? "View" : "Fragment";
|
|
663
|
+
var sNodeSerialization = node.outerHTML ? node.cloneNode(false).outerHTML : node.textContent;
|
|
681
664
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
if (bXHTML || xmlNode.namespaceURI === SVG_NAMESPACE) {
|
|
685
|
-
// determine ID
|
|
686
|
-
var sId = xmlNode.getAttribute("id");
|
|
687
|
-
if ( sId == null ) {
|
|
688
|
-
sId = bRoot === true ? oView.getId() : undefined;
|
|
689
|
-
} else {
|
|
690
|
-
sId = getId(oView, xmlNode);
|
|
691
|
-
}
|
|
692
|
-
if ( sLocalName === "style" ) {
|
|
693
|
-
// We need to remove the namespace prefix from style nodes
|
|
694
|
-
// otherwise the style element's content will be output as text and not evaluated as CSS
|
|
695
|
-
// We do this by manually 'cloning' the style without the NS prefix
|
|
696
|
-
|
|
697
|
-
// original node values
|
|
698
|
-
var aAttributes = xmlNode.attributes; // array-like 'NamedNodeMap'
|
|
699
|
-
var sTextContent = xmlNode.textContent;
|
|
700
|
-
|
|
701
|
-
// 'clone'
|
|
702
|
-
xmlNode = document.createElement(sLocalName);
|
|
703
|
-
xmlNode.textContent = sTextContent;
|
|
704
|
-
|
|
705
|
-
// copy all non-prefixed attributes
|
|
706
|
-
// -> prefixed attributes are invalid HTML
|
|
707
|
-
for (var j = 0; j < aAttributes.length; j++) {
|
|
708
|
-
var oAttr = aAttributes[j];
|
|
709
|
-
if (!oAttr.prefix) {
|
|
710
|
-
xmlNode.setAttribute(oAttr.name, oAttr.value);
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
// avoid encoding of style content by writing the whole tag as unsafeHtml
|
|
714
|
-
// for compatibility reasons, apply the same ID rewriting as for other tags
|
|
715
|
-
if ( sId != null ) {
|
|
716
|
-
xmlNode.setAttribute("id", sId);
|
|
717
|
-
}
|
|
718
|
-
if ( bRoot === true ) {
|
|
719
|
-
xmlNode.setAttribute("data-sap-ui-preserve", oView.getId());
|
|
720
|
-
}
|
|
721
|
-
rm.unsafeHtml(xmlNode.outerHTML);
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
724
|
-
// write opening tag
|
|
725
|
-
var bVoid = rVoidTags.test(sLocalName);
|
|
726
|
-
if ( bVoid ) {
|
|
727
|
-
rm.voidStart(sLocalName, sId);
|
|
728
|
-
} else {
|
|
729
|
-
rm.openStart(sLocalName, sId);
|
|
730
|
-
}
|
|
731
|
-
// write attributes
|
|
732
|
-
for (var i = 0; i < xmlNode.attributes.length; i++) {
|
|
733
|
-
var attr = xmlNode.attributes[i];
|
|
734
|
-
if ( attr.name !== "id" ) {
|
|
735
|
-
rm.attr(bXHTML ? attr.name.toLowerCase() : attr.name, attr.value);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
if ( bRoot === true ) {
|
|
739
|
-
rm.attr("data-sap-ui-preserve", oView.getId());
|
|
740
|
-
}
|
|
741
|
-
if ( bVoid ) {
|
|
742
|
-
rm.voidEnd();
|
|
743
|
-
if ( xmlNode.firstChild ) {
|
|
744
|
-
Log.error("Content of void HTML element '" + sLocalName + "' will be ignored");
|
|
745
|
-
}
|
|
746
|
-
} else {
|
|
747
|
-
rm.openEnd();
|
|
665
|
+
return "Error found in " + sType + " (id: '" + oView.getId() + "').\nXML node: '" + sNodeSerialization + "':\n" + vError;
|
|
666
|
+
}
|
|
748
667
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
668
|
+
function normalizeRootNode(node) {
|
|
669
|
+
var sNodeName = localName(node),
|
|
670
|
+
oWrapper;
|
|
671
|
+
|
|
672
|
+
// Normalize the view content by wrapping it with either a "View" tag or a "FragmentDefinition" tag to
|
|
673
|
+
// simplify the parsing process
|
|
674
|
+
if (oView.isA("sap.ui.core.mvc.XMLView") && (node.namespaceURI === XHTML_NAMESPACE || node.namespaceURI === SVG_NAMESPACE)) {
|
|
675
|
+
// XHTML or SVG nodes are placed into a sub view without having "View" as root tag
|
|
676
|
+
// Wrap the content into a "View" node
|
|
677
|
+
oWrapper = node.ownerDocument.createElementNS(CORE_MVC_NAMESPACE, "View");
|
|
678
|
+
} else if (oView.isA("sap.ui.core.Fragment") && (sNodeName !== "FragmentDefinition" || node.namespaceURI !== CORE_NAMESPACE)) {
|
|
679
|
+
// Wrap the content into a "FragmentDefinition" node for single control node
|
|
680
|
+
oWrapper = node.ownerDocument.createElementNS(CORE_NAMESPACE, "FragmentDefinition");
|
|
681
|
+
}
|
|
755
682
|
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
parseChildren(xmlNode, false, true, pRequireContext);
|
|
759
|
-
// TODO: check if this branch is required or can be handled by the below one
|
|
683
|
+
if (oWrapper) {
|
|
684
|
+
var oOldParent = node.parentNode;
|
|
760
685
|
|
|
761
|
-
|
|
686
|
+
if (oOldParent) {
|
|
687
|
+
oOldParent.replaceChild(oWrapper, node);
|
|
688
|
+
}
|
|
689
|
+
oWrapper.appendChild(node);
|
|
690
|
+
}
|
|
762
691
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
// Chaining the Promises as we need to make sure the order in which the XML DOM nodes are processed is fixed (depth-first, pre-order).
|
|
766
|
-
// The order of processing (and Promise resolution) is mandatory for keeping the order of the UI5 Controls' aggregation fixed and compatible.
|
|
767
|
-
return createControlOrExtension(xmlNode, pRequireContext).then(function(aChildControls) {
|
|
768
|
-
for (var i = 0; i < aChildControls.length; i++) {
|
|
769
|
-
var oChild = aChildControls[i];
|
|
770
|
-
|
|
771
|
-
// only views have a content aggregation
|
|
772
|
-
if (oView.getMetadata().hasAggregation("content")) {
|
|
773
|
-
// track extensionpoint information for root-level children of the view
|
|
774
|
-
oView._epInfo = oView._epInfo || {
|
|
775
|
-
contentControlsCount: 0,
|
|
776
|
-
last: null,
|
|
777
|
-
all: []
|
|
778
|
-
};
|
|
779
|
-
|
|
780
|
-
// child node is a placeholder for an ExtensionPoint
|
|
781
|
-
// only in Flexibility scenario if an ExtensionProvider is given!
|
|
782
|
-
if (oChild._isExtensionPoint) {
|
|
783
|
-
oChild.index = oView._epInfo.contentControlsCount;
|
|
784
|
-
oChild.targetControl = oView;
|
|
785
|
-
oChild.aggregationName = "content";
|
|
786
|
-
if (oView._epInfo.last) {
|
|
787
|
-
oView._epInfo.last._nextSibling = oChild;
|
|
788
|
-
}
|
|
789
|
-
oView._epInfo.last = oChild;
|
|
790
|
-
oView._epInfo.all.push(oChild);
|
|
791
|
-
} else {
|
|
792
|
-
// regular UI5 Controls can be added to the content aggregation directly
|
|
793
|
-
oView._epInfo.contentControlsCount++;
|
|
794
|
-
oView.addAggregation("content", oChild);
|
|
795
|
-
}
|
|
692
|
+
return oWrapper;
|
|
693
|
+
}
|
|
796
694
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
}
|
|
802
|
-
return aChildControls;
|
|
803
|
-
});
|
|
804
|
-
});
|
|
805
|
-
rm.renderControl(pResultChain);
|
|
695
|
+
function processNode(node, pChain) {
|
|
696
|
+
var bWrapped = false,
|
|
697
|
+
sCurrentName = oView.sViewName || oView._sFragmentName,
|
|
698
|
+
oNewRoot, sNodeName;
|
|
806
699
|
|
|
700
|
+
if (!sCurrentName) {
|
|
701
|
+
var oTopView = oView;
|
|
702
|
+
var iLoopCounter = 0; // Make sure there are not infinite loops
|
|
703
|
+
while (++iLoopCounter < 1000 && oTopView && oTopView !== oTopView._oContainingView) {
|
|
704
|
+
oTopView = oTopView._oContainingView;
|
|
807
705
|
}
|
|
706
|
+
sCurrentName = oTopView.sViewName;
|
|
707
|
+
}
|
|
808
708
|
|
|
809
|
-
|
|
709
|
+
oNewRoot = normalizeRootNode(node);
|
|
710
|
+
if (oNewRoot) {
|
|
711
|
+
node = oNewRoot;
|
|
712
|
+
bWrapped = true;
|
|
713
|
+
}
|
|
810
714
|
|
|
811
|
-
|
|
715
|
+
sNodeName = localName(node);
|
|
716
|
+
if (oView.isA("sap.ui.core.mvc.XMLView")) {
|
|
717
|
+
if ((sNodeName !== "View" && sNodeName !== "XMLView") || node.namespaceURI !== CORE_MVC_NAMESPACE) {
|
|
718
|
+
Log.error("XMLView's root node must be 'View' or 'XMLView' and have the namespace 'sap.ui.core.mvc'" + (sCurrentName ? " (View name: " + sCurrentName + ")" : ""));
|
|
719
|
+
}
|
|
720
|
+
// createRegularControls
|
|
721
|
+
pResultChain = pChain.then(function() {
|
|
722
|
+
return createRegularControls(node, oView.getMetadata().getClass(), pChain, null, { rootArea: true, rootNode: true });
|
|
723
|
+
});
|
|
724
|
+
} else {
|
|
725
|
+
var handleChildren = getHandleChildrenStrategy(bAsync, function(node, childNode, mOptions) {
|
|
726
|
+
if (childNode.nodeType === 1 /* Element Node*/) {
|
|
727
|
+
return createControls(childNode, mOptions.chain, null /*closest binding*/, undefined /* aggregation info*/, { rootArea: true });
|
|
728
|
+
}
|
|
729
|
+
});
|
|
812
730
|
|
|
813
|
-
|
|
814
|
-
|
|
731
|
+
pResultChain = pChain.then(function() {
|
|
732
|
+
return handleChildren(node, {
|
|
733
|
+
chain: pChain
|
|
734
|
+
});
|
|
735
|
+
});
|
|
815
736
|
|
|
816
|
-
/**
|
|
817
|
-
* Parses the children of an XML node.
|
|
818
|
-
*
|
|
819
|
-
* @param {Element} xmlNode the xml node which will be parsed
|
|
820
|
-
* @param {boolean} bRoot
|
|
821
|
-
* @param {boolean} bIgnoreToplevelTextNodes
|
|
822
|
-
* @param {Promise} pRequireContext Promise which resolves with the loaded modules from require context
|
|
823
|
-
* @returns {Promise[]} each resolving to the according child nodes content
|
|
824
|
-
*/
|
|
825
|
-
function parseChildren(xmlNode, bRoot, bIgnoreToplevelTextNodes, pRequireContext) {
|
|
826
|
-
var children = xmlNode.childNodes;
|
|
827
|
-
for (var i = 0; i < children.length; i++) {
|
|
828
|
-
parseNode(children[i], bRoot, bIgnoreToplevelTextNodes, pRequireContext);
|
|
829
737
|
}
|
|
738
|
+
return bWrapped;
|
|
830
739
|
}
|
|
831
740
|
|
|
832
741
|
/**
|
|
@@ -886,56 +795,200 @@ function(
|
|
|
886
795
|
*
|
|
887
796
|
* @param {Element} node The current XMLNode which is being processed
|
|
888
797
|
* @param {Promise} pRequireContext Promise which resolves with the loaded modules from require context
|
|
798
|
+
* @param {object} [oClosestBinding] Information on the binding that is closest to currently processed control
|
|
799
|
+
* node. Used by the flex extension-point provider to correctly trigger aggregation updates. This is necessary
|
|
800
|
+
* for extension-points that are inside a template control of an aggregation.
|
|
801
|
+
* @param {Object} [oAggregation] The information of the aggregation to which the control being processed will be added
|
|
802
|
+
* @param {object} [oConfig] The config object that contains information which is forwarded during the recursive processing
|
|
803
|
+
* @param {boolean} [oConfig.rootArea=false] Indicates whether it's processing the root area of an XMLView
|
|
804
|
+
* @param {boolean} [oConfig.rootNode=false] Indicates whether the <code>node</code> is the root node of an XMLView's content
|
|
889
805
|
* @return {Promise} resolving to an array with 0..n controls
|
|
890
806
|
* @private
|
|
891
807
|
*/
|
|
892
|
-
function createControls(node, pRequireContext, oClosestBinding) {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
808
|
+
function createControls(node, pRequireContext, oClosestBinding, oAggregation, oConfig) {
|
|
809
|
+
var bRootArea = oConfig && oConfig.rootArea,
|
|
810
|
+
bRootNodeInSubView = oConfig && oConfig.rootNode && oView.isSubView(),
|
|
811
|
+
sLocalName = localName(node),
|
|
812
|
+
bRenderingRelevant = bRootArea && (oView.isA("sap.ui.core.Fragment") || (oAggregation && oAggregation.name === "content")),
|
|
813
|
+
pResult, i;
|
|
814
|
+
|
|
815
|
+
if ( node.nodeType === 1 /* ELEMENT_NODE */ ) {
|
|
816
|
+
// differentiate between SAPUI5 and plain-HTML children
|
|
817
|
+
if (node.namespaceURI === XHTML_NAMESPACE || node.namespaceURI === SVG_NAMESPACE ) {
|
|
818
|
+
if (bRootArea) {
|
|
819
|
+
if (oAggregation && oAggregation.name !== "content") {
|
|
820
|
+
Log.error(createErrorInfo(node, "XHTML nodes can only be added to the 'content' aggregation and not to the '" + oAggregation.name + "' aggregation."));
|
|
821
|
+
return SyncPromise.resolve([]);
|
|
822
|
+
}
|
|
896
823
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
824
|
+
if (oConfig && oConfig.contentBound) {
|
|
825
|
+
throw new Error(createErrorInfo(node, "No XHTML or SVG node is allowed because the 'content' aggregation is bound."));
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
var bXHTML = node.namespaceURI === XHTML_NAMESPACE;
|
|
829
|
+
|
|
830
|
+
// determine ID
|
|
831
|
+
var sId = node.getAttribute("id");
|
|
832
|
+
if ( sId != null ) {
|
|
833
|
+
sId = getId(oView, node);
|
|
834
|
+
} else {
|
|
835
|
+
sId = bRootNodeInSubView ? oView.getId() : undefined;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
if ( sLocalName === "style" ) {
|
|
839
|
+
// We need to remove the namespace prefix from style nodes
|
|
840
|
+
// otherwise the style element's content will be output as text and not evaluated as CSS
|
|
841
|
+
// We do this by manually 'cloning' the style without the namespace prefix
|
|
842
|
+
|
|
843
|
+
// original node values
|
|
844
|
+
var aAttributes = node.attributes; // array-like 'NamedNodeMap'
|
|
845
|
+
var sTextContent = node.textContent;
|
|
846
|
+
|
|
847
|
+
// 'clone'
|
|
848
|
+
node = document.createElement(sLocalName);
|
|
849
|
+
node.textContent = sTextContent;
|
|
850
|
+
|
|
851
|
+
// copy all non-prefixed attributes
|
|
852
|
+
// -> prefixed attributes are invalid HTML
|
|
853
|
+
for (i = 0; i < aAttributes.length; i++) {
|
|
854
|
+
var oAttr = aAttributes[i];
|
|
855
|
+
if (!oAttr.prefix) {
|
|
856
|
+
node.setAttribute(oAttr.name, oAttr.value);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
// avoid encoding of style content by writing the whole tag as unsafeHtml
|
|
860
|
+
// for compatibility reasons, apply the same ID rewriting as for other tags
|
|
861
|
+
if ( sId != null ) {
|
|
862
|
+
node.setAttribute("id", sId);
|
|
863
|
+
}
|
|
864
|
+
if ( bRootNodeInSubView ) {
|
|
865
|
+
node.setAttribute("data-sap-ui-preserve", oView.getId());
|
|
866
|
+
}
|
|
867
|
+
rm.unsafeHtml(node.outerHTML);
|
|
868
|
+
return SyncPromise.resolve([]);
|
|
869
|
+
}
|
|
870
|
+
// write opening tag
|
|
871
|
+
var bVoid = rVoidTags.test(sLocalName);
|
|
872
|
+
if ( bVoid ) {
|
|
873
|
+
rm.voidStart(sLocalName, sId);
|
|
874
|
+
} else {
|
|
875
|
+
rm.openStart(sLocalName, sId);
|
|
876
|
+
}
|
|
877
|
+
// write attributes
|
|
878
|
+
for (i = 0; i < node.attributes.length; i++) {
|
|
879
|
+
var attr = node.attributes[i];
|
|
880
|
+
if ( attr.name !== "id" ) {
|
|
881
|
+
rm.attr(bXHTML ? attr.name.toLowerCase() : attr.name, attr.value);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
if ( bRootNodeInSubView ) {
|
|
885
|
+
rm.attr("data-sap-ui-preserve", oView.getId());
|
|
886
|
+
}
|
|
887
|
+
if ( bVoid ) {
|
|
888
|
+
rm.voidEnd();
|
|
889
|
+
if ( node.firstChild ) {
|
|
890
|
+
Log.error("Content of void HTML element '" + sLocalName + "' will be ignored");
|
|
891
|
+
}
|
|
892
|
+
} else {
|
|
893
|
+
rm.openEnd();
|
|
894
|
+
|
|
895
|
+
// write children
|
|
896
|
+
// For HTMLTemplateElement nodes, skip the associated DocumentFragment node
|
|
897
|
+
var oContent = node instanceof HTMLTemplateElement ? node.content : node;
|
|
898
|
+
|
|
899
|
+
var handleChildren = getHandleChildrenStrategy(bAsync, function (node, childNode, mOptions) {
|
|
900
|
+
return createControls(childNode, mOptions.chain, mOptions.closestBinding, mOptions.aggregation, mOptions.config);
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
pResult = handleChildren(oContent, {
|
|
904
|
+
chain: pRequireContext,
|
|
905
|
+
closestBinding: oClosestBinding,
|
|
906
|
+
aggregation: oAggregation,
|
|
907
|
+
config: { rootArea: bRootArea }
|
|
908
|
+
});
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
return pResult.then(function(aResults) {
|
|
912
|
+
rm.close(sLocalName);
|
|
913
|
+
|
|
914
|
+
// aResults can contain the following elements:
|
|
915
|
+
// * require context object
|
|
916
|
+
// * array of control instance(s)
|
|
917
|
+
// * undefined
|
|
918
|
+
return aResults.reduce(function(acc, vControls) {
|
|
919
|
+
if (Array.isArray(vControls)) {
|
|
920
|
+
vControls.forEach(function(oControl) {
|
|
921
|
+
acc.push(oControl);
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
return acc;
|
|
925
|
+
}, []);
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
} else {
|
|
929
|
+
var id = node.attributes['id'] ? node.attributes['id'].textContent || node.attributes['id'].text : null;
|
|
930
|
+
|
|
931
|
+
if (bEnrichFullIds) {
|
|
932
|
+
return XMLTemplateProcessor.enrichTemplateIdsPromise(node, oView, bAsync).then(function(){
|
|
933
|
+
// do not create controls
|
|
934
|
+
return [];
|
|
935
|
+
});
|
|
936
|
+
} else {
|
|
937
|
+
// plain HTML node - create a new View control
|
|
938
|
+
// creates a view instance, but makes sure the new view receives the correct owner component
|
|
939
|
+
var fnCreateView = function (oViewClass) {
|
|
940
|
+
var mViewParameters = {
|
|
941
|
+
id: id ? getId(oView, node, id) : undefined,
|
|
942
|
+
xmlNode: node,
|
|
943
|
+
containingView: oView._oContainingView,
|
|
944
|
+
processingMode: oView._sProcessingMode // add processing mode, so it can be propagated to subviews inside the HTML block
|
|
945
|
+
};
|
|
946
|
+
// running with owner component
|
|
947
|
+
if (oView.fnScopedRunWithOwner) {
|
|
948
|
+
return oView.fnScopedRunWithOwner(function () {
|
|
949
|
+
return new oViewClass(mViewParameters);
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
// no owner component
|
|
953
|
+
// (or fully sync path, which handles the owner propagation on a higher level)
|
|
915
954
|
return new oViewClass(mViewParameters);
|
|
955
|
+
};
|
|
956
|
+
|
|
957
|
+
return pRequireContext.then(function() {
|
|
958
|
+
if (bAsync) {
|
|
959
|
+
return new Promise(function (resolve, reject) {
|
|
960
|
+
sap.ui.require(["sap/ui/core/mvc/XMLView"], function(XMLView) {
|
|
961
|
+
resolve([fnCreateView(XMLView)]);
|
|
962
|
+
}, reject);
|
|
963
|
+
});
|
|
964
|
+
} else {
|
|
965
|
+
var XMLView = sap.ui.requireSync("sap/ui/core/mvc/XMLView"); // legacy-relevant: Sync path
|
|
966
|
+
return [fnCreateView(XMLView)];
|
|
967
|
+
}
|
|
916
968
|
});
|
|
917
969
|
}
|
|
918
|
-
|
|
919
|
-
// (or fully sync path, which handles the owner propagation on a higher level)
|
|
920
|
-
return new oViewClass(mViewParameters);
|
|
921
|
-
};
|
|
970
|
+
}
|
|
922
971
|
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
}, reject);
|
|
928
|
-
});
|
|
929
|
-
} else {
|
|
930
|
-
var XMLView = sap.ui.requireSync("sap/ui/core/mvc/XMLView"); // legacy-relevant: Sync path
|
|
931
|
-
return SyncPromise.resolve([fnCreateView(XMLView)]);
|
|
972
|
+
} else {
|
|
973
|
+
pResult = createControlOrExtension(node, pRequireContext, oClosestBinding);
|
|
974
|
+
if (bRenderingRelevant) {
|
|
975
|
+
rm.renderControl(pResult);
|
|
932
976
|
}
|
|
977
|
+
// non-HTML (SAPUI5) control
|
|
978
|
+
// we must return the result in either bRootArea=true or the bRootArea=false case because we use the result
|
|
979
|
+
// to add the control to the aggregation of its parent control
|
|
980
|
+
return pResult;
|
|
981
|
+
}
|
|
982
|
+
} else if (node.nodeType === 3 /* TEXT_NODE */ && bRenderingRelevant) {
|
|
983
|
+
if (!oConfig || !oConfig.contentBound) {
|
|
984
|
+
// content aggregation isn't bound
|
|
985
|
+
rm.text(node.textContent);
|
|
986
|
+
} else if (node.textContent.trim()) {
|
|
987
|
+
throw new Error(createErrorInfo(node, "Text node isn't allowed because the 'content' aggregation is bound."));
|
|
933
988
|
}
|
|
934
|
-
|
|
935
|
-
} else {
|
|
936
|
-
// non-HTML (SAPUI5) control
|
|
937
|
-
return createControlOrExtension(node, pRequireContext, oClosestBinding);
|
|
938
989
|
}
|
|
990
|
+
|
|
991
|
+
return SyncPromise.resolve([]);
|
|
939
992
|
}
|
|
940
993
|
|
|
941
994
|
/**
|
|
@@ -945,6 +998,9 @@ function(
|
|
|
945
998
|
*
|
|
946
999
|
* @param {Element} node The current XMLNode which is being processed
|
|
947
1000
|
* @param {Promise} pRequireContext Promise which resolves with the loaded modules from require context
|
|
1001
|
+
* @param {object} [oClosestBinding] Information on the binding that is closest to currently processed control
|
|
1002
|
+
* node. Used by the flex extension-point provider to correctly trigger aggregation updates. This is necessary
|
|
1003
|
+
* for extension-points that are inside a template control of an aggregation.
|
|
948
1004
|
* @return {Promise} resolving to an array with 0..n controls created from a node
|
|
949
1005
|
* @private
|
|
950
1006
|
*/
|
|
@@ -1027,10 +1083,20 @@ function(
|
|
|
1027
1083
|
* One control for regular controls, zero for ExtensionPoints without configured extension and
|
|
1028
1084
|
* n controls for multi-root Fragments.
|
|
1029
1085
|
*
|
|
1086
|
+
* @param {Element} node The current XMLNode which is being processed
|
|
1087
|
+
* @param {function} oClass The constructor of the control that is currently being processed
|
|
1088
|
+
* @param {Promise} pRequireContext Promise which resolves with the loaded modules from require context
|
|
1089
|
+
* @param {object} [oClosestBinding] Information on the binding that is closest to currently processed control
|
|
1090
|
+
* node. Used by the flex extension-point provider to correctly trigger aggregation updates. This is necessary
|
|
1091
|
+
* for extension-points that are inside a template control of an aggregation.
|
|
1092
|
+
* @param {object} [oConfig] The config object that contains information which is forwarded during the recursive processing
|
|
1093
|
+
* @param {boolean} [oConfig.rootArea=false] Indicates whether it's processing the root area of an XMLView
|
|
1094
|
+
* @param {boolean} [oConfig.rootNode=false] Indicates whether the <code>node</code> is the root node of an XMLView's content
|
|
1095
|
+
*
|
|
1030
1096
|
* @return {Promise} resolving to an array with 0..n controls created from a node
|
|
1031
1097
|
* @private
|
|
1032
1098
|
*/
|
|
1033
|
-
function createRegularControls(node, oClass, pRequireContext, oClosestBinding) {
|
|
1099
|
+
function createRegularControls(node, oClass, pRequireContext, oClosestBinding, oConfig) {
|
|
1034
1100
|
var ns = node.namespaceURI,
|
|
1035
1101
|
mSettings = {},
|
|
1036
1102
|
mAggregationsWithExtensionPoints = {},
|
|
@@ -1044,10 +1110,12 @@ function(
|
|
|
1044
1110
|
// 2. Associations
|
|
1045
1111
|
// -> might refer to controls inside the node, which have been removed earlier when the StashedControl was created
|
|
1046
1112
|
// 3. Events
|
|
1047
|
-
bStashedControl = node.getAttribute("stashed") === "true"
|
|
1048
|
-
|
|
1113
|
+
bStashedControl = node.getAttribute("stashed") === "true",
|
|
1114
|
+
bRootArea = oConfig && oConfig.rootArea,
|
|
1115
|
+
bViewRootNode = oConfig && oConfig.rootNode,
|
|
1116
|
+
oRequireContext;
|
|
1049
1117
|
|
|
1050
|
-
// remove stashed attribute as it is an
|
|
1118
|
+
// remove stashed attribute as it is an unknown property.
|
|
1051
1119
|
if (!bEnrichFullIds) {
|
|
1052
1120
|
node.removeAttribute("stashed");
|
|
1053
1121
|
}
|
|
@@ -1056,10 +1124,16 @@ function(
|
|
|
1056
1124
|
return SyncPromise.resolve([]);
|
|
1057
1125
|
}
|
|
1058
1126
|
|
|
1127
|
+
if (bViewRootNode) {
|
|
1128
|
+
// although the 'id' isn't needed for mSettings object because the view instance is already created,
|
|
1129
|
+
// it's still needed for the closestBinding info object
|
|
1130
|
+
mSettings.id = oView.getId();
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1059
1133
|
var oMetadata = oClass.getMetadata();
|
|
1060
1134
|
var mKnownSettings = oMetadata.getAllSettings();
|
|
1061
1135
|
|
|
1062
|
-
var pSelfRequireContext = parseAndLoadRequireContext(node, bAsync);
|
|
1136
|
+
var pSelfRequireContext = !bRootArea ? parseAndLoadRequireContext(node, bAsync) : undefined;
|
|
1063
1137
|
|
|
1064
1138
|
// create new promise only when the current node has core:require defined
|
|
1065
1139
|
if (pSelfRequireContext) {
|
|
@@ -1074,6 +1148,8 @@ function(
|
|
|
1074
1148
|
oRequireModules = null;
|
|
1075
1149
|
}
|
|
1076
1150
|
|
|
1151
|
+
oRequireContext = oRequireModules;
|
|
1152
|
+
|
|
1077
1153
|
if (!bEnrichFullIds) {
|
|
1078
1154
|
for (var i = 0; i < node.attributes.length; i++) {
|
|
1079
1155
|
var attr = node.attributes[i],
|
|
@@ -1082,13 +1158,17 @@ function(
|
|
|
1082
1158
|
oInfo = mKnownSettings[sName],
|
|
1083
1159
|
sValue = attr.value;
|
|
1084
1160
|
|
|
1161
|
+
if (bViewRootNode && VIEW_SPECIAL_ATTRIBUTES.includes(sName)) {
|
|
1162
|
+
continue;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1085
1165
|
// apply the value of the attribute to a
|
|
1086
1166
|
// * property,
|
|
1087
1167
|
// * association (id of the control),
|
|
1088
1168
|
// * event (name of the function in the controller) or
|
|
1089
1169
|
// * CustomData element (namespace-prefixed attribute)
|
|
1090
1170
|
|
|
1091
|
-
if (sName === "id") {
|
|
1171
|
+
if (sName === "id" && !bViewRootNode) { // "id" attribute on View's root node isn't supported
|
|
1092
1172
|
// special handling for ID
|
|
1093
1173
|
mSettings[sName] = getId(oView, node, sValue);
|
|
1094
1174
|
|
|
@@ -1255,15 +1335,10 @@ function(
|
|
|
1255
1335
|
// Errors caught here are expected UI5 issues, e.g. DataType errors, broken BindingSyntax, missing event handler functions etc.
|
|
1256
1336
|
// we enrich the error message with XML information, e.g. the node causing the issue
|
|
1257
1337
|
if (!oError.isEnriched) {
|
|
1258
|
-
var sType = oView.getMetadata().isA("sap.ui.core.mvc.View") ? "View" : "Fragment";
|
|
1259
|
-
var sNodeSerialization = node && node.cloneNode(false).outerHTML;
|
|
1260
1338
|
// Logging the error like this cuts away the stack trace,
|
|
1261
1339
|
// but provides better information for applications.
|
|
1262
1340
|
// For Framework debugging, we would have to look at the error object anyway.
|
|
1263
|
-
oError = new Error(
|
|
1264
|
-
"Error found in " + sType + " (id: '" + oView.getId() + "').\nXML node: '" + sNodeSerialization + "':\n" +
|
|
1265
|
-
oError
|
|
1266
|
-
);
|
|
1341
|
+
oError = new Error(createErrorInfo(node, oError));
|
|
1267
1342
|
oError.isEnriched = true;
|
|
1268
1343
|
|
|
1269
1344
|
// TODO: Can be enriched with additional info for a support rule (not yet implemented)
|
|
@@ -1272,7 +1347,7 @@ function(
|
|
|
1272
1347
|
|
|
1273
1348
|
// [COMPATIBILITY]
|
|
1274
1349
|
// sync: we just log the error and keep on processing
|
|
1275
|
-
// asnyc: throw the error, so the
|
|
1350
|
+
// asnyc: throw the error, so the parseTemplate Promise will reject
|
|
1276
1351
|
if (bAsync && oView._sProcessingMode !== XMLProcessingMode.SequentialLegacy) {
|
|
1277
1352
|
throw oError;
|
|
1278
1353
|
}
|
|
@@ -1291,8 +1366,13 @@ function(
|
|
|
1291
1366
|
* @return {Promise} resolving to an array with 0..n controls created from a node
|
|
1292
1367
|
* @private
|
|
1293
1368
|
*/
|
|
1294
|
-
function handleChild(node,
|
|
1295
|
-
var
|
|
1369
|
+
function handleChild(node, childNode, mOptions) {
|
|
1370
|
+
var oAggregation = mOptions.aggregation,
|
|
1371
|
+
mAggregations = mOptions.allAggregations,
|
|
1372
|
+
pRequireContext = mOptions.chain,
|
|
1373
|
+
oClosestBinding = mOptions.closestBinding,
|
|
1374
|
+
oConfig = mOptions.config,
|
|
1375
|
+
oNamedAggregation,
|
|
1296
1376
|
fnCreateStashedControl;
|
|
1297
1377
|
|
|
1298
1378
|
// inspect only element nodes
|
|
@@ -1300,22 +1380,28 @@ function(
|
|
|
1300
1380
|
|
|
1301
1381
|
if (childNode.namespaceURI === XML_COMPOSITE_NAMESPACE) {
|
|
1302
1382
|
mSettings[localName(childNode)] = childNode.querySelector("*");
|
|
1303
|
-
return;
|
|
1383
|
+
return undefined;
|
|
1304
1384
|
}
|
|
1305
1385
|
// check for a named aggregation (must have the same namespace as the parent and an aggregation with the same name must exist)
|
|
1306
1386
|
oNamedAggregation = childNode.namespaceURI === ns && mAggregations && mAggregations[localName(childNode)];
|
|
1307
1387
|
|
|
1308
1388
|
if (oNamedAggregation) {
|
|
1309
1389
|
// the children of the current childNode are aggregated controls (or HTML) below the named aggregation
|
|
1310
|
-
return handleChildren(childNode,
|
|
1390
|
+
return handleChildren(childNode, {
|
|
1391
|
+
aggregation: oNamedAggregation,
|
|
1392
|
+
allAggregations: null,
|
|
1393
|
+
chain: pRequireContext,
|
|
1394
|
+
closestBinding: oClosestBinding,
|
|
1395
|
+
config: oConfig
|
|
1396
|
+
});
|
|
1311
1397
|
} else if (oAggregation) {
|
|
1312
1398
|
// TODO consider moving this to a place where HTML and SVG nodes can be handled properly
|
|
1313
1399
|
// create a StashedControl for inactive controls, which is not placed in an aggregation
|
|
1314
|
-
if (
|
|
1400
|
+
if (childNode.getAttribute("stashed") === "true" && !bEnrichFullIds) {
|
|
1315
1401
|
var oStashedNode = childNode;
|
|
1316
|
-
// remove
|
|
1402
|
+
// clone the node and remove all descendants
|
|
1317
1403
|
childNode = childNode.cloneNode();
|
|
1318
|
-
// remove stashed attribute as it is an
|
|
1404
|
+
// remove stashed attribute as it is an unknown property.
|
|
1319
1405
|
oStashedNode.removeAttribute("stashed");
|
|
1320
1406
|
|
|
1321
1407
|
fnCreateStashedControl = function() {
|
|
@@ -1331,7 +1417,12 @@ function(
|
|
|
1331
1417
|
bAsync = false;
|
|
1332
1418
|
|
|
1333
1419
|
try {
|
|
1334
|
-
return handleChild(node,
|
|
1420
|
+
return handleChild(node, oStashedNode, {
|
|
1421
|
+
aggregation: oAggregation,
|
|
1422
|
+
allAggregations: mAggregations,
|
|
1423
|
+
chain: SyncPromise.resolve(oRequireContext),
|
|
1424
|
+
closestBinding: oClosestBinding
|
|
1425
|
+
}).unwrap();
|
|
1335
1426
|
} finally {
|
|
1336
1427
|
// EVO-Todo:revert back to the original async/sync behavior
|
|
1337
1428
|
// if we moved to the sync path for the stashed control, we might now go back to the async path.
|
|
@@ -1353,19 +1444,24 @@ function(
|
|
|
1353
1444
|
setUI5Attribute(childNode, "invisible");
|
|
1354
1445
|
}
|
|
1355
1446
|
|
|
1356
|
-
// whether the created controls will be the template for a list binding
|
|
1357
1447
|
if ( mSettings[oAggregation.name] &&
|
|
1358
|
-
|
|
1448
|
+
// whether the created controls will be the template for a list binding
|
|
1359
1449
|
typeof mSettings[oAggregation.name].path === "string") {
|
|
1360
1450
|
oClosestBinding = {
|
|
1361
1451
|
aggregation: oAggregation.name,
|
|
1362
1452
|
id: mSettings.id
|
|
1363
1453
|
};
|
|
1454
|
+
|
|
1455
|
+
// mark that the content aggregation of the View node is bound
|
|
1456
|
+
if (bViewRootNode && oAggregation.name === "content") {
|
|
1457
|
+
oConfig = oConfig || {};
|
|
1458
|
+
oConfig.contentBound = true;
|
|
1459
|
+
}
|
|
1364
1460
|
}
|
|
1365
1461
|
|
|
1366
1462
|
// child node name does not equal an aggregation name,
|
|
1367
1463
|
// so this child must be a control (or HTML) which is aggregated below the DEFAULT aggregation
|
|
1368
|
-
return createControls(childNode, pRequireContext, oClosestBinding).then(function(aControls) {
|
|
1464
|
+
return createControls(childNode, pRequireContext, oClosestBinding, oAggregation, oConfig).then(function(aControls) {
|
|
1369
1465
|
for (var j = 0; j < aControls.length; j++) {
|
|
1370
1466
|
var oControl = aControls[j];
|
|
1371
1467
|
// append the child to the aggregation
|
|
@@ -1414,14 +1510,17 @@ function(
|
|
|
1414
1510
|
}
|
|
1415
1511
|
return aControls;
|
|
1416
1512
|
});
|
|
1417
|
-
} else
|
|
1418
|
-
throw new Error("Cannot add direct child without default aggregation defined for control " + oMetadata.getElementName());
|
|
1513
|
+
} else {
|
|
1514
|
+
throw new Error(createErrorInfo(childNode, "Cannot add direct child without default aggregation defined for control " + oMetadata.getElementName()));
|
|
1419
1515
|
}
|
|
1420
|
-
|
|
1421
1516
|
} else if (childNode.nodeType === 3 /* TEXT_NODE */) {
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1517
|
+
if (oConfig && oConfig.rootArea) {
|
|
1518
|
+
createControls(childNode, pRequireContext, oClosestBinding, oAggregation, oConfig);
|
|
1519
|
+
} else {
|
|
1520
|
+
var sTextContent = childNode.textContent || childNode.text;
|
|
1521
|
+
if (sTextContent && sTextContent.trim()) { // whitespace would be okay
|
|
1522
|
+
throw new Error(createErrorInfo(childNode, "Cannot add text nodes as direct child of an aggregation. For adding text to an aggregation, a surrounding html tag is needed."));
|
|
1523
|
+
}
|
|
1425
1524
|
}
|
|
1426
1525
|
} // other nodes types are silently ignored
|
|
1427
1526
|
|
|
@@ -1431,7 +1530,13 @@ function(
|
|
|
1431
1530
|
var oAggregation = oMetadata.getDefaultAggregation();
|
|
1432
1531
|
var mAggregations = oMetadata.getAllAggregations();
|
|
1433
1532
|
|
|
1434
|
-
return handleChildren(node,
|
|
1533
|
+
return handleChildren(node, {
|
|
1534
|
+
aggregation: oAggregation,
|
|
1535
|
+
allAggregations: mAggregations,
|
|
1536
|
+
chain: pRequireContext,
|
|
1537
|
+
closestBinding: oClosestBinding,
|
|
1538
|
+
config: oConfig
|
|
1539
|
+
}).then(function() {
|
|
1435
1540
|
// apply the settings to the control
|
|
1436
1541
|
var vNewControlInstance;
|
|
1437
1542
|
var pProvider = SyncPromise.resolve();
|
|
@@ -1441,103 +1546,123 @@ function(
|
|
|
1441
1546
|
var oOwnerComponent = Component.getOwnerComponentFor(oView);
|
|
1442
1547
|
var bIsAsyncComponent = oOwnerComponent && oOwnerComponent.isA("sap.ui.core.IAsyncContentCreation");
|
|
1443
1548
|
|
|
1444
|
-
if (bEnrichFullIds
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
// If the view is owned by an async-component we can propagate the asynchronous creation behavior to the nested views
|
|
1455
|
-
if (bIsAsyncComponent && bAsync) {
|
|
1456
|
-
// legacy check: async=false is not supported with an async-component
|
|
1457
|
-
if (mSettings.async === false) {
|
|
1458
|
-
throw new Error(
|
|
1459
|
-
"A nested view contained in a Component implementing 'sap.ui.core.IAsyncContentCreation' is processed asynchronously by default and cannot be processed synchronously.\n" +
|
|
1460
|
-
"Affected Component '" + oOwnerComponent.getMetadata().getComponentName() + "' and View '" + mSettings.viewName + "'."
|
|
1461
|
-
);
|
|
1462
|
-
}
|
|
1549
|
+
if (bEnrichFullIds) {
|
|
1550
|
+
if (!bRootArea && node.hasAttribute("id")) {
|
|
1551
|
+
setId(oView, node);
|
|
1552
|
+
}
|
|
1553
|
+
} else if (!bViewRootNode && oClass.getMetadata().isA("sap.ui.core.mvc.View")) {
|
|
1554
|
+
var fnCreateViewInstance = function () {
|
|
1555
|
+
if (!oClass._sType && !mSettings.viewName) {
|
|
1556
|
+
// Add module view name
|
|
1557
|
+
mSettings.viewName = "module:" + oClass.getMetadata().getName().replace(/\./g, "/");
|
|
1558
|
+
}
|
|
1463
1559
|
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1560
|
+
// If the view is owned by an async-component we can propagate the asynchronous creation behavior to the nested views
|
|
1561
|
+
if (bIsAsyncComponent && bAsync) {
|
|
1562
|
+
// legacy check: async=false is not supported with an async-component
|
|
1563
|
+
if (mSettings.async === false) {
|
|
1564
|
+
throw new Error(
|
|
1565
|
+
"A nested view contained in a Component implementing 'sap.ui.core.IAsyncContentCreation' is processed asynchronously by default and cannot be processed synchronously.\n" +
|
|
1566
|
+
"Affected Component '" + oOwnerComponent.getMetadata().getComponentName() + "' and View '" + mSettings.viewName + "'."
|
|
1567
|
+
);
|
|
1472
1568
|
}
|
|
1473
|
-
};
|
|
1474
1569
|
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
// We need to use the already created scoped runWithOwner function from the outer view instance.
|
|
1478
|
-
// This way, the nested views are receiving the correct Owner component, across asynchronous calls.
|
|
1479
|
-
vNewControlInstance = oView.fnScopedRunWithOwner(fnCreateViewInstance);
|
|
1570
|
+
mSettings.type = oClass._sType || sType;
|
|
1571
|
+
pInstanceCreated = View.create(mSettings);
|
|
1480
1572
|
} else {
|
|
1481
|
-
|
|
1573
|
+
// Pass processingMode to nested XMLViews
|
|
1574
|
+
if (oClass.getMetadata().isA("sap.ui.core.mvc.XMLView") && oView._sProcessingMode) {
|
|
1575
|
+
mSettings.processingMode = oView._sProcessingMode;
|
|
1576
|
+
}
|
|
1577
|
+
return View._create(mSettings, undefined, oClass._sType || sType);
|
|
1482
1578
|
}
|
|
1579
|
+
};
|
|
1483
1580
|
|
|
1484
|
-
|
|
1581
|
+
// for views having a factory function defined we use the factory function!
|
|
1582
|
+
if (oView.fnScopedRunWithOwner) {
|
|
1583
|
+
// We need to use the already created scoped runWithOwner function from the outer view instance.
|
|
1584
|
+
// This way, the nested views are receiving the correct Owner component, across asynchronous calls.
|
|
1585
|
+
vNewControlInstance = oView.fnScopedRunWithOwner(fnCreateViewInstance);
|
|
1586
|
+
} else {
|
|
1587
|
+
vNewControlInstance = fnCreateViewInstance();
|
|
1588
|
+
}
|
|
1485
1589
|
|
|
1486
|
-
|
|
1487
|
-
// XML / HTML fragments: might include nested views / fragments,
|
|
1488
|
-
// which are processed asynchronously. Therefore the processingMode is needed
|
|
1489
|
-
// JS fragments: might include synchronously or asynchronously created content. Nevertheless, the execution of the
|
|
1490
|
-
// content creation is not in the scope of the xml template processor, therefore the processing mode is not needed
|
|
1491
|
-
if (sType !== ViewType.JS) {
|
|
1492
|
-
mSettings.processingMode = oView._sProcessingMode;
|
|
1493
|
-
}
|
|
1590
|
+
} else if (oClass.getMetadata().isA("sap.ui.core.Fragment") && bAsync) {
|
|
1494
1591
|
|
|
1495
|
-
|
|
1496
|
-
|
|
1592
|
+
// Pass processingMode to any fragments except JS
|
|
1593
|
+
// XML / HTML fragments: might include nested views / fragments,
|
|
1594
|
+
// which are processed asynchronously. Therefore the processingMode is needed
|
|
1595
|
+
// JS fragments: might include synchronously or asynchronously created content. Nevertheless, the execution of the
|
|
1596
|
+
// content creation is not in the scope of the xml template processor, therefore the processing mode is not needed
|
|
1597
|
+
if (sType !== ViewType.JS) {
|
|
1598
|
+
mSettings.processingMode = oView._sProcessingMode;
|
|
1599
|
+
}
|
|
1497
1600
|
|
|
1498
|
-
|
|
1499
|
-
|
|
1601
|
+
var sFragmentPath = "sap/ui/core/Fragment";
|
|
1602
|
+
var Fragment = sap.ui.require(sFragmentPath);
|
|
1500
1603
|
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
} else {
|
|
1504
|
-
pInstanceCreated = new Promise(function (resolve, reject) {
|
|
1505
|
-
sap.ui.require([sFragmentPath], function (Fragment) {
|
|
1506
|
-
Fragment.load(mSettings).then(function (oFragmentContent) {
|
|
1507
|
-
resolve(oFragmentContent);
|
|
1508
|
-
});
|
|
1509
|
-
}, reject);
|
|
1510
|
-
});
|
|
1511
|
-
}
|
|
1512
|
-
} else {
|
|
1513
|
-
// call the control constructor with the according owner in scope
|
|
1514
|
-
var fnCreateInstance = function() {
|
|
1515
|
-
var oInstance;
|
|
1516
|
-
|
|
1517
|
-
// the scoped runWithOwner function is only during ASYNC processing!
|
|
1518
|
-
if (oView.fnScopedRunWithOwner) {
|
|
1604
|
+
// call Fragment.load with mSettings.name
|
|
1605
|
+
mSettings.name = mSettings.name || mSettings.fragmentName;
|
|
1519
1606
|
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1607
|
+
if (Fragment) {
|
|
1608
|
+
pInstanceCreated = Fragment.load(mSettings);
|
|
1609
|
+
} else {
|
|
1610
|
+
pInstanceCreated = new Promise(function (resolve, reject) {
|
|
1611
|
+
sap.ui.require([sFragmentPath], function (Fragment) {
|
|
1612
|
+
Fragment.load(mSettings).then(function (oFragmentContent) {
|
|
1613
|
+
resolve(oFragmentContent);
|
|
1523
1614
|
});
|
|
1524
|
-
}
|
|
1525
|
-
|
|
1615
|
+
}, reject);
|
|
1616
|
+
});
|
|
1617
|
+
}
|
|
1618
|
+
} else {
|
|
1619
|
+
// call the control constructor with the according owner in scope
|
|
1620
|
+
var fnCreateInstance = function() {
|
|
1621
|
+
var oInstance;
|
|
1622
|
+
|
|
1623
|
+
if (bViewRootNode) {
|
|
1624
|
+
oInstance = oView;
|
|
1625
|
+
if (!bAsync) {
|
|
1626
|
+
// oParseConfig.settings: the settings object that is given to the factory method
|
|
1627
|
+
// mSettings: the settings object that contains the properties parsed from View tag
|
|
1628
|
+
//
|
|
1629
|
+
// In sync case, mSettings is applied before the oParseConfig.settings. In order to make
|
|
1630
|
+
// the mSettings win against the oParseConfig.settings, the properties that exist in
|
|
1631
|
+
// both objects are merged into the oParseConfig.settings with the value taken from
|
|
1632
|
+
// mSettings and they are then deleted from mSettings.
|
|
1633
|
+
if (oParseConfig && oParseConfig.settings) {
|
|
1634
|
+
Object.keys(mSettings).forEach(function(sKey) {
|
|
1635
|
+
if (oParseConfig.settings.hasOwnProperty(sKey)) {
|
|
1636
|
+
oParseConfig.settings[sKey] = mSettings[sKey];
|
|
1637
|
+
delete mSettings[sKey];
|
|
1638
|
+
}
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1526
1641
|
}
|
|
1642
|
+
oView.applySettings(mSettings);
|
|
1643
|
+
} else if (oView.fnScopedRunWithOwner) {
|
|
1644
|
+
// the scoped runWithOwner function is only during ASYNC processing!
|
|
1645
|
+
oInstance = oView.fnScopedRunWithOwner(function () {
|
|
1646
|
+
var oInstance = new oClass(mSettings);
|
|
1647
|
+
return oInstance;
|
|
1648
|
+
});
|
|
1649
|
+
} else {
|
|
1650
|
+
oInstance = new oClass(mSettings);
|
|
1651
|
+
}
|
|
1527
1652
|
|
|
1528
|
-
|
|
1529
|
-
|
|
1653
|
+
// check if we need to hand the ExtensionPoint info to the ExtensionProvider
|
|
1654
|
+
pProvider = fnTriggerExtensionPointProvider(bAsync, oInstance, mAggregationsWithExtensionPoints);
|
|
1530
1655
|
|
|
1531
|
-
|
|
1532
|
-
|
|
1656
|
+
return oInstance;
|
|
1657
|
+
};
|
|
1533
1658
|
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
}
|
|
1659
|
+
if (oParseConfig && oParseConfig.fnRunWithPreprocessor) {
|
|
1660
|
+
vNewControlInstance = oParseConfig.fnRunWithPreprocessor(fnCreateInstance);
|
|
1661
|
+
} else {
|
|
1662
|
+
vNewControlInstance = fnCreateInstance();
|
|
1539
1663
|
}
|
|
1540
1664
|
}
|
|
1665
|
+
|
|
1541
1666
|
return pInstanceCreated.then(function (vContent) {
|
|
1542
1667
|
return vContent || vNewControlInstance;
|
|
1543
1668
|
}).then(function (vFinalInstance) {
|
|
@@ -1665,7 +1790,7 @@ function(
|
|
|
1665
1790
|
oCtx = oBinding;
|
|
1666
1791
|
oBinding = {parts: [oCtx]};
|
|
1667
1792
|
} else {
|
|
1668
|
-
//check the text
|
|
1793
|
+
//check the text Arrangements
|
|
1669
1794
|
checkFormatter(oBinding.formatter.textFragments);
|
|
1670
1795
|
//only allow a number at the binding
|
|
1671
1796
|
}
|