neo.mjs 10.0.0-beta.4 → 10.0.0-beta.6
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/.github/RELEASE_NOTES/v10.0.0-beta.4.md +2 -2
- package/.github/RELEASE_NOTES/v10.0.0-beta.5.md +70 -0
- package/.github/RELEASE_NOTES/v10.0.0-beta.6.md +48 -0
- package/.github/epic-functional-components.md +498 -0
- package/.github/ticket-asymmetric-vdom-updates.md +122 -0
- package/README.md +0 -3
- package/ServiceWorker.mjs +2 -2
- package/apps/colors/store/Colors.mjs +1 -0
- package/apps/colors/view/GridContainer.mjs +3 -0
- package/apps/colors/view/HeaderToolbar.mjs +2 -0
- package/apps/colors/view/Viewport.mjs +3 -0
- package/apps/covid/view/FooterContainer.mjs +3 -0
- package/apps/covid/view/GalleryContainer.mjs +2 -0
- package/apps/covid/view/GalleryContainerController.mjs +1 -0
- package/apps/covid/view/HeaderContainer.mjs +2 -0
- package/apps/covid/view/HelixContainer.mjs +2 -0
- package/apps/covid/view/HelixContainerController.mjs +1 -0
- package/apps/covid/view/MainContainer.mjs +3 -0
- package/apps/covid/view/TableContainer.mjs +3 -0
- package/apps/covid/view/TableContainerController.mjs +1 -0
- package/apps/covid/view/WorldMapContainer.mjs +2 -0
- package/apps/covid/view/country/Gallery.mjs +3 -0
- package/apps/covid/view/country/Helix.mjs +8 -0
- package/apps/covid/view/country/HistoricalDataTable.mjs +1 -0
- package/apps/covid/view/country/Table.mjs +2 -0
- package/apps/covid/view/mapboxGl/Component.mjs +1 -0
- package/apps/covid/view/mapboxGl/Container.mjs +2 -0
- package/apps/email/EPIC_PLAN.md +58 -0
- package/apps/email/neo-config.json +2 -2
- package/apps/email/store/Emails.mjs +11 -1
- package/apps/email/view/ComposeView.mjs +44 -0
- package/apps/email/view/MainView.mjs +89 -0
- package/apps/email/view/Viewport.mjs +4 -33
- package/apps/email/view/ViewportStateProvider.mjs +3 -3
- package/apps/form/store/SideNav.mjs +1 -0
- package/apps/form/view/FormContainer.mjs +1 -0
- package/apps/form/view/FormPageContainer.mjs +2 -0
- package/apps/form/view/SideNavList.mjs +1 -0
- package/apps/form/view/Viewport.mjs +3 -0
- package/apps/portal/childapps/preview/MainContainer.mjs +1 -0
- package/apps/portal/index.html +1 -1
- package/apps/portal/store/BlogPosts.mjs +2 -0
- package/apps/portal/store/Content.mjs +1 -0
- package/apps/portal/store/ContentSections.mjs +1 -0
- package/apps/portal/store/Examples.mjs +1 -0
- package/apps/portal/view/HeaderToolbar.mjs +1 -0
- package/apps/portal/view/Viewport.mjs +5 -0
- package/apps/portal/view/ViewportController.mjs +8 -2
- package/apps/portal/view/about/Container.mjs +2 -0
- package/apps/portal/view/about/MemberContainer.mjs +7 -0
- package/apps/portal/view/blog/Container.mjs +2 -0
- package/apps/portal/view/blog/List.mjs +2 -0
- package/apps/portal/view/examples/List.mjs +1 -0
- package/apps/portal/view/examples/TabContainer.mjs +4 -0
- package/apps/portal/view/home/ContentBox.mjs +3 -0
- package/apps/portal/view/home/FeatureSection.mjs +8 -0
- package/apps/portal/view/home/FooterContainer.mjs +4 -1
- package/apps/portal/view/home/MainContainer.mjs +2 -0
- package/apps/portal/view/home/parts/AfterMath.mjs +2 -0
- package/apps/portal/view/home/parts/BaseContainer.mjs +1 -0
- package/apps/portal/view/home/parts/Colors.mjs +4 -0
- package/apps/portal/view/home/parts/Features.mjs +2 -0
- package/apps/portal/view/home/parts/Helix.mjs +5 -0
- package/apps/portal/view/home/parts/How.mjs +4 -0
- package/apps/portal/view/home/parts/MainNeo.mjs +1 -0
- package/apps/portal/view/home/parts/References.mjs +2 -0
- package/apps/portal/view/learn/ContentComponent.mjs +11 -5
- package/apps/portal/view/learn/ContentTreeList.mjs +2 -0
- package/apps/portal/view/learn/CubeLayoutButton.mjs +1 -0
- package/apps/portal/view/learn/MainContainer.mjs +4 -0
- package/apps/portal/view/learn/PageContainer.mjs +2 -0
- package/apps/portal/view/learn/PageSectionsContainer.mjs +3 -0
- package/apps/portal/view/learn/PageSectionsList.mjs +1 -0
- package/apps/portal/view/services/Component.mjs +1 -0
- package/apps/realworld/api/Base.mjs +1 -0
- package/apps/realworld/view/HeaderComponent.mjs +4 -0
- package/apps/realworld/view/HomeComponent.mjs +7 -0
- package/apps/realworld/view/MainContainer.mjs +2 -0
- package/apps/realworld/view/MainContainerController.mjs +2 -0
- package/apps/realworld/view/article/CommentComponent.mjs +3 -0
- package/apps/realworld/view/article/Component.mjs +17 -10
- package/apps/realworld/view/article/CreateCommentComponent.mjs +2 -0
- package/apps/realworld/view/article/CreateComponent.mjs +5 -0
- package/apps/realworld/view/article/PreviewComponent.mjs +9 -0
- package/apps/realworld/view/article/TagListComponent.mjs +2 -0
- package/apps/realworld/view/user/ProfileComponent.mjs +7 -0
- package/apps/realworld/view/user/SettingsComponent.mjs +5 -0
- package/apps/realworld/view/user/SignUpComponent.mjs +3 -0
- package/apps/realworld2/api/Base.mjs +1 -0
- package/apps/realworld2/view/FooterComponent.mjs +1 -0
- package/apps/realworld2/view/HeaderToolbar.mjs +3 -0
- package/apps/realworld2/view/HomeContainer.mjs +1 -0
- package/apps/realworld2/view/MainContainer.mjs +2 -0
- package/apps/realworld2/view/MainContainerController.mjs +1 -0
- package/apps/realworld2/view/article/Helix.mjs +1 -0
- package/apps/realworld2/view/article/PreviewComponent.mjs +9 -0
- package/apps/realworld2/view/article/PreviewList.mjs +1 -0
- package/apps/realworld2/view/article/TagListComponent.mjs +2 -0
- package/apps/route/view/CenterContainer.mjs +1 -0
- package/apps/route/view/MainView.mjs +1 -0
- package/apps/sharedcovid/childapps/sharedcovidchart/MainContainer.mjs +1 -0
- package/apps/sharedcovid/childapps/sharedcovidgallery/MainContainer.mjs +1 -0
- package/apps/sharedcovid/childapps/sharedcovidhelix/MainContainer.mjs +1 -0
- package/apps/sharedcovid/childapps/sharedcovidmap/MainContainer.mjs +1 -0
- package/apps/sharedcovid/view/FooterContainer.mjs +3 -0
- package/apps/sharedcovid/view/GalleryContainer.mjs +2 -0
- package/apps/sharedcovid/view/GalleryContainerController.mjs +1 -0
- package/apps/sharedcovid/view/HeaderContainer.mjs +2 -0
- package/apps/sharedcovid/view/HelixContainer.mjs +2 -0
- package/apps/sharedcovid/view/HelixContainerController.mjs +1 -0
- package/apps/sharedcovid/view/MainContainer.mjs +3 -0
- package/apps/sharedcovid/view/TableContainer.mjs +3 -0
- package/apps/sharedcovid/view/TableContainerController.mjs +1 -0
- package/apps/sharedcovid/view/WorldMapContainer.mjs +2 -0
- package/apps/sharedcovid/view/country/Gallery.mjs +3 -0
- package/apps/sharedcovid/view/country/Helix.mjs +8 -0
- package/apps/sharedcovid/view/country/HistoricalDataTable.mjs +1 -0
- package/apps/sharedcovid/view/country/Table.mjs +2 -0
- package/apps/sharedcovid/view/mapboxGl/Component.mjs +1 -0
- package/apps/sharedcovid/view/mapboxGl/Container.mjs +2 -0
- package/apps/shareddialog/childapps/shareddialog2/view/MainContainer.mjs +2 -0
- package/apps/shareddialog/view/DemoDialog.mjs +2 -0
- package/apps/shareddialog/view/MainContainer.mjs +2 -0
- package/apps/shareddialog/view/MainContainerController.mjs +1 -0
- package/buildScripts/addReactiveTags.mjs +191 -0
- package/buildScripts/checkReactiveTags.mjs +160 -0
- package/docs/app/store/Api.mjs +1 -0
- package/docs/app/store/Examples.mjs +1 -0
- package/docs/app/view/ApiTreeList.mjs +1 -0
- package/docs/app/view/ContentTabContainer.mjs +2 -0
- package/docs/app/view/ExamplesTreeList.mjs +2 -0
- package/docs/app/view/HeaderContainer.mjs +3 -0
- package/docs/app/view/MainContainer.mjs +5 -0
- package/docs/app/view/classdetails/HeaderComponent.mjs +1 -0
- package/docs/app/view/classdetails/MainContainer.mjs +3 -0
- package/docs/app/view/classdetails/MembersList.mjs +5 -0
- package/docs/app/view/classdetails/SourceViewComponent.mjs +2 -0
- package/examples/ConfigurationViewport.mjs +14 -8
- package/examples/button/effect/MainContainer.mjs +207 -0
- package/examples/button/effect/app.mjs +6 -0
- package/examples/button/effect/index.html +11 -0
- package/examples/button/effect/neo-config.json +6 -0
- package/examples/calendar/weekview/MainContainer.mjs +4 -0
- package/examples/component/coronaGallery/CountryGallery.mjs +2 -0
- package/examples/component/coronaGallery/CountryStore.mjs +1 -0
- package/examples/component/coronaGallery/Viewport.mjs +3 -0
- package/examples/component/coronaGallery/ViewportController.mjs +1 -0
- package/examples/component/coronaHelix/CountryHelix.mjs +7 -0
- package/examples/component/coronaHelix/MainContainer.mjs +1 -0
- package/examples/component/gallery/ImageStore.mjs +1 -0
- package/examples/component/helix/ImageStore.mjs +1 -0
- package/examples/component/helix/Viewport.mjs +3 -0
- package/examples/component/helix/ViewportController.mjs +1 -0
- package/examples/component/multiWindowCoronaGallery/childapp/Viewport.mjs +1 -0
- package/examples/component/multiWindowHelix/childapp/Viewport.mjs +1 -0
- package/examples/component/wrapper/googleMaps/MapComponent.mjs +2 -0
- package/examples/core/config/MainContainer.mjs +2 -0
- package/examples/dialog/DemoDialog.mjs +2 -0
- package/examples/dialog/MainContainer.mjs +1 -0
- package/examples/form/field/color/MainStore.mjs +1 -0
- package/examples/functional/defineComponent/Component.mjs +18 -0
- package/examples/functional/defineComponent/MainContainer.mjs +41 -0
- package/examples/functional/defineComponent/app.mjs +6 -0
- package/examples/functional/defineComponent/index.html +11 -0
- package/examples/functional/defineComponent/neo-config.json +6 -0
- package/examples/functional/hostComponent/Component.mjs +32 -0
- package/examples/functional/hostComponent/MainContainer.mjs +48 -0
- package/examples/functional/hostComponent/app.mjs +6 -0
- package/examples/functional/hostComponent/index.html +11 -0
- package/examples/functional/hostComponent/neo-config.json +6 -0
- package/examples/grid/animatedRowSorting/Viewport.mjs +1 -1
- package/examples/grid/bigData/ControlsContainer.mjs +3 -0
- package/examples/grid/bigData/GridContainer.mjs +4 -2
- package/examples/grid/bigData/MainContainer.mjs +2 -0
- package/examples/grid/bigData/MainModel.mjs +1 -0
- package/examples/grid/bigData/MainStore.mjs +3 -0
- package/examples/grid/cellEditing/MainContainer.mjs +1 -1
- package/examples/grid/container/MainContainer.mjs +1 -1
- package/examples/grid/covid/GridContainer.mjs +3 -0
- package/examples/grid/covid/MainContainer.mjs +2 -0
- package/examples/grid/covid/Store.mjs +1 -0
- package/examples/grid/nestedRecordFields/EditUserDialog.mjs +3 -0
- package/examples/grid/nestedRecordFields/Viewport.mjs +3 -1
- package/examples/list/animate/List.mjs +4 -0
- package/examples/list/animate/MainContainer.mjs +2 -0
- package/examples/list/circle/MainStore.mjs +1 -0
- package/examples/list/color/MainStore.mjs +1 -0
- package/examples/preloadingAssets/view/MainContainer.mjs +2 -0
- package/examples/stateProvider/advanced/MainContainer.mjs +1 -0
- package/examples/stateProvider/dialog/EditUserDialog.mjs +2 -0
- package/examples/stateProvider/dialog/MainContainer.mjs +1 -0
- package/examples/stateProvider/extendedClass/MainContainer.mjs +2 -0
- package/examples/stateProvider/inline/MainContainer.mjs +1 -0
- package/examples/stateProvider/inlineNoStateProvider/MainContainer.mjs +1 -0
- package/examples/stateProvider/inlineNoStateProvider/MainContainerController.mjs +2 -0
- package/examples/stateProvider/multiWindow/EditUserDialog.mjs +3 -0
- package/examples/stateProvider/multiWindow/MainContainer.mjs +1 -0
- package/examples/stateProvider/multiWindow/Viewport.mjs +1 -0
- package/examples/stateProvider/nestedData/MainContainer.mjs +1 -0
- package/examples/stateProvider/table/MainContainer.mjs +1 -0
- package/examples/table/covid/MainContainer.mjs +2 -0
- package/examples/table/covid/Store.mjs +1 -0
- package/examples/table/covid/TableContainer.mjs +3 -0
- package/examples/table/nestedRecordFields/EditUserDialog.mjs +3 -0
- package/examples/table/nestedRecordFields/Viewport.mjs +1 -0
- package/examples/todoList/version1/MainComponent.mjs +1 -1
- package/examples/toolbar/breadcrumb/view/MainContainer.mjs +2 -0
- package/examples/toolbar/paging/store/Users.mjs +1 -0
- package/examples/toolbar/paging/view/AddUserDialog.mjs +3 -0
- package/examples/toolbar/paging/view/MainContainer.mjs +3 -0
- package/examples/treeAccordion/MainContainer.mjs +2 -2
- package/examples/worker/task/MainContainer.mjs +1 -0
- package/learn/Glossary.md +1 -0
- package/learn/UsingTheseTopics.md +1 -0
- package/learn/benefits/ConfigSystem.md +2 -0
- package/learn/benefits/Effort.md +1 -0
- package/learn/benefits/Features.md +1 -0
- package/learn/benefits/FormsEngine.md +1 -0
- package/learn/benefits/FourEnvironments.md +2 -0
- package/learn/benefits/Introduction.md +2 -0
- package/learn/benefits/MultiWindow.md +3 -1
- package/learn/benefits/OffTheMainThread.md +2 -0
- package/learn/benefits/Quick.md +2 -0
- package/learn/benefits/RPCLayer.md +2 -0
- package/learn/benefits/Speed.md +2 -0
- package/learn/comparisons/NeoVsAngular.md +90 -0
- package/learn/comparisons/NeoVsExtJs.md +178 -0
- package/learn/comparisons/NeoVsNextJs.md +124 -0
- package/learn/comparisons/NeoVsReact.md +95 -0
- package/learn/comparisons/NeoVsSolid.md +78 -0
- package/learn/comparisons/NeoVsVue.md +92 -0
- package/learn/comparisons/Overview.md +46 -0
- package/learn/gettingstarted/ComponentModels.md +2 -0
- package/learn/gettingstarted/Config.md +2 -0
- package/learn/gettingstarted/DescribingTheUI.md +2 -0
- package/learn/gettingstarted/Events.md +2 -0
- package/learn/gettingstarted/Extending.md +2 -0
- package/learn/gettingstarted/References.md +2 -0
- package/learn/gettingstarted/Setup.md +3 -2
- package/learn/gettingstarted/Workspaces.md +2 -0
- package/learn/guides/datahandling/Collections.md +1 -0
- package/learn/guides/datahandling/Records.md +1 -0
- package/learn/guides/datahandling/StateProviders.md +131 -16
- package/learn/guides/datahandling/Tables.md +1 -1
- package/learn/guides/fundamentals/ConfigSystemDeepDive.md +1 -0
- package/learn/guides/fundamentals/DeclarativeComponentTreesVsImperativeVdom.md +2 -0
- package/learn/guides/fundamentals/DeclarativeVDOMWithEffects.md +168 -0
- package/learn/guides/fundamentals/ExtendingNeoClasses.md +1 -0
- package/learn/guides/fundamentals/InstanceLifecycle.md +3 -1
- package/learn/guides/fundamentals/MainThreadAddons.md +2 -0
- package/learn/guides/specificfeatures/Mixins.md +3 -1
- package/learn/guides/specificfeatures/MultiWindow.md +3 -1
- package/learn/guides/specificfeatures/PortalApp.md +2 -0
- package/learn/guides/uibuildingblocks/ComponentsAndContainers.md +2 -0
- package/learn/guides/uibuildingblocks/CustomComponents.md +2 -0
- package/learn/guides/uibuildingblocks/Layouts.md +2 -0
- package/learn/guides/uibuildingblocks/WorkingWithVDom.md +2 -0
- package/learn/guides/userinteraction/Forms.md +2 -0
- package/learn/guides/userinteraction/events/CustomEvents.md +2 -1
- package/learn/guides/userinteraction/events/DomEvents.md +2 -0
- package/learn/javascript/ClassFeatures.md +4 -3
- package/learn/javascript/Classes.md +10 -13
- package/learn/javascript/Overrides.md +10 -6
- package/learn/javascript/Super.md +12 -8
- package/learn/tree.json +71 -63
- package/learn/tutorials/Earthquakes.md +2 -0
- package/learn/tutorials/RSP.md +3 -1
- package/learn/tutorials/TodoList.md +103 -7
- package/package.json +6 -4
- package/resources/scss/src/apps/email/ComposeView.scss +16 -0
- package/resources/scss/src/apps/email/MainView.scss +5 -0
- package/resources/scss/src/apps/portal/learn/ContentComponent.scss +5 -4
- package/src/DefaultConfig.mjs +12 -2
- package/src/Main.mjs +1 -0
- package/src/Neo.mjs +377 -178
- package/src/Xhr.mjs +1 -0
- package/src/button/Base.mjs +13 -0
- package/src/button/Effect.mjs +449 -0
- package/src/button/Split.mjs +2 -0
- package/src/calendar/store/Calendars.mjs +1 -0
- package/src/calendar/store/Colors.mjs +1 -0
- package/src/calendar/store/Events.mjs +1 -0
- package/src/calendar/view/DayComponent.mjs +2 -0
- package/src/calendar/view/EditEventContainer.mjs +4 -1
- package/src/calendar/view/MainContainer.mjs +13 -0
- package/src/calendar/view/MainContainerStateProvider.mjs +14 -28
- package/src/calendar/view/SettingsContainer.mjs +1 -0
- package/src/calendar/view/YearComponent.mjs +16 -0
- package/src/calendar/view/calendars/ColorsList.mjs +2 -0
- package/src/calendar/view/calendars/Container.mjs +2 -0
- package/src/calendar/view/calendars/EditContainer.mjs +1 -0
- package/src/calendar/view/month/Component.mjs +11 -0
- package/src/calendar/view/settings/GeneralContainer.mjs +1 -0
- package/src/calendar/view/settings/MonthContainer.mjs +1 -0
- package/src/calendar/view/settings/WeekContainer.mjs +1 -0
- package/src/calendar/view/settings/YearContainer.mjs +1 -0
- package/src/calendar/view/week/Component.mjs +15 -1
- package/src/calendar/view/week/TimeAxisComponent.mjs +4 -0
- package/src/code/LivePreview.mjs +51 -23
- package/src/collection/Base.mjs +14 -12
- package/src/collection/Filter.mjs +6 -0
- package/src/collection/Sorter.mjs +3 -0
- package/src/component/Base.mjs +156 -802
- package/src/component/Canvas.mjs +1 -0
- package/src/component/Chip.mjs +4 -0
- package/src/component/Circle.mjs +14 -0
- package/src/component/Clock.mjs +4 -0
- package/src/component/DateSelector.mjs +12 -0
- package/src/component/Gallery.mjs +11 -0
- package/src/component/Helix.mjs +24 -0
- package/src/component/Label.mjs +1 -0
- package/src/component/Legend.mjs +3 -0
- package/src/component/MagicMoveText.mjs +4 -0
- package/src/component/Progress.mjs +3 -0
- package/src/component/Splitter.mjs +3 -0
- package/src/component/StatusBadge.mjs +6 -0
- package/src/component/Timer.mjs +4 -0
- package/src/component/Toast.mjs +6 -0
- package/src/component/Video.mjs +1 -0
- package/src/component/mwc/Button.mjs +7 -0
- package/src/component/mwc/TextField.mjs +9 -0
- package/src/component/wrapper/AmChart.mjs +2 -0
- package/src/component/wrapper/GoogleMaps.mjs +3 -0
- package/src/component/wrapper/MapboxGL.mjs +5 -0
- package/src/component/wrapper/MonacoEditor.mjs +12 -0
- package/src/container/Accordion.mjs +2 -0
- package/src/container/Base.mjs +34 -26
- package/src/container/Panel.mjs +1 -0
- package/src/container/Viewport.mjs +1 -0
- package/src/controller/Application.mjs +1 -0
- package/src/controller/Base.mjs +1 -0
- package/src/controller/Component.mjs +1 -0
- package/src/core/Base.mjs +193 -22
- package/src/core/Compare.mjs +4 -7
- package/src/core/Config.mjs +137 -33
- package/src/core/Effect.mjs +193 -0
- package/src/core/EffectBatchManager.mjs +67 -0
- package/src/core/EffectManager.mjs +60 -0
- package/src/core/IdGenerator.mjs +13 -44
- package/src/data/Model.mjs +2 -0
- package/src/data/Store.mjs +7 -0
- package/src/data/connection/WebSocket.mjs +2 -0
- package/src/date/DayViewComponent.mjs +2 -0
- package/src/date/SelectorContainer.mjs +14 -0
- package/src/dialog/Base.mjs +8 -0
- package/src/draggable/DragZone.mjs +5 -0
- package/src/draggable/tree/DragZone.mjs +1 -0
- package/src/filter/BooleanContainer.mjs +2 -0
- package/src/filter/NumberContainer.mjs +3 -0
- package/src/filter/ToggleOperatorsButton.mjs +2 -0
- package/src/form/Fieldset.mjs +6 -0
- package/src/form/field/Base.mjs +7 -0
- package/src/form/field/CheckBox.mjs +18 -0
- package/src/form/field/Chip.mjs +1 -0
- package/src/form/field/ComboBox.mjs +8 -0
- package/src/form/field/Country.mjs +1 -0
- package/src/form/field/Currency.mjs +2 -0
- package/src/form/field/Date.mjs +4 -0
- package/src/form/field/Display.mjs +1 -0
- package/src/form/field/Email.mjs +1 -0
- package/src/form/field/FileUpload.mjs +7 -0
- package/src/form/field/Hidden.mjs +1 -0
- package/src/form/field/Number.mjs +7 -0
- package/src/form/field/Password.mjs +1 -0
- package/src/form/field/Phone.mjs +3 -0
- package/src/form/field/Picker.mjs +2 -0
- package/src/form/field/Radio.mjs +1 -0
- package/src/form/field/Range.mjs +3 -0
- package/src/form/field/Search.mjs +2 -0
- package/src/form/field/Text.mjs +32 -0
- package/src/form/field/TextArea.mjs +7 -0
- package/src/form/field/Time.mjs +6 -0
- package/src/form/field/Url.mjs +3 -0
- package/src/form/field/ZipCode.mjs +2 -0
- package/src/form/field/trigger/Base.mjs +3 -0
- package/src/form/field/trigger/Clear.mjs +2 -0
- package/src/form/field/trigger/CopyToClipboard.mjs +2 -0
- package/src/form/field/trigger/Date.mjs +1 -0
- package/src/form/field/trigger/Picker.mjs +1 -0
- package/src/form/field/trigger/Search.mjs +1 -0
- package/src/form/field/trigger/SpinDown.mjs +2 -0
- package/src/form/field/trigger/SpinUp.mjs +1 -0
- package/src/form/field/trigger/Time.mjs +2 -0
- package/src/functional/_export.mjs +6 -0
- package/src/functional/component/Base.mjs +499 -0
- package/src/functional/defineComponent.mjs +102 -0
- package/src/functional/useConfig.mjs +52 -0
- package/src/functional/useEvent.mjs +43 -0
- package/src/grid/Body.mjs +20 -1
- package/src/grid/Container.mjs +57 -63
- package/src/grid/ScrollManager.mjs +2 -0
- package/src/grid/VerticalScrollbar.mjs +2 -0
- package/src/grid/column/Base.mjs +2 -0
- package/src/grid/column/Component.mjs +1 -1
- package/src/grid/header/Button.mjs +7 -0
- package/src/grid/header/Toolbar.mjs +6 -0
- package/src/grid/plugin/AnimateRows.mjs +2 -0
- package/src/layout/Base.mjs +3 -0
- package/src/layout/Card.mjs +1 -0
- package/src/layout/Cube.mjs +11 -1
- package/src/layout/Fit.mjs +1 -0
- package/src/layout/Flexbox.mjs +7 -0
- package/src/layout/Form.mjs +2 -0
- package/src/layout/Grid.mjs +1 -0
- package/src/layout/HBox.mjs +1 -0
- package/src/layout/VBox.mjs +1 -0
- package/src/list/Base.mjs +13 -0
- package/src/list/Chip.mjs +1 -0
- package/src/list/Circle.mjs +2 -0
- package/src/list/Color.mjs +1 -0
- package/src/list/plugin/Animate.mjs +2 -0
- package/src/main/DeltaUpdates.mjs +1 -0
- package/src/main/DomEvents.mjs +2 -0
- package/src/main/addon/CloneNode.mjs +1 -0
- package/src/main/addon/Cookie.mjs +1 -0
- package/src/main/addon/GoogleMaps.mjs +1 -0
- package/src/main/addon/LocalStorage.mjs +1 -0
- package/src/main/addon/MapboxGL.mjs +1 -0
- package/src/main/addon/Markdown.mjs +1 -0
- package/src/main/addon/Navigator.mjs +1 -0
- package/src/main/addon/Popover.mjs +1 -0
- package/src/main/addon/Stylesheet.mjs +1 -0
- package/src/main/addon/WindowPosition.mjs +1 -0
- package/src/manager/Component.mjs +0 -71
- package/src/manager/VDomUpdate.mjs +235 -0
- package/src/menu/List.mjs +6 -0
- package/src/menu/Model.mjs +1 -0
- package/src/menu/Panel.mjs +3 -0
- package/src/menu/Store.mjs +1 -0
- package/src/mixin/DomEvents.mjs +130 -0
- package/src/mixin/VdomLifecycle.mjs +667 -0
- package/src/plugin/Base.mjs +1 -0
- package/src/plugin/Resizable.mjs +2 -0
- package/src/selection/Model.mjs +15 -18
- package/src/selection/grid/BaseModel.mjs +1 -0
- package/src/sitemap/Component.mjs +1 -0
- package/src/state/Provider.mjs +376 -457
- package/src/state/createHierarchicalDataProxy.mjs +138 -0
- package/src/tab/Container.mjs +6 -0
- package/src/tab/Strip.mjs +1 -0
- package/src/tab/header/Button.mjs +2 -0
- package/src/tab/header/EffectButton.mjs +77 -0
- package/src/tab/header/Toolbar.mjs +1 -0
- package/src/table/Body.mjs +3 -0
- package/src/table/Container.mjs +10 -0
- package/src/table/header/Button.mjs +8 -0
- package/src/table/header/Toolbar.mjs +5 -0
- package/src/table/plugin/CellEditing.mjs +1 -0
- package/src/toolbar/Base.mjs +4 -0
- package/src/toolbar/Breadcrumb.mjs +3 -0
- package/src/toolbar/Paging.mjs +5 -0
- package/src/tooltip/Base.mjs +2 -0
- package/src/tree/List.mjs +3 -0
- package/src/util/HashHistory.mjs +1 -0
- package/src/util/KeyNavigation.mjs +2 -0
- package/src/util/Matrix.mjs +1 -0
- package/src/util/VDom.mjs +7 -1
- package/src/util/VNode.mjs +7 -1
- package/src/util/vdom/TreeBuilder.mjs +129 -0
- package/src/vdom/Helper.mjs +44 -33
- package/src/vdom/VNode.mjs +5 -7
- package/src/worker/App.mjs +1 -5
- package/src/worker/Base.mjs +2 -0
- package/src/worker/Manager.mjs +2 -0
- package/src/worker/ServiceBase.mjs +6 -1
- package/test/siesta/siesta.js +36 -1
- package/test/siesta/tests/CollectionBase.mjs +10 -10
- package/test/siesta/tests/VdomCalendar.mjs +13 -9
- package/test/siesta/tests/VdomHelper.mjs +22 -59
- package/test/siesta/tests/config/AfterSetConfig.mjs +100 -0
- package/test/siesta/tests/{ReactiveConfigs.mjs → config/Basic.mjs} +58 -21
- package/test/siesta/tests/config/CircularDependencies.mjs +166 -0
- package/test/siesta/tests/config/CustomFunctions.mjs +69 -0
- package/test/siesta/tests/config/Hierarchy.mjs +94 -0
- package/test/siesta/tests/config/MemoryLeak.mjs +92 -0
- package/test/siesta/tests/config/MultiLevelHierarchy.mjs +85 -0
- package/test/siesta/tests/core/Effect.mjs +127 -0
- package/test/siesta/tests/core/EffectBatching.mjs +310 -0
- package/test/siesta/tests/neo/MixinStaticConfig.mjs +138 -0
- package/test/siesta/tests/state/Provider.mjs +537 -0
- package/test/siesta/tests/state/ProviderNestedDataConfigs.mjs +255 -0
- package/test/siesta/tests/state/createHierarchicalDataProxy.mjs +204 -0
- package/test/siesta/tests/vdom/VdomAsymmetricUpdates.mjs +366 -0
- package/test/siesta/tests/vdom/VdomRealWorldUpdates.mjs +249 -0
- package/learn/javascript/NewNode.md +0 -31
package/src/component/Base.mjs
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
import Base from '../core/Base.mjs';
|
2
2
|
import ClassSystemUtil from '../util/ClassSystem.mjs';
|
3
3
|
import ComponentManager from '../manager/Component.mjs';
|
4
|
-
import
|
4
|
+
import DomEvents from '../mixin/DomEvents.mjs';
|
5
5
|
import KeyNavigation from '../util/KeyNavigation.mjs';
|
6
6
|
import Logger from '../util/Logger.mjs';
|
7
7
|
import NeoArray from '../util/Array.mjs';
|
8
8
|
import Observable from '../core/Observable.mjs';
|
9
9
|
import Rectangle from '../util/Rectangle.mjs';
|
10
10
|
import Style from '../util/Style.mjs';
|
11
|
+
import VdomLifecycle from '../mixin/VdomLifecycle.mjs';
|
11
12
|
import VDomUtil from '../util/VDom.mjs';
|
12
13
|
import VNodeUtil from '../util/VNode.mjs';
|
13
14
|
import {isDescriptor} from '../core/ConfigSymbols.mjs';
|
@@ -24,6 +25,9 @@ const
|
|
24
25
|
* Base class for all Components which have a DOM representation
|
25
26
|
* @class Neo.component.Base
|
26
27
|
* @extends Neo.core.Base
|
28
|
+
* @mixes Neo.component.mixin.DomEvents
|
29
|
+
* @mixes Neo.core.Observable
|
30
|
+
* @mixes Neo.component.mixin.VdomLifecycle
|
27
31
|
*/
|
28
32
|
class Component extends Base {
|
29
33
|
/**
|
@@ -33,12 +37,6 @@ class Component extends Base {
|
|
33
37
|
* @static
|
34
38
|
*/
|
35
39
|
static hideModes = ['removeDom', 'visibility']
|
36
|
-
/**
|
37
|
-
* True automatically applies the core.Observable mixin
|
38
|
-
* @member {Boolean} observable=true
|
39
|
-
* @static
|
40
|
-
*/
|
41
|
-
static observable = true
|
42
40
|
|
43
41
|
static config = {
|
44
42
|
/**
|
@@ -54,32 +52,23 @@ class Component extends Base {
|
|
54
52
|
/**
|
55
53
|
* The default alignment specification to position this Component relative to some other
|
56
54
|
* Component, or Element or Rectangle. Only applies in case floating = true.
|
57
|
-
* @member {Object|String} align_={edgeAlign:'t-b',constrainTo:'document.body'}
|
55
|
+
* @member {Object|String} align_={[isDescriptor]: true, merge: 'deep', value: {edgeAlign: 't-b',constrainTo: 'document.body'}}
|
56
|
+
* @reactive
|
58
57
|
*/
|
59
58
|
align_: {
|
60
|
-
|
61
|
-
|
59
|
+
[isDescriptor]: true,
|
60
|
+
merge : 'deep',
|
61
|
+
value: {
|
62
|
+
edgeAlign : 't-b',
|
63
|
+
constrainTo: 'document.body'
|
64
|
+
}
|
62
65
|
},
|
63
66
|
/**
|
64
67
|
* The name of the App this component belongs to
|
65
68
|
* @member {String|null} appName_=null
|
69
|
+
* @reactive
|
66
70
|
*/
|
67
71
|
appName_: null,
|
68
|
-
/**
|
69
|
-
* True automatically mounts a component after being rendered.
|
70
|
-
* Use this for the top level component of your app.
|
71
|
-
* @member {Boolean} autoMount=false
|
72
|
-
* @tutorial 02_ClassSystem
|
73
|
-
*/
|
74
|
-
autoMount: false,
|
75
|
-
/**
|
76
|
-
* True automatically renders a component after being created inside the init call.
|
77
|
-
* Use this for the top level component of your app.
|
78
|
-
* @member {Boolean} autoRender=false
|
79
|
-
* @see {@link Neo.component.Base#init init}
|
80
|
-
* @tutorial 02_ClassSystem
|
81
|
-
*/
|
82
|
-
autoRender: false,
|
83
72
|
/**
|
84
73
|
* CSS selectors to apply to the root level node of this component
|
85
74
|
* @member {String[]} baseCls=[]
|
@@ -101,17 +90,20 @@ class Component extends Base {
|
|
101
90
|
* Custom CSS selectors to apply to the root level node of this component
|
102
91
|
* You can override baseCls to remove default selectors.
|
103
92
|
* @member {String[]} cls_=null
|
93
|
+
* @reactive
|
104
94
|
*/
|
105
95
|
cls_: null,
|
106
96
|
/**
|
107
97
|
* manager.Focus will change this flag on focusin & out dom events
|
108
98
|
* @member {Boolean} containsFocus_=false
|
109
99
|
* @protected
|
100
|
+
* @reactive
|
110
101
|
*/
|
111
102
|
containsFocus_: false,
|
112
103
|
/**
|
113
104
|
* Assign a component controller to this component (pass an imported module or the string based class name)
|
114
105
|
* @member {Neo.controller.Component|String} controller_=null
|
106
|
+
* @reactive
|
115
107
|
*/
|
116
108
|
controller_: null,
|
117
109
|
/**
|
@@ -119,32 +111,19 @@ class Component extends Base {
|
|
119
111
|
* Read only.
|
120
112
|
* @member {Object} data_=null
|
121
113
|
* @protected
|
114
|
+
* @reactive
|
122
115
|
*/
|
123
116
|
data_: null,
|
124
117
|
/**
|
125
118
|
* Disabled components will get the neo-disabled cls applied and won't receive DOM events
|
126
119
|
* @member {Boolean} disabled_=false
|
120
|
+
* @reactive
|
127
121
|
*/
|
128
122
|
disabled_: false,
|
129
|
-
/**
|
130
|
-
* An array of domListener configs
|
131
|
-
* @member {Object[]|null} domListeners_=null
|
132
|
-
* @example
|
133
|
-
* afterSetStayOnHover(value, oldValue) {
|
134
|
-
* if (value) {
|
135
|
-
* let me = this;
|
136
|
-
*
|
137
|
-
* me.addDomListeners(
|
138
|
-
* {mouseenter: me.onMouseEnter, scope: me},
|
139
|
-
* {mouseleave: me.onMouseLeave, scope: me}
|
140
|
-
* )
|
141
|
-
* }
|
142
|
-
*}
|
143
|
-
*/
|
144
|
-
domListeners_: null,
|
145
123
|
/**
|
146
124
|
* Set this config to true to dynamically import a DropZone module & create an instance
|
147
125
|
* @member {Boolean} droppable_=false
|
126
|
+
* @reactive
|
148
127
|
*/
|
149
128
|
droppable_: false,
|
150
129
|
/**
|
@@ -166,39 +145,30 @@ class Component extends Base {
|
|
166
145
|
* @protected
|
167
146
|
*/
|
168
147
|
hasBeenMounted: false,
|
169
|
-
/**
|
170
|
-
* Internal flag
|
171
|
-
* @member {Boolean} hasRenderingListener=false
|
172
|
-
* @protected
|
173
|
-
*/
|
174
|
-
hasRenderingListener: false,
|
175
|
-
/**
|
176
|
-
* Internal flag for vdom changes after a component got unmounted
|
177
|
-
* (delta updates can no longer get applied & a new render call is required before re-mounting)
|
178
|
-
* @member {Boolean} hasUnmountedVdomChanges_=false
|
179
|
-
* @protected
|
180
|
-
*/
|
181
|
-
hasUnmountedVdomChanges_: false,
|
182
148
|
/**
|
183
149
|
* Shortcut for style.height, defaults to px
|
184
150
|
* @member {Number|String|null} height_=null
|
151
|
+
* @reactive
|
185
152
|
*/
|
186
153
|
height_: null,
|
187
154
|
/**
|
188
155
|
* Initial setting to hide or show the component and
|
189
156
|
* you can use either hide()/show() or change this config directly to change the hidden state
|
190
157
|
* @member {Boolean} hidden_=false
|
158
|
+
* @reactive
|
191
159
|
*/
|
192
160
|
hidden_: false,
|
193
161
|
/**
|
194
162
|
* Used for hide and show and defines if the component
|
195
163
|
* should use css visibility:'hidden' or vdom:removeDom
|
196
164
|
* @member {String} hideMode_='removeDom'
|
165
|
+
* @reactive
|
197
166
|
*/
|
198
167
|
hideMode_: 'removeDom',
|
199
168
|
/**
|
200
169
|
* The top level innerHTML of the component
|
201
170
|
* @member {String|null} html_=null
|
171
|
+
* @reactive
|
202
172
|
*/
|
203
173
|
html_: null,
|
204
174
|
/**
|
@@ -207,78 +177,73 @@ class Component extends Base {
|
|
207
177
|
* @member {Boolean|String} isLoading=false
|
208
178
|
*/
|
209
179
|
isLoading_: false,
|
210
|
-
/**
|
211
|
-
* Internal flag which will get set to true while an update request (worker messages) is in progress
|
212
|
-
* @member {Boolean} isVdomUpdating_=false
|
213
|
-
* @protected
|
214
|
-
*/
|
215
|
-
isVdomUpdating_: false,
|
216
180
|
/**
|
217
181
|
* Using the keys config will create an instance of Neo.util.KeyNavigation.
|
218
182
|
* @see {@link Neo.util.KeyNavigation KeyNavigation}
|
219
183
|
* @member {Object} keys_=null
|
184
|
+
* @reactive
|
220
185
|
*/
|
221
186
|
keys_: null,
|
222
187
|
/**
|
223
188
|
* Gets used inside afterSetIsLoading() to define the CSS for the loading spinner icon
|
224
189
|
* @member {String[]} loadingSpinnerCls_=['fa','fa-spinner','fa-spin']
|
190
|
+
* @reactive
|
225
191
|
*/
|
226
192
|
loadingSpinnerCls_: ['fa', 'fa-spinner', 'fa-spin'],
|
227
193
|
/**
|
228
194
|
* Shortcut for style.maxHeight, defaults to px
|
229
195
|
* @member {Number|String|null} maxHeight_=null
|
196
|
+
* @reactive
|
230
197
|
*/
|
231
198
|
maxHeight_: null,
|
232
199
|
/**
|
233
200
|
* Shortcut for style.maxWidth, defaults to px
|
234
201
|
* @member {Number|String|null} maxWidth_=null
|
202
|
+
* @reactive
|
235
203
|
*/
|
236
204
|
maxWidth_: null,
|
237
205
|
/**
|
238
206
|
* Shortcut for style.minHeight, defaults to px
|
239
207
|
* @member {Number|String|null} minHeight_=null
|
208
|
+
* @reactive
|
240
209
|
*/
|
241
210
|
minHeight_: null,
|
242
211
|
/**
|
243
212
|
* Shortcut for style.minWidth, defaults to px
|
244
213
|
* @member {Number|String|null} minWidth_=null
|
214
|
+
* @reactive
|
245
215
|
*/
|
246
216
|
minWidth_: null,
|
217
|
+
/**
|
218
|
+
* @member {Neo.core.Base[]} mixins=[DomEvents, Observable, VdomLifecycle]
|
219
|
+
*/
|
220
|
+
mixins: [DomEvents, Observable, VdomLifecycle],
|
247
221
|
/**
|
248
222
|
* Override specific stateProvider data properties.
|
249
223
|
* This will merge the content.
|
250
224
|
* @member {Object|null} modelData=null
|
251
225
|
*/
|
252
226
|
modelData: null,
|
253
|
-
/**
|
254
|
-
* True in case the component is mounted to the DOM
|
255
|
-
* @member {Boolean} mounted_=false
|
256
|
-
* @protected
|
257
|
-
*/
|
258
|
-
mounted_: false,
|
259
|
-
/**
|
260
|
-
* Internal flag which will get set to true in case an update call arrives while another update is running
|
261
|
-
* @member {Boolean} needsVdomUpdate_=false
|
262
|
-
* @protected
|
263
|
-
*/
|
264
|
-
needsVdomUpdate_: false,
|
265
227
|
/**
|
266
228
|
* If the parentId does not match a neo component id, you can manually set this value for finding
|
267
229
|
* view controllers or state providers.
|
268
230
|
* Use case: manually dropping components into a vdom structure
|
269
231
|
* @member {Neo.component.Base|null} parentComponent_=null
|
270
232
|
* @protected
|
233
|
+
* @reactive
|
271
234
|
*/
|
272
235
|
parentComponent_: null,
|
273
236
|
/**
|
274
237
|
* The parent component id or document.body
|
275
238
|
* @member {String} parentId_='document.body'
|
239
|
+
* @reactive
|
276
240
|
*/
|
277
241
|
parentId_: 'document.body',
|
278
242
|
/**
|
279
243
|
* Array of Plugin Modules and / or config objects
|
280
244
|
* @member {Array|null} plugins_=null
|
281
245
|
* @protected
|
246
|
+
* @reactive
|
282
247
|
*/
|
283
248
|
plugins_: null,
|
284
249
|
/**
|
@@ -286,6 +251,7 @@ class Component extends Base {
|
|
286
251
|
* References will also get mapped into the vdom root (data-ref: value).
|
287
252
|
* @member {String|null} reference_=null
|
288
253
|
* @protected
|
254
|
+
* @reactive
|
289
255
|
*/
|
290
256
|
reference_: null,
|
291
257
|
/**
|
@@ -295,16 +261,11 @@ class Component extends Base {
|
|
295
261
|
* @protected
|
296
262
|
*/
|
297
263
|
responsive_: null,
|
298
|
-
/**
|
299
|
-
* True in case the component is rendering the vnode
|
300
|
-
* @member {Boolean} rendering_=false
|
301
|
-
* @protected
|
302
|
-
*/
|
303
|
-
rendering_: false,
|
304
264
|
/**
|
305
265
|
* Specify a role tag attribute for the vdom root.
|
306
266
|
* See: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles
|
307
267
|
* @member {String|null} role_=null
|
268
|
+
* @reactive
|
308
269
|
*/
|
309
270
|
role_: null,
|
310
271
|
/**
|
@@ -312,28 +273,29 @@ class Component extends Base {
|
|
312
273
|
* Set this to 'x' or 'y' to add style 'overflow-x' or 'overflow-y' to 'auto'
|
313
274
|
* Other than false this will add cls 'neo-scrollable'.
|
314
275
|
* @member {Boolean|"x"|"y"} scrollable_=false
|
276
|
+
* @reactive
|
315
277
|
*/
|
316
278
|
scrollable_: false,
|
317
|
-
/**
|
318
|
-
* Set this to true for bulk updates. Ensure to set it back to false afterwards.
|
319
|
-
* Internally the value will get saved as a number to ensure that child methods won't stop the silent mode too early.
|
320
|
-
* @member {Boolean} silentVdomUpdate_=false
|
321
|
-
*/
|
322
|
-
silentVdomUpdate_: false,
|
323
279
|
/**
|
324
280
|
* Optionally add a state.Provider to share state data with child components
|
325
281
|
* @member {Object|null} stateProvider_=null
|
282
|
+
* @reactive
|
326
283
|
*/
|
327
284
|
stateProvider_: null,
|
328
285
|
/**
|
329
286
|
* Style attributes added to this vdom root. see: getVdomRoot()
|
330
|
-
* @member {Object}
|
287
|
+
* @member {Object} style={[isDescriptor]: true, merge: 'shallow', value: null}
|
331
288
|
*/
|
332
|
-
style_:
|
289
|
+
style_: {
|
290
|
+
[isDescriptor]: true,
|
291
|
+
merge : 'shallow',
|
292
|
+
value : null
|
293
|
+
},
|
333
294
|
/**
|
334
295
|
* You can pass a used theme directly to any component,
|
335
296
|
* to style specific component trees differently from your main view.
|
336
297
|
* @member {String|null} theme_=null
|
298
|
+
* @reactive
|
337
299
|
*/
|
338
300
|
theme_: null,
|
339
301
|
/**
|
@@ -341,11 +303,13 @@ class Component extends Base {
|
|
341
303
|
* this shortcut enables us to change the vdom root tag on instance level.
|
342
304
|
* Use cases: switch a Toolbar to a "nav" tag, switch a SideNav to an "aside" tag.
|
343
305
|
* @member {String|null} tag_=null
|
306
|
+
* @reactive
|
344
307
|
*/
|
345
308
|
tag_: null,
|
346
309
|
/**
|
347
310
|
* The top level textContent of the component
|
348
311
|
* @member {String|null} text_=null
|
312
|
+
* @reactive
|
349
313
|
*/
|
350
314
|
text_: null,
|
351
315
|
/**
|
@@ -358,51 +322,42 @@ class Component extends Base {
|
|
358
322
|
* If a widget needs its own instance for any reason, inslude the property `ownInstance : true`
|
359
323
|
* in the tooltip config object.
|
360
324
|
* @member {Object|String} tooltip_=null
|
325
|
+
* @reactive
|
361
326
|
*/
|
362
327
|
tooltip_: null,
|
363
328
|
/**
|
364
329
|
* Add 'primary' and other attributes to make it an outstanding design
|
365
330
|
* @member {String|null} ui_=null
|
331
|
+
* @reactive
|
366
332
|
*/
|
367
333
|
ui_: null,
|
368
|
-
/**
|
369
|
-
* Defines the depth of the vdom tree for the next update cycle.
|
370
|
-
* - The value 1 will only send the current vdom structure as it is
|
371
|
-
* - The value of 2 will include the vdom of direct children
|
372
|
-
* - The value of 3 will include the vdom of grandchildren
|
373
|
-
* - The value of -1 will include the full tree of any depth
|
374
|
-
* @member {Number} updateDepth_=1
|
375
|
-
*/
|
376
|
-
updateDepth_: 1,
|
377
|
-
/**
|
378
|
-
* The component vnode tree. Available after the component got rendered.
|
379
|
-
* @member {Object} vnode_=null
|
380
|
-
* @protected
|
381
|
-
*/
|
382
|
-
vnode_: {
|
383
|
-
[isDescriptor]: true,
|
384
|
-
value : null,
|
385
|
-
isEqual : (a, b) => a === b // vnode trees can be huge, and will get compared by the vdom worker.
|
386
|
-
},
|
387
334
|
/**
|
388
335
|
* Shortcut for style.width, defaults to px
|
389
336
|
* @member {Number|String|null} width_=null
|
337
|
+
* @reactive
|
390
338
|
*/
|
391
339
|
width_: null,
|
392
340
|
/**
|
393
341
|
* The custom windowIs (timestamp) this component belongs to
|
394
342
|
* @member {Number|null} windowId_=null
|
343
|
+
* @reactive
|
395
344
|
*/
|
396
345
|
windowId_: null,
|
397
346
|
/**
|
398
347
|
* @member {String[]|null} wrapperCls_=null
|
348
|
+
* @reactive
|
399
349
|
*/
|
400
350
|
wrapperCls_: null,
|
401
351
|
/**
|
402
352
|
* Top level style attributes. Useful in case getVdomRoot() does not point to the top level DOM node.
|
403
|
-
* @member {Object|null} wrapperStyle_=null
|
353
|
+
* @member {Object|null} wrapperStyle_={[isDescriptor]: true, merge: 'shallow', value: null}
|
354
|
+
* @reactive
|
404
355
|
*/
|
405
|
-
wrapperStyle_:
|
356
|
+
wrapperStyle_: {
|
357
|
+
[isDescriptor]: true,
|
358
|
+
merge : 'shallow',
|
359
|
+
value : null
|
360
|
+
},
|
406
361
|
/**
|
407
362
|
* The vdom markup for this component.
|
408
363
|
* @member {Object} _vdom={}
|
@@ -411,21 +366,11 @@ class Component extends Base {
|
|
411
366
|
}
|
412
367
|
|
413
368
|
/**
|
414
|
-
*
|
415
|
-
*
|
416
|
-
*
|
417
|
-
* @member {Object} childUpdateCache={}
|
418
|
-
*/
|
419
|
-
childUpdateCache = {}
|
420
|
-
/**
|
421
|
-
* Stores the updateDepth while an update is running to enable checks for parent update collisions
|
422
|
-
* @member {Number|null} currentUpdateDepth=null
|
423
|
-
*/
|
424
|
-
currentUpdateDepth = null
|
425
|
-
/**
|
426
|
-
* @member {Function[]} resolveUpdateCache=[]
|
369
|
+
* Internal flag which will get set to true while a component is waiting for its mountedPromise
|
370
|
+
* @member {Boolean} isAwaitingMount=false
|
371
|
+
* @protected
|
427
372
|
*/
|
428
|
-
|
373
|
+
isAwaitingMount = false
|
429
374
|
|
430
375
|
/**
|
431
376
|
* Convenience shortcut to access the App this component belongs to
|
@@ -453,6 +398,33 @@ class Component extends Base {
|
|
453
398
|
this._listeners = value
|
454
399
|
}
|
455
400
|
|
401
|
+
/**
|
402
|
+
* A Promise that resolves when the component is mounted to the DOM.
|
403
|
+
* This provides a convenient way to wait for the component to be fully
|
404
|
+
* available and interactive before executing subsequent logic.
|
405
|
+
*
|
406
|
+
* It also handles unmounting by resetting the promise, so it can be safely
|
407
|
+
* awaited again if the component is remounted.
|
408
|
+
* @returns {Promise<Neo.component.Base>}
|
409
|
+
*/
|
410
|
+
get mountedPromise() {
|
411
|
+
let me = this;
|
412
|
+
|
413
|
+
if (!me._mountedPromise) {
|
414
|
+
me._mountedPromise = new Promise(resolve => {
|
415
|
+
if (me.mounted) {
|
416
|
+
// If already mounted, resolve immediately.
|
417
|
+
resolve(me)
|
418
|
+
} else {
|
419
|
+
// Otherwise, store the resolver to be called by afterSetMounted.
|
420
|
+
me.mountedPromiseResolve = resolve
|
421
|
+
}
|
422
|
+
})
|
423
|
+
}
|
424
|
+
|
425
|
+
return this._mountedPromise
|
426
|
+
}
|
427
|
+
|
456
428
|
/**
|
457
429
|
* Convenience method to access the parent component
|
458
430
|
* @returns {Neo.component.Base|null}
|
@@ -503,21 +475,7 @@ class Component extends Base {
|
|
503
475
|
this.cls = cls
|
504
476
|
}
|
505
477
|
|
506
|
-
/**
|
507
|
-
* Convenience shortcut to add additional dom listeners
|
508
|
-
* @param {Object|Object[]} value
|
509
|
-
*/
|
510
|
-
addDomListeners(value) {
|
511
|
-
if (!Array.isArray(value)) {
|
512
|
-
value = [value]
|
513
|
-
}
|
514
|
-
|
515
|
-
let domListeners = this.domListeners;
|
516
|
-
|
517
|
-
domListeners.push(...value);
|
518
478
|
|
519
|
-
this.domListeners = domListeners
|
520
|
-
}
|
521
479
|
|
522
480
|
/**
|
523
481
|
* Either a string like 'color: red; background-color: blue;'
|
@@ -593,7 +551,12 @@ class Component extends Base {
|
|
593
551
|
afterSetConfig(key, value, oldValue) {
|
594
552
|
let me = this;
|
595
553
|
|
596
|
-
if (
|
554
|
+
if (Neo.isUsingStateProviders && me[twoWayBindingSymbol]) {
|
555
|
+
// When a component config is updated by its state provider, this flag is set to the config's key.
|
556
|
+
// This prevents circular updates in two-way data bindings by skipping the push back to the state provider.
|
557
|
+
if (me._skipTwoWayPush === key) {
|
558
|
+
return;
|
559
|
+
}
|
597
560
|
let binding = me.bind?.[key];
|
598
561
|
|
599
562
|
if (binding?.twoWay) {
|
@@ -615,19 +578,7 @@ class Component extends Base {
|
|
615
578
|
this.cls = cls
|
616
579
|
}
|
617
580
|
|
618
|
-
/**
|
619
|
-
* Registers the domListeners inside the Neo.manager.DomEvent
|
620
|
-
* @param {Object[]} value
|
621
|
-
* @param {Object[]} oldValue
|
622
|
-
* @protected
|
623
|
-
*/
|
624
|
-
afterSetDomListeners(value, oldValue) {
|
625
|
-
let me = this;
|
626
581
|
|
627
|
-
if (value?.[0] || oldValue?.[0]) {
|
628
|
-
DomEventManager.updateDomListeners(me, value, oldValue)
|
629
|
-
}
|
630
|
-
}
|
631
582
|
|
632
583
|
/**
|
633
584
|
* Triggered after the droppable config got changed
|
@@ -651,29 +602,6 @@ class Component extends Base {
|
|
651
602
|
}
|
652
603
|
}
|
653
604
|
|
654
|
-
/**
|
655
|
-
* Triggered after the hasUnmountedVdomChanges config got changed
|
656
|
-
* @param {Boolean} value
|
657
|
-
* @param {Boolean} oldValue
|
658
|
-
* @protected
|
659
|
-
*/
|
660
|
-
afterSetHasUnmountedVdomChanges(value, oldValue) {
|
661
|
-
if (value || (!value && oldValue)) {
|
662
|
-
let parentIds = ComponentManager.getParentIds(this),
|
663
|
-
i = 0,
|
664
|
-
len = parentIds.length,
|
665
|
-
parent;
|
666
|
-
|
667
|
-
for (; i < len; i++) {
|
668
|
-
parent = Neo.getComponent(parentIds[i]);
|
669
|
-
|
670
|
-
if (parent) {
|
671
|
-
parent._hasUnmountedVdomChanges = value // silent update
|
672
|
-
}
|
673
|
-
}
|
674
|
-
}
|
675
|
-
}
|
676
|
-
|
677
605
|
/**
|
678
606
|
* Triggered after the height config got changed
|
679
607
|
* @param {Number|String|null} value
|
@@ -767,16 +695,6 @@ class Component extends Base {
|
|
767
695
|
}
|
768
696
|
}
|
769
697
|
|
770
|
-
/**
|
771
|
-
* Triggered after the isVdomUpdating config got changed
|
772
|
-
* @param {Number|null} value
|
773
|
-
* @param {Number|null} oldValue
|
774
|
-
* @protected
|
775
|
-
*/
|
776
|
-
afterSetIsVdomUpdating(value, oldValue) {
|
777
|
-
this.currentUpdateDepth = value ? this.updateDepth : null
|
778
|
-
}
|
779
|
-
|
780
698
|
/**
|
781
699
|
* Triggered after the maxHeight config got changed
|
782
700
|
* @param {Number|String|null} value
|
@@ -832,17 +750,10 @@ class Component extends Base {
|
|
832
750
|
let me = this,
|
833
751
|
{id, windowId} = me;
|
834
752
|
|
835
|
-
if (value) {
|
753
|
+
if (value) { // mount
|
836
754
|
me.hasBeenMounted = true;
|
837
755
|
|
838
|
-
|
839
|
-
// todo: the main thread reply of mount arrives after pushing the task into the queue which does not ensure the dom is mounted
|
840
|
-
me.timeout(150).then(() => {
|
841
|
-
DomEventManager.mountDomListeners(me)
|
842
|
-
})
|
843
|
-
}
|
844
|
-
|
845
|
-
me.doResolveUpdateCache();
|
756
|
+
me.initDomEvents();
|
846
757
|
|
847
758
|
if (me.floating) {
|
848
759
|
me.alignTo();
|
@@ -851,9 +762,15 @@ class Component extends Base {
|
|
851
762
|
me.focus(id, true)
|
852
763
|
}
|
853
764
|
|
854
|
-
me.
|
855
|
-
|
856
|
-
|
765
|
+
me.mountedPromiseResolve?.(this);
|
766
|
+
delete me.mountedPromiseResolve;
|
767
|
+
|
768
|
+
me.fire('mounted', me.id);
|
769
|
+
} else { // unmount
|
770
|
+
me.revertFocus();
|
771
|
+
|
772
|
+
// The promise needs to get reset, in case the component gets remounted.
|
773
|
+
delete me._mountedPromise;
|
857
774
|
}
|
858
775
|
}
|
859
776
|
}
|
@@ -939,6 +856,16 @@ class Component extends Base {
|
|
939
856
|
}
|
940
857
|
}
|
941
858
|
|
859
|
+
/**
|
860
|
+
* Triggered after the stateProvider config got changed
|
861
|
+
* @param {Neo.state.Provider} value
|
862
|
+
* @param {Object|Neo.state.Provider|null} oldValue
|
863
|
+
* @protected
|
864
|
+
*/
|
865
|
+
afterSetStateProvider(value, oldValue) {
|
866
|
+
value?.createBindings(this)
|
867
|
+
}
|
868
|
+
|
942
869
|
/**
|
943
870
|
* Triggered after the style config got changed
|
944
871
|
* @param {Object} value
|
@@ -1042,26 +969,6 @@ class Component extends Base {
|
|
1042
969
|
me.cls = cls
|
1043
970
|
}
|
1044
971
|
|
1045
|
-
/**
|
1046
|
-
* Triggered after the vdom pseudo-config got changed
|
1047
|
-
* @param {Object} value
|
1048
|
-
* @param {Object|null} oldValue
|
1049
|
-
* @protected
|
1050
|
-
*/
|
1051
|
-
afterSetVdom(value, oldValue) {
|
1052
|
-
this.updateVdom()
|
1053
|
-
}
|
1054
|
-
|
1055
|
-
/**
|
1056
|
-
* Triggered after the vnode config got changed
|
1057
|
-
* @param {Object} value
|
1058
|
-
* @param {Object|null} oldValue
|
1059
|
-
* @protected
|
1060
|
-
*/
|
1061
|
-
afterSetVnode(value, oldValue) {
|
1062
|
-
oldValue !== undefined && this.syncVnodeTree()
|
1063
|
-
}
|
1064
|
-
|
1065
972
|
/**
|
1066
973
|
* Triggered after the width config got changed
|
1067
974
|
* @param {Number|String|null} value
|
@@ -1232,8 +1139,7 @@ class Component extends Base {
|
|
1232
1139
|
}
|
1233
1140
|
}
|
1234
1141
|
|
1235
|
-
|
1236
|
-
return Neo.merge({}, value, me.constructor.config.align)
|
1142
|
+
return value
|
1237
1143
|
}
|
1238
1144
|
|
1239
1145
|
/**
|
@@ -1458,22 +1364,6 @@ class Component extends Base {
|
|
1458
1364
|
}
|
1459
1365
|
}
|
1460
1366
|
|
1461
|
-
/**
|
1462
|
-
* Convenience shortcut to create a component reference
|
1463
|
-
* @returns {Object}
|
1464
|
-
*/
|
1465
|
-
createVdomReference() {
|
1466
|
-
let me = this,
|
1467
|
-
reference = {componentId: me.id},
|
1468
|
-
vdomId = me.vdom.id;
|
1469
|
-
|
1470
|
-
if (vdomId && me.id !== vdomId) {
|
1471
|
-
reference.id = vdomId
|
1472
|
-
}
|
1473
|
-
|
1474
|
-
return reference
|
1475
|
-
}
|
1476
|
-
|
1477
1367
|
/**
|
1478
1368
|
* Unregister this instance from the ComponentManager
|
1479
1369
|
* @param {Boolean} updateParentVdom=false true to remove the component from the parent vdom => real dom
|
@@ -1481,14 +1371,13 @@ class Component extends Base {
|
|
1481
1371
|
* todo: unregister events
|
1482
1372
|
*/
|
1483
1373
|
destroy(updateParentVdom=false, silent=false) {
|
1484
|
-
let me
|
1485
|
-
{parent, parentId}
|
1486
|
-
parentStateProvider = parent?.getStateProvider(),
|
1374
|
+
let me = this,
|
1375
|
+
{parent, parentId} = me,
|
1487
1376
|
parentVdom;
|
1488
1377
|
|
1489
1378
|
me.revertFocus();
|
1490
1379
|
|
1491
|
-
me.
|
1380
|
+
me.removeDomEvents();
|
1492
1381
|
|
1493
1382
|
me.controller = null; // triggers destroy()
|
1494
1383
|
|
@@ -1496,8 +1385,6 @@ class Component extends Base {
|
|
1496
1385
|
|
1497
1386
|
me.stateProvider = null; // triggers destroy()
|
1498
1387
|
|
1499
|
-
me.bind && parentStateProvider?.removeBindings(me.id);
|
1500
|
-
|
1501
1388
|
me.plugins?.forEach(plugin => {
|
1502
1389
|
plugin.destroy()
|
1503
1390
|
});
|
@@ -1522,18 +1409,6 @@ class Component extends Base {
|
|
1522
1409
|
me.unmount = Neo.emptyFn
|
1523
1410
|
}
|
1524
1411
|
|
1525
|
-
/**
|
1526
|
-
* Triggers all stored resolve() callbacks
|
1527
|
-
*/
|
1528
|
-
doResolveUpdateCache() {
|
1529
|
-
let me = this;
|
1530
|
-
|
1531
|
-
if (me.resolveUpdateCache) {
|
1532
|
-
me.resolveUpdateCache.forEach(item => item());
|
1533
|
-
me.resolveUpdateCache = []
|
1534
|
-
}
|
1535
|
-
}
|
1536
|
-
|
1537
1412
|
/**
|
1538
1413
|
* Convenience shortcut for Neo.manager.Component.down
|
1539
1414
|
* @param {Object|String} config
|
@@ -1544,59 +1419,6 @@ class Component extends Base {
|
|
1544
1419
|
return ComponentManager.down(this, config, returnFirstMatch)
|
1545
1420
|
}
|
1546
1421
|
|
1547
|
-
/**
|
1548
|
-
* Internal method to send update requests to the vdom worker
|
1549
|
-
* @param {function} [resolve] used by promiseUpdate()
|
1550
|
-
* @param {function} [reject] used by promiseUpdate()
|
1551
|
-
* @private
|
1552
|
-
*/
|
1553
|
-
#executeVdomUpdate(resolve, reject) {
|
1554
|
-
let me = this,
|
1555
|
-
{vdom, vnode} = me,
|
1556
|
-
opts = {},
|
1557
|
-
deltas;
|
1558
|
-
|
1559
|
-
if (currentWorker.isSharedWorker) {
|
1560
|
-
opts.appName = me.appName;
|
1561
|
-
opts.windowId = me.windowId
|
1562
|
-
}
|
1563
|
-
|
1564
|
-
me.isVdomUpdating = true;
|
1565
|
-
|
1566
|
-
// we can not set the config directly => it could already be false,
|
1567
|
-
// and we still want to pass it further into subtrees
|
1568
|
-
me._needsVdomUpdate = false;
|
1569
|
-
me.afterSetNeedsVdomUpdate?.(false, true);
|
1570
|
-
|
1571
|
-
opts.vdom = ComponentManager.getVdomTree(vdom, me.updateDepth);
|
1572
|
-
opts.vnode = ComponentManager.getVnodeTree(vnode, me.updateDepth);
|
1573
|
-
|
1574
|
-
// Reset the updateDepth to the default value for the next update cycle
|
1575
|
-
me._updateDepth = me.constructor.config.updateDepth;
|
1576
|
-
|
1577
|
-
Neo.vdom.Helper.update(opts).catch(err => {
|
1578
|
-
me.isVdomUpdating = false;
|
1579
|
-
reject?.()
|
1580
|
-
}).then(data => {
|
1581
|
-
// Checking if the component got destroyed before the update cycle is done
|
1582
|
-
if (me.id) {
|
1583
|
-
// It is crucial to delegate the vnode tree before resolving the cycle
|
1584
|
-
me.vnode = data.vnode;
|
1585
|
-
me.isVdomUpdating = false;
|
1586
|
-
|
1587
|
-
deltas = data.deltas;
|
1588
|
-
|
1589
|
-
if (!Neo.config.useVdomWorker && deltas.length > 0) {
|
1590
|
-
Neo.applyDeltas(me.appName, deltas).then(() => {
|
1591
|
-
me.resolveVdomUpdate(resolve)
|
1592
|
-
})
|
1593
|
-
} else {
|
1594
|
-
me.resolveVdomUpdate(resolve)
|
1595
|
-
}
|
1596
|
-
}
|
1597
|
-
})
|
1598
|
-
}
|
1599
|
-
|
1600
1422
|
/**
|
1601
1423
|
* Calls focus() on the top level DOM node of this component or on a given node via id
|
1602
1424
|
* @param {String} id=this.id
|
@@ -1642,7 +1464,8 @@ class Component extends Base {
|
|
1642
1464
|
}
|
1643
1465
|
|
1644
1466
|
if (parentComponent) {
|
1645
|
-
|
1467
|
+
// todo: We need ?. until functional.component.Base supports controllers
|
1468
|
+
return parentComponent.getConfigInstanceByNtype?.(configName, ntype)
|
1646
1469
|
}
|
1647
1470
|
|
1648
1471
|
return null
|
@@ -1690,43 +1513,6 @@ class Component extends Base {
|
|
1690
1513
|
return Rectangle.clone(result)
|
1691
1514
|
}
|
1692
1515
|
|
1693
|
-
/**
|
1694
|
-
* Honors different item roots for mount / render OPs
|
1695
|
-
* @returns {String}
|
1696
|
-
*/
|
1697
|
-
getMountedParentId() {
|
1698
|
-
let parentId = this.parentId,
|
1699
|
-
parent = Neo.getComponent(parentId),
|
1700
|
-
itemsRoot = parent?.getVdomItemsRoot?.();
|
1701
|
-
|
1702
|
-
return itemsRoot ? itemsRoot.id : parentId
|
1703
|
-
}
|
1704
|
-
|
1705
|
-
/**
|
1706
|
-
* Calculate the real parentIndex inside the DOM
|
1707
|
-
* @returns {Number|undefined}
|
1708
|
-
*/
|
1709
|
-
getMountedParentIndex() {
|
1710
|
-
let parent = this.parent,
|
1711
|
-
items = parent?.items || [],
|
1712
|
-
i = 0,
|
1713
|
-
index = 0,
|
1714
|
-
len = items.length,
|
1715
|
-
item;
|
1716
|
-
|
1717
|
-
for (; i < len; i++) {
|
1718
|
-
item = items[i];
|
1719
|
-
|
1720
|
-
if (item === this) {
|
1721
|
-
return index
|
1722
|
-
}
|
1723
|
-
|
1724
|
-
if (!item.hidden && item.hideMode === 'removeDom') {
|
1725
|
-
index++
|
1726
|
-
}
|
1727
|
-
}
|
1728
|
-
}
|
1729
|
-
|
1730
1516
|
/**
|
1731
1517
|
* Get the parent components as an array
|
1732
1518
|
* @returns {Neo.component.Base[]}
|
@@ -1793,7 +1579,7 @@ class Component extends Base {
|
|
1793
1579
|
* @returns {Neo.state.Provider|null}
|
1794
1580
|
*/
|
1795
1581
|
getStateProvider(ntype) {
|
1796
|
-
if (!
|
1582
|
+
if (!Neo.isUsingStateProviders) {
|
1797
1583
|
return null
|
1798
1584
|
}
|
1799
1585
|
|
@@ -1849,44 +1635,6 @@ class Component extends Base {
|
|
1849
1635
|
return Neo.config.themes?.[0]
|
1850
1636
|
}
|
1851
1637
|
|
1852
|
-
/**
|
1853
|
-
* Search a vdom child node by id for a given vdom tree
|
1854
|
-
* @param {String} id
|
1855
|
-
* @param {Object} vdom=this.vdom
|
1856
|
-
* @returns {Object}
|
1857
|
-
*/
|
1858
|
-
getVdomChild(id, vdom=this.vdom) {
|
1859
|
-
return VDomUtil.find(vdom, id)?.vdom
|
1860
|
-
}
|
1861
|
-
|
1862
|
-
/**
|
1863
|
-
* Specify a different vdom root if needed to apply the top level style attributes on a different level.
|
1864
|
-
* Make sure to use getVnodeRoot() as well, to keep the vdom & vnode trees in sync.
|
1865
|
-
* @returns {Object} The new vdom root
|
1866
|
-
*/
|
1867
|
-
getVdomRoot() {
|
1868
|
-
return this.vdom
|
1869
|
-
}
|
1870
|
-
|
1871
|
-
/**
|
1872
|
-
* Specify a different vnode root if needed to apply the top level style attributes on a different level.
|
1873
|
-
* Make sure to use getVdomRoot() as well, to keep the vdom & vnode trees in sync.
|
1874
|
-
* @returns {Object} The new vnode root
|
1875
|
-
*/
|
1876
|
-
getVnodeRoot() {
|
1877
|
-
return this.vnode
|
1878
|
-
}
|
1879
|
-
|
1880
|
-
/**
|
1881
|
-
* Checks if a given updateDepth & distance would result in an update collision
|
1882
|
-
* @param {Number} updateDepth
|
1883
|
-
* @param {Number} distance
|
1884
|
-
* @returns {Boolean}
|
1885
|
-
*/
|
1886
|
-
hasUpdateCollision(updateDepth, distance) {
|
1887
|
-
return updateDepth === -1 ? true : distance < updateDepth
|
1888
|
-
}
|
1889
|
-
|
1890
1638
|
/**
|
1891
1639
|
* Hide the component.
|
1892
1640
|
* hideMode: 'removeDom' uses vdom removeDom.
|
@@ -1930,16 +1678,11 @@ class Component extends Base {
|
|
1930
1678
|
}
|
1931
1679
|
|
1932
1680
|
/**
|
1933
|
-
*
|
1934
|
-
* @param {Object} config
|
1935
|
-
* @param {Boolean} [preventOriginalConfig] True prevents the instance from getting an originalConfig property
|
1681
|
+
* @param args
|
1936
1682
|
*/
|
1937
|
-
initConfig(
|
1938
|
-
super.initConfig(
|
1939
|
-
|
1940
|
-
let me = this;
|
1941
|
-
|
1942
|
-
me.getStateProvider()?.parseConfig(me)
|
1683
|
+
initConfig(...args) {
|
1684
|
+
super.initConfig(...args);
|
1685
|
+
this.getStateProvider()?.createBindings(this)
|
1943
1686
|
}
|
1944
1687
|
|
1945
1688
|
/**
|
@@ -1960,45 +1703,6 @@ class Component extends Base {
|
|
1960
1703
|
return me.parent.floating
|
1961
1704
|
}
|
1962
1705
|
|
1963
|
-
/**
|
1964
|
-
* Checks for vdom updates inside the parent chain and if found.
|
1965
|
-
* Registers the component for a vdom update once done.
|
1966
|
-
* @param {String} parentId=this.parentId
|
1967
|
-
* @param {Function} [resolve] Gets passed by updateVdom()
|
1968
|
-
* @param {Number} distance=1 Distance inside the component tree
|
1969
|
-
* @returns {Boolean}
|
1970
|
-
*/
|
1971
|
-
isParentUpdating(parentId=this.parentId, resolve, distance=1) {
|
1972
|
-
if (parentId !== 'document.body') {
|
1973
|
-
let me = this,
|
1974
|
-
parent = Neo.getComponent(parentId);
|
1975
|
-
|
1976
|
-
if (parent) {
|
1977
|
-
if (parent.isVdomUpdating) {
|
1978
|
-
if (me.hasUpdateCollision(parent.currentUpdateDepth, distance)) {
|
1979
|
-
if (Neo.config.logVdomUpdateCollisions) {
|
1980
|
-
console.warn('vdom parent update conflict with:', parent, 'for:', me)
|
1981
|
-
}
|
1982
|
-
|
1983
|
-
parent.childUpdateCache[me.id] = {distance, resolve};
|
1984
|
-
|
1985
|
-
// Adding the resolve fn to its own cache, since the parent will trigger
|
1986
|
-
// a new update() directly on this cmp
|
1987
|
-
resolve && me.resolveUpdateCache.push(resolve);
|
1988
|
-
return true
|
1989
|
-
}
|
1990
|
-
|
1991
|
-
// If an update is running and does not have a collision, we do not need to check further parents
|
1992
|
-
return false
|
1993
|
-
}
|
1994
|
-
|
1995
|
-
return me.isParentUpdating(parent.parentId, resolve, distance+1)
|
1996
|
-
}
|
1997
|
-
}
|
1998
|
-
|
1999
|
-
return false
|
2000
|
-
}
|
2001
|
-
|
2002
1706
|
/**
|
2003
1707
|
* @param {Number|String} value
|
2004
1708
|
* @returns {Promise<number>}
|
@@ -2025,28 +1729,15 @@ class Component extends Base {
|
|
2025
1729
|
* @returns {Object} config
|
2026
1730
|
*/
|
2027
1731
|
mergeConfig(...args) {
|
2028
|
-
let
|
2029
|
-
config
|
2030
|
-
|
2031
|
-
// it should be possible to set custom configs for the vdom on instance level,
|
2032
|
-
// however there will be already added attributes (e.g. id), so a merge seems to be the best strategy.
|
2033
|
-
vdom = {...me._vdom || {}, ...config.vdom || {}};
|
2034
|
-
|
2035
|
-
// avoid any interference on prototype level
|
2036
|
-
// does not clone existing Neo instances
|
2037
|
-
me._vdom = Neo.clone(vdom, true, true);
|
1732
|
+
let config = super.mergeConfig(...args),
|
1733
|
+
vdom = config.vdom || config._vdom || {};
|
2038
1734
|
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
}
|
2043
|
-
|
2044
|
-
me.wrapperStyle = Neo.clone(config.wrapperStyle, false);
|
1735
|
+
// It should be possible to modify root level vdom attributes on instance level.
|
1736
|
+
// Note that vdom is not a real config, but implemented via get() & set().
|
1737
|
+
this._vdom = Neo.clone({...vdom, ...this._vdom || {}}, true);
|
2045
1738
|
|
2046
|
-
delete config.style;
|
2047
1739
|
delete config._vdom;
|
2048
1740
|
delete config.vdom;
|
2049
|
-
delete config.wrapperStyle;
|
2050
1741
|
|
2051
1742
|
return config
|
2052
1743
|
}
|
@@ -2099,40 +1790,16 @@ class Component extends Base {
|
|
2099
1790
|
}
|
2100
1791
|
}
|
2101
1792
|
|
2102
|
-
/**
|
2103
|
-
* Checks the needsVdomUpdate config inside the parent tree
|
2104
|
-
* @param {String} parentId=this.parentId
|
2105
|
-
* @param {Function} [resolve] gets passed by updateVdom()
|
2106
|
-
* @param {Number} distance=1 Distance inside the component tree
|
2107
|
-
* @returns {Boolean}
|
2108
|
-
*/
|
2109
|
-
needsParentUpdate(parentId=this.parentId, resolve, distance=1) {
|
2110
|
-
if (parentId !== 'document.body') {
|
2111
|
-
let me = this,
|
2112
|
-
parent = Neo.getComponent(parentId);
|
2113
|
-
|
2114
|
-
if (parent) {
|
2115
|
-
// We are checking for parent.updateDepth, since we care about the depth of the next update cycle
|
2116
|
-
if (parent.needsVdomUpdate && me.hasUpdateCollision(parent.updateDepth, distance)) {
|
2117
|
-
parent.resolveUpdateCache.push(...me.resolveUpdateCache);
|
2118
|
-
resolve && parent.resolveUpdateCache.push(resolve);
|
2119
|
-
me.resolveUpdateCache = [];
|
2120
|
-
return true
|
2121
|
-
}
|
2122
|
-
|
2123
|
-
return me.needsParentUpdate(parent.parentId, resolve, distance+1)
|
2124
|
-
}
|
2125
|
-
}
|
2126
|
-
|
2127
|
-
return false
|
2128
|
-
}
|
2129
|
-
|
2130
1793
|
/**
|
2131
1794
|
*
|
2132
1795
|
*/
|
2133
1796
|
onConstructed() {
|
2134
|
-
super.onConstructed()
|
2135
|
-
|
1797
|
+
super.onConstructed()
|
1798
|
+
|
1799
|
+
let me = this;
|
1800
|
+
|
1801
|
+
me.keys?.register(me);
|
1802
|
+
me.getStateProvider()?.createBindings(me)
|
2136
1803
|
}
|
2137
1804
|
|
2138
1805
|
/**
|
@@ -2174,65 +1841,6 @@ class Component extends Base {
|
|
2174
1841
|
* @param {Array} opts.oldPath dom element ids upwards
|
2175
1842
|
*/
|
2176
1843
|
|
2177
|
-
/**
|
2178
|
-
* Gets called from the render() promise success handler
|
2179
|
-
* @param {Object} vnode
|
2180
|
-
* @param {Boolean} autoMount Mount the DOM after the vnode got created
|
2181
|
-
* @protected
|
2182
|
-
*/
|
2183
|
-
onRender(vnode, autoMount) {
|
2184
|
-
let me = this,
|
2185
|
-
{app} = me;
|
2186
|
-
|
2187
|
-
me.rendering = false;
|
2188
|
-
|
2189
|
-
// if app is a check to see if the Component got destroyed while rendering => before onRender got triggered
|
2190
|
-
if (app) {
|
2191
|
-
if (!app.rendered) {
|
2192
|
-
app.rendering = false;
|
2193
|
-
app.rendered = true;
|
2194
|
-
app.fire('render')
|
2195
|
-
}
|
2196
|
-
|
2197
|
-
me.vnode = vnode;
|
2198
|
-
|
2199
|
-
let childIds = ComponentManager.getChildIds(vnode),
|
2200
|
-
i = 0,
|
2201
|
-
len = childIds.length,
|
2202
|
-
child;
|
2203
|
-
|
2204
|
-
for (; i < len; i++) {
|
2205
|
-
child = Neo.getComponent(childIds[i]);
|
2206
|
-
|
2207
|
-
if (child) {
|
2208
|
-
child.rendered = true
|
2209
|
-
}
|
2210
|
-
}
|
2211
|
-
|
2212
|
-
me._rendered = true; // silent update
|
2213
|
-
me.fire('rendered', me.id);
|
2214
|
-
|
2215
|
-
if (autoMount) {
|
2216
|
-
me.mounted = true;
|
2217
|
-
|
2218
|
-
if (!app.mounted) {
|
2219
|
-
app.mounted = true;
|
2220
|
-
app.fire('mounted')
|
2221
|
-
}
|
2222
|
-
}
|
2223
|
-
}
|
2224
|
-
}
|
2225
|
-
|
2226
|
-
/**
|
2227
|
-
* Promise based vdom update
|
2228
|
-
* @returns {Promise<any>}
|
2229
|
-
*/
|
2230
|
-
promiseUpdate() {
|
2231
|
-
return new Promise((resolve, reject) => {
|
2232
|
-
this.updateVdom(resolve, reject)
|
2233
|
-
})
|
2234
|
-
}
|
2235
|
-
|
2236
1844
|
/**
|
2237
1845
|
* Remove a cls from the vdomRoot
|
2238
1846
|
* @param {String} value
|
@@ -2244,32 +1852,7 @@ class Component extends Base {
|
|
2244
1852
|
this.cls = cls
|
2245
1853
|
}
|
2246
1854
|
|
2247
|
-
/**
|
2248
|
-
* @param {Array|Object} value
|
2249
|
-
*/
|
2250
|
-
removeDomListeners(value) {
|
2251
|
-
if (!Array.isArray(value)) {
|
2252
|
-
value = [value];
|
2253
|
-
}
|
2254
|
-
|
2255
|
-
let me = this,
|
2256
|
-
{domListeners} = me,
|
2257
|
-
i, len;
|
2258
|
-
|
2259
|
-
value.forEach(item => {
|
2260
|
-
i = 0;
|
2261
|
-
len = domListeners.length;
|
2262
1855
|
|
2263
|
-
for (; i < len; i++) {
|
2264
|
-
if (Neo.isEqual(item, domListeners[i])) {
|
2265
|
-
domListeners.splice(i, 1);
|
2266
|
-
break
|
2267
|
-
}
|
2268
|
-
}
|
2269
|
-
});
|
2270
|
-
|
2271
|
-
me.domListeners = domListeners
|
2272
|
-
}
|
2273
1856
|
|
2274
1857
|
/**
|
2275
1858
|
* Either a string like 'color' or an array containing style attributes to remove
|
@@ -2298,108 +1881,6 @@ class Component extends Base {
|
|
2298
1881
|
return style
|
2299
1882
|
}
|
2300
1883
|
|
2301
|
-
/**
|
2302
|
-
* Creates the vnode tree for this component and mounts the component in case
|
2303
|
-
* - you pass true for the mount param
|
2304
|
-
* - or the autoMount config is set to true
|
2305
|
-
* @param {Boolean} [mount] Mount the DOM after the vnode got created
|
2306
|
-
*/
|
2307
|
-
async render(mount) {
|
2308
|
-
let me = this,
|
2309
|
-
autoMount = mount || me.autoMount,
|
2310
|
-
{app} = me,
|
2311
|
-
{useVdomWorker} = Neo.config;
|
2312
|
-
|
2313
|
-
// Verify that the critical rendering path => CSS files for the new tree is in place
|
2314
|
-
if (autoMount && currentWorker.countLoadingThemeFiles !== 0) {
|
2315
|
-
currentWorker.on('themeFilesLoaded', function() {
|
2316
|
-
!me.mounted && me.render(mount)
|
2317
|
-
}, me, {once: true});
|
2318
|
-
|
2319
|
-
return
|
2320
|
-
}
|
2321
|
-
|
2322
|
-
me.rendering = true;
|
2323
|
-
|
2324
|
-
if (!app.rendered) {
|
2325
|
-
app.rendering = true
|
2326
|
-
}
|
2327
|
-
|
2328
|
-
if (me.vdom) {
|
2329
|
-
me.isVdomUpdating = true;
|
2330
|
-
|
2331
|
-
delete me.vdom.removeDom;
|
2332
|
-
|
2333
|
-
me._needsVdomUpdate = false;
|
2334
|
-
me.afterSetNeedsVdomUpdate?.(false, true);
|
2335
|
-
|
2336
|
-
const data = await Neo.vdom.Helper.create({
|
2337
|
-
appName : me.appName,
|
2338
|
-
autoMount,
|
2339
|
-
parentId : autoMount ? me.getMountedParentId() : undefined,
|
2340
|
-
parentIndex: autoMount ? me.getMountedParentIndex() : undefined,
|
2341
|
-
vdom : ComponentManager.getVdomTree(me.vdom),
|
2342
|
-
windowId : me.windowId
|
2343
|
-
});
|
2344
|
-
|
2345
|
-
me.onRender(data.vnode, useVdomWorker ? autoMount : false);
|
2346
|
-
me.isVdomUpdating = false;
|
2347
|
-
|
2348
|
-
autoMount && !useVdomWorker && me.mount();
|
2349
|
-
|
2350
|
-
me.resolveVdomUpdate()
|
2351
|
-
}
|
2352
|
-
}
|
2353
|
-
|
2354
|
-
/**
|
2355
|
-
* Internal helper fn to resolve the Promise for updateVdom()
|
2356
|
-
* @param {Function|undefined} resolve
|
2357
|
-
* @protected
|
2358
|
-
*/
|
2359
|
-
resolveVdomUpdate(resolve) {
|
2360
|
-
let me = this,
|
2361
|
-
hasChildUpdateCache = !Neo.isEmpty(me.childUpdateCache),
|
2362
|
-
component;
|
2363
|
-
|
2364
|
-
me.doResolveUpdateCache();
|
2365
|
-
|
2366
|
-
resolve?.();
|
2367
|
-
|
2368
|
-
if (me.needsVdomUpdate) {
|
2369
|
-
if (hasChildUpdateCache) {
|
2370
|
-
Object.entries(me.childUpdateCache).forEach(([key, value]) => {
|
2371
|
-
component = Neo.getComponent(key);
|
2372
|
-
|
2373
|
-
// The component might already got destroyed
|
2374
|
-
if (component) {
|
2375
|
-
// Pass callbacks to the resolver cache => getting executed once the following update is done
|
2376
|
-
value.resolve && NeoArray.add(me.resolveUpdateCache, value.resolve);
|
2377
|
-
|
2378
|
-
// Adjust the updateDepth to include the depth of all merged child updates
|
2379
|
-
if (me.updateDepth !== -1) {
|
2380
|
-
if (component.updateDepth === -1) {
|
2381
|
-
me.updateDepth = -1
|
2382
|
-
} else {
|
2383
|
-
// Since updateDepth is 1-based, we need to subtract 1 level
|
2384
|
-
me.updateDepth = me.updateDepth + value.distance + component.updateDepth - 1
|
2385
|
-
}
|
2386
|
-
}
|
2387
|
-
}
|
2388
|
-
});
|
2389
|
-
|
2390
|
-
me.childUpdateCache = {}
|
2391
|
-
}
|
2392
|
-
|
2393
|
-
me.update()
|
2394
|
-
} else if (hasChildUpdateCache) {
|
2395
|
-
Object.keys(me.childUpdateCache).forEach(key => {
|
2396
|
-
Neo.getComponent(key)?.update()
|
2397
|
-
});
|
2398
|
-
|
2399
|
-
me.childUpdateCache = {}
|
2400
|
-
}
|
2401
|
-
}
|
2402
|
-
|
2403
1884
|
/**
|
2404
1885
|
*
|
2405
1886
|
*/
|
@@ -2418,33 +1899,33 @@ class Component extends Base {
|
|
2418
1899
|
* @returns {Promise<*>}
|
2419
1900
|
*/
|
2420
1901
|
set(values={}, silent=false) {
|
2421
|
-
|
2422
|
-
|
2423
|
-
|
2424
|
-
me.silentVdomUpdate = true;
|
2425
|
-
|
2426
|
-
super.set(values);
|
1902
|
+
const
|
1903
|
+
me = this,
|
1904
|
+
wasHidden = me.hidden;
|
2427
1905
|
|
2428
|
-
me.
|
1906
|
+
me.setSilent(values);
|
2429
1907
|
|
2430
|
-
if (silent
|
2431
|
-
|
2432
|
-
} else {
|
2433
|
-
if (needsRendering) {
|
1908
|
+
if (!silent && me.needsVdomUpdate) {
|
1909
|
+
if (wasHidden && !me.hidden) {
|
2434
1910
|
me.show();
|
2435
1911
|
return Promise.resolve()
|
2436
1912
|
}
|
2437
1913
|
|
2438
1914
|
return me.promiseUpdate()
|
2439
1915
|
}
|
1916
|
+
|
1917
|
+
return Promise.resolve()
|
2440
1918
|
}
|
2441
1919
|
|
2442
1920
|
/**
|
2443
|
-
*
|
1921
|
+
* A silent version of set(), which does not trigger a vdom update at the end.
|
1922
|
+
* Useful for batching multiple config changes.
|
2444
1923
|
* @param {Object} values={}
|
2445
1924
|
*/
|
2446
|
-
setSilent(values
|
2447
|
-
|
1925
|
+
setSilent(values={}) {
|
1926
|
+
this.silentVdomUpdate = true;
|
1927
|
+
super.set(values);
|
1928
|
+
this.silentVdomUpdate = false
|
2448
1929
|
}
|
2449
1930
|
|
2450
1931
|
/**
|
@@ -2483,78 +1964,6 @@ class Component extends Base {
|
|
2483
1964
|
me._hidden = false
|
2484
1965
|
}
|
2485
1966
|
|
2486
|
-
/**
|
2487
|
-
* Placeholder method for util.VDom.syncVdomIds to allow overriding (disabling) it
|
2488
|
-
* @param {Neo.vdom.VNode} [vnode=this.vnode]
|
2489
|
-
* @param {Object} [vdom=this.vdom]
|
2490
|
-
* @param {Boolean} force=false
|
2491
|
-
*/
|
2492
|
-
syncVdomIds(vnode=this.vnode, vdom=this.vdom, force=false) {
|
2493
|
-
VDomUtil.syncVdomIds(vnode, vdom, force)
|
2494
|
-
}
|
2495
|
-
|
2496
|
-
/**
|
2497
|
-
* In case a component receives a new vnode, we want to do:
|
2498
|
-
* - sync the vdom ids
|
2499
|
-
* - setting rendered to true for child components
|
2500
|
-
* - updating the parent component to ensure that the vnode tree stays persistent
|
2501
|
-
* @param {Neo.vdom.VNode} [vnode=this.vnode]
|
2502
|
-
*/
|
2503
|
-
syncVnodeTree(vnode=this.vnode) {
|
2504
|
-
let me = this,
|
2505
|
-
childComponents = ComponentManager.getChildren(me),
|
2506
|
-
debug = false,
|
2507
|
-
map = {},
|
2508
|
-
childVnode, start;
|
2509
|
-
|
2510
|
-
if (debug) {
|
2511
|
-
start = performance.now()
|
2512
|
-
}
|
2513
|
-
|
2514
|
-
me.syncVdomIds();
|
2515
|
-
|
2516
|
-
if (vnode && me.id !== vnode.id) {
|
2517
|
-
ComponentManager.registerWrapperNode(vnode.id, me)
|
2518
|
-
}
|
2519
|
-
|
2520
|
-
// we need one separate iteration first to ensure all wrapper nodes get registered
|
2521
|
-
childComponents.forEach(component => {
|
2522
|
-
childVnode = VNodeUtil.find(me.vnode, component.vdom.id)?.vnode;
|
2523
|
-
|
2524
|
-
if (childVnode) {
|
2525
|
-
map[component.id] = childVnode;
|
2526
|
-
|
2527
|
-
if (component.id !== childVnode.id) {
|
2528
|
-
ComponentManager.registerWrapperNode(childVnode.id, component)
|
2529
|
-
}
|
2530
|
-
}
|
2531
|
-
});
|
2532
|
-
|
2533
|
-
// delegate the latest node updates to all possible child components found inside the vnode tree
|
2534
|
-
childComponents.forEach(component => {
|
2535
|
-
childVnode = map[component.id];
|
2536
|
-
|
2537
|
-
if (childVnode) {
|
2538
|
-
// silent update
|
2539
|
-
component._vnode = ComponentManager.addVnodeComponentReferences(childVnode, component.id);
|
2540
|
-
|
2541
|
-
if (!component.rendered) {
|
2542
|
-
component._rendered = true;
|
2543
|
-
component.fire('rendered', component.id)
|
2544
|
-
}
|
2545
|
-
|
2546
|
-
component.mounted = true
|
2547
|
-
} else {
|
2548
|
-
console.warn('syncVnodeTree: Could not replace the child vnode for', component.id)
|
2549
|
-
}
|
2550
|
-
});
|
2551
|
-
|
2552
|
-
// silent update
|
2553
|
-
me._vnode = vnode ? ComponentManager.addVnodeComponentReferences(vnode, me.id) : null;
|
2554
|
-
|
2555
|
-
debug && console.log('syncVnodeTree', me.id, performance.now() - start)
|
2556
|
-
}
|
2557
|
-
|
2558
1967
|
/**
|
2559
1968
|
* Toggle a cls inside the vdomRoot of the component
|
2560
1969
|
* @param {String} value
|
@@ -2590,13 +1999,6 @@ class Component extends Base {
|
|
2590
1999
|
return ComponentManager.up(this.id, config)
|
2591
2000
|
}
|
2592
2001
|
|
2593
|
-
/**
|
2594
|
-
*
|
2595
|
-
*/
|
2596
|
-
update() {
|
2597
|
-
this.afterSetVdom(this.vdom, null)
|
2598
|
-
}
|
2599
|
-
|
2600
2002
|
/**
|
2601
2003
|
*
|
2602
2004
|
*/
|
@@ -2615,54 +2017,6 @@ class Component extends Base {
|
|
2615
2017
|
me.update()
|
2616
2018
|
}
|
2617
2019
|
|
2618
|
-
/**
|
2619
|
-
* Gets called after the vdom config gets changed in case the component is already mounted (delta updates).
|
2620
|
-
* @param {function} [resolve] used by promiseUpdate()
|
2621
|
-
* @param {function} [reject] used by promiseUpdate()
|
2622
|
-
* @protected
|
2623
|
-
*/
|
2624
|
-
updateVdom(resolve, reject) {
|
2625
|
-
let me = this,
|
2626
|
-
{app, mounted, parentId, vnode} = me;
|
2627
|
-
|
2628
|
-
if (me.isVdomUpdating || me.silentVdomUpdate) {
|
2629
|
-
resolve && me.resolveUpdateCache.push(resolve);
|
2630
|
-
me.needsVdomUpdate = true
|
2631
|
-
} else {
|
2632
|
-
if (!mounted && me.isConstructed && !me.hasRenderingListener && app?.rendering === true) {
|
2633
|
-
me.hasRenderingListener = true;
|
2634
|
-
|
2635
|
-
app.on('mounted', () => {
|
2636
|
-
me.timeout(50).then(() => {
|
2637
|
-
me.vnode && me.updateVdom(resolve, reject)
|
2638
|
-
})
|
2639
|
-
}, me, {once: true})
|
2640
|
-
} else {
|
2641
|
-
if (resolve && (!mounted || !vnode)) {
|
2642
|
-
me.resolveUpdateCache.push(resolve)
|
2643
|
-
}
|
2644
|
-
|
2645
|
-
if (
|
2646
|
-
!me.needsParentUpdate(parentId, resolve)
|
2647
|
-
&& !me.isParentUpdating(parentId, resolve)
|
2648
|
-
&& mounted
|
2649
|
-
&& vnode
|
2650
|
-
) {
|
2651
|
-
// Verify that the critical rendering path => CSS files for the new tree is in place
|
2652
|
-
if (currentWorker.countLoadingThemeFiles !== 0) {
|
2653
|
-
currentWorker.on('themeFilesLoaded', function() {
|
2654
|
-
me.updateVdom(resolve, reject)
|
2655
|
-
}, me, {once: true})
|
2656
|
-
} else {
|
2657
|
-
me.#executeVdomUpdate(resolve, reject)
|
2658
|
-
}
|
2659
|
-
}
|
2660
|
-
}
|
2661
|
-
}
|
2662
|
-
|
2663
|
-
me.hasUnmountedVdomChanges = !mounted && me.hasBeenMounted
|
2664
|
-
}
|
2665
|
-
|
2666
2020
|
/**
|
2667
2021
|
* In case you are sure a DOMRect exists, use getDomRect()
|
2668
2022
|
* Otherwise you can wait for it using this method.
|