neo.mjs 10.0.0-beta.5 → 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.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/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 +130 -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 +10 -8
- 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 -64
- 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 +217 -166
- package/src/Xhr.mjs +1 -0
- package/src/button/Base.mjs +13 -0
- package/src/button/Effect.mjs +16 -2
- 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 +7 -10
- package/src/collection/Filter.mjs +6 -0
- package/src/collection/Sorter.mjs +3 -0
- package/src/component/Base.mjs +104 -771
- 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 +7 -3
- 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 +55 -3
- package/src/core/Compare.mjs +4 -7
- package/src/core/Config.mjs +65 -52
- package/src/core/Effect.mjs +79 -13
- package/src/core/EffectBatchManager.mjs +18 -19
- package/src/core/EffectManager.mjs +25 -3
- 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 +50 -60
- 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/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 +98 -70
- package/src/state/createHierarchicalDataProxy.mjs +39 -25
- 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 +2 -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 +35 -23
- package/src/vdom/VNode.mjs +4 -6
- package/src/worker/App.mjs +1 -0
- 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 +5 -2
- package/test/siesta/tests/VdomCalendar.mjs +13 -9
- package/test/siesta/tests/core/Effect.mjs +10 -14
- package/test/siesta/tests/core/EffectBatching.mjs +25 -37
- package/test/siesta/tests/state/ProviderNestedDataConfigs.mjs +255 -0
- package/test/siesta/tests/state/createHierarchicalDataProxy.mjs +42 -55
- 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
|
/**
|
@@ -55,6 +53,7 @@ class Component extends Base {
|
|
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
55
|
* @member {Object|String} align_={[isDescriptor]: true, merge: 'deep', value: {edgeAlign: 't-b',constrainTo: 'document.body'}}
|
56
|
+
* @reactive
|
58
57
|
*/
|
59
58
|
align_: {
|
60
59
|
[isDescriptor]: true,
|
@@ -67,23 +66,9 @@ class Component extends Base {
|
|
67
66
|
/**
|
68
67
|
* The name of the App this component belongs to
|
69
68
|
* @member {String|null} appName_=null
|
69
|
+
* @reactive
|
70
70
|
*/
|
71
71
|
appName_: null,
|
72
|
-
/**
|
73
|
-
* True automatically mounts a component after being rendered.
|
74
|
-
* Use this for the top level component of your app.
|
75
|
-
* @member {Boolean} autoMount=false
|
76
|
-
* @tutorial 02_ClassSystem
|
77
|
-
*/
|
78
|
-
autoMount: false,
|
79
|
-
/**
|
80
|
-
* True automatically renders a component after being created inside the init call.
|
81
|
-
* Use this for the top level component of your app.
|
82
|
-
* @member {Boolean} autoRender=false
|
83
|
-
* @see {@link Neo.component.Base#init init}
|
84
|
-
* @tutorial 02_ClassSystem
|
85
|
-
*/
|
86
|
-
autoRender: false,
|
87
72
|
/**
|
88
73
|
* CSS selectors to apply to the root level node of this component
|
89
74
|
* @member {String[]} baseCls=[]
|
@@ -105,17 +90,20 @@ class Component extends Base {
|
|
105
90
|
* Custom CSS selectors to apply to the root level node of this component
|
106
91
|
* You can override baseCls to remove default selectors.
|
107
92
|
* @member {String[]} cls_=null
|
93
|
+
* @reactive
|
108
94
|
*/
|
109
95
|
cls_: null,
|
110
96
|
/**
|
111
97
|
* manager.Focus will change this flag on focusin & out dom events
|
112
98
|
* @member {Boolean} containsFocus_=false
|
113
99
|
* @protected
|
100
|
+
* @reactive
|
114
101
|
*/
|
115
102
|
containsFocus_: false,
|
116
103
|
/**
|
117
104
|
* Assign a component controller to this component (pass an imported module or the string based class name)
|
118
105
|
* @member {Neo.controller.Component|String} controller_=null
|
106
|
+
* @reactive
|
119
107
|
*/
|
120
108
|
controller_: null,
|
121
109
|
/**
|
@@ -123,32 +111,19 @@ class Component extends Base {
|
|
123
111
|
* Read only.
|
124
112
|
* @member {Object} data_=null
|
125
113
|
* @protected
|
114
|
+
* @reactive
|
126
115
|
*/
|
127
116
|
data_: null,
|
128
117
|
/**
|
129
118
|
* Disabled components will get the neo-disabled cls applied and won't receive DOM events
|
130
119
|
* @member {Boolean} disabled_=false
|
120
|
+
* @reactive
|
131
121
|
*/
|
132
122
|
disabled_: false,
|
133
|
-
/**
|
134
|
-
* An array of domListener configs
|
135
|
-
* @member {Object[]|null} domListeners_=null
|
136
|
-
* @example
|
137
|
-
* afterSetStayOnHover(value, oldValue) {
|
138
|
-
* if (value) {
|
139
|
-
* let me = this;
|
140
|
-
*
|
141
|
-
* me.addDomListeners(
|
142
|
-
* {mouseenter: me.onMouseEnter, scope: me},
|
143
|
-
* {mouseleave: me.onMouseLeave, scope: me}
|
144
|
-
* )
|
145
|
-
* }
|
146
|
-
*}
|
147
|
-
*/
|
148
|
-
domListeners_: null,
|
149
123
|
/**
|
150
124
|
* Set this config to true to dynamically import a DropZone module & create an instance
|
151
125
|
* @member {Boolean} droppable_=false
|
126
|
+
* @reactive
|
152
127
|
*/
|
153
128
|
droppable_: false,
|
154
129
|
/**
|
@@ -170,39 +145,30 @@ class Component extends Base {
|
|
170
145
|
* @protected
|
171
146
|
*/
|
172
147
|
hasBeenMounted: false,
|
173
|
-
/**
|
174
|
-
* Internal flag
|
175
|
-
* @member {Boolean} hasRenderingListener=false
|
176
|
-
* @protected
|
177
|
-
*/
|
178
|
-
hasRenderingListener: false,
|
179
|
-
/**
|
180
|
-
* Internal flag for vdom changes after a component got unmounted
|
181
|
-
* (delta updates can no longer get applied & a new render call is required before re-mounting)
|
182
|
-
* @member {Boolean} hasUnmountedVdomChanges_=false
|
183
|
-
* @protected
|
184
|
-
*/
|
185
|
-
hasUnmountedVdomChanges_: false,
|
186
148
|
/**
|
187
149
|
* Shortcut for style.height, defaults to px
|
188
150
|
* @member {Number|String|null} height_=null
|
151
|
+
* @reactive
|
189
152
|
*/
|
190
153
|
height_: null,
|
191
154
|
/**
|
192
155
|
* Initial setting to hide or show the component and
|
193
156
|
* you can use either hide()/show() or change this config directly to change the hidden state
|
194
157
|
* @member {Boolean} hidden_=false
|
158
|
+
* @reactive
|
195
159
|
*/
|
196
160
|
hidden_: false,
|
197
161
|
/**
|
198
162
|
* Used for hide and show and defines if the component
|
199
163
|
* should use css visibility:'hidden' or vdom:removeDom
|
200
164
|
* @member {String} hideMode_='removeDom'
|
165
|
+
* @reactive
|
201
166
|
*/
|
202
167
|
hideMode_: 'removeDom',
|
203
168
|
/**
|
204
169
|
* The top level innerHTML of the component
|
205
170
|
* @member {String|null} html_=null
|
171
|
+
* @reactive
|
206
172
|
*/
|
207
173
|
html_: null,
|
208
174
|
/**
|
@@ -211,78 +177,73 @@ class Component extends Base {
|
|
211
177
|
* @member {Boolean|String} isLoading=false
|
212
178
|
*/
|
213
179
|
isLoading_: false,
|
214
|
-
/**
|
215
|
-
* Internal flag which will get set to true while an update request (worker messages) is in progress
|
216
|
-
* @member {Boolean} isVdomUpdating_=false
|
217
|
-
* @protected
|
218
|
-
*/
|
219
|
-
isVdomUpdating_: false,
|
220
180
|
/**
|
221
181
|
* Using the keys config will create an instance of Neo.util.KeyNavigation.
|
222
182
|
* @see {@link Neo.util.KeyNavigation KeyNavigation}
|
223
183
|
* @member {Object} keys_=null
|
184
|
+
* @reactive
|
224
185
|
*/
|
225
186
|
keys_: null,
|
226
187
|
/**
|
227
188
|
* Gets used inside afterSetIsLoading() to define the CSS for the loading spinner icon
|
228
189
|
* @member {String[]} loadingSpinnerCls_=['fa','fa-spinner','fa-spin']
|
190
|
+
* @reactive
|
229
191
|
*/
|
230
192
|
loadingSpinnerCls_: ['fa', 'fa-spinner', 'fa-spin'],
|
231
193
|
/**
|
232
194
|
* Shortcut for style.maxHeight, defaults to px
|
233
195
|
* @member {Number|String|null} maxHeight_=null
|
196
|
+
* @reactive
|
234
197
|
*/
|
235
198
|
maxHeight_: null,
|
236
199
|
/**
|
237
200
|
* Shortcut for style.maxWidth, defaults to px
|
238
201
|
* @member {Number|String|null} maxWidth_=null
|
202
|
+
* @reactive
|
239
203
|
*/
|
240
204
|
maxWidth_: null,
|
241
205
|
/**
|
242
206
|
* Shortcut for style.minHeight, defaults to px
|
243
207
|
* @member {Number|String|null} minHeight_=null
|
208
|
+
* @reactive
|
244
209
|
*/
|
245
210
|
minHeight_: null,
|
246
211
|
/**
|
247
212
|
* Shortcut for style.minWidth, defaults to px
|
248
213
|
* @member {Number|String|null} minWidth_=null
|
214
|
+
* @reactive
|
249
215
|
*/
|
250
216
|
minWidth_: null,
|
217
|
+
/**
|
218
|
+
* @member {Neo.core.Base[]} mixins=[DomEvents, Observable, VdomLifecycle]
|
219
|
+
*/
|
220
|
+
mixins: [DomEvents, Observable, VdomLifecycle],
|
251
221
|
/**
|
252
222
|
* Override specific stateProvider data properties.
|
253
223
|
* This will merge the content.
|
254
224
|
* @member {Object|null} modelData=null
|
255
225
|
*/
|
256
226
|
modelData: null,
|
257
|
-
/**
|
258
|
-
* True in case the component is mounted to the DOM
|
259
|
-
* @member {Boolean} mounted_=false
|
260
|
-
* @protected
|
261
|
-
*/
|
262
|
-
mounted_: false,
|
263
|
-
/**
|
264
|
-
* Internal flag which will get set to true in case an update call arrives while another update is running
|
265
|
-
* @member {Boolean} needsVdomUpdate_=false
|
266
|
-
* @protected
|
267
|
-
*/
|
268
|
-
needsVdomUpdate_: false,
|
269
227
|
/**
|
270
228
|
* If the parentId does not match a neo component id, you can manually set this value for finding
|
271
229
|
* view controllers or state providers.
|
272
230
|
* Use case: manually dropping components into a vdom structure
|
273
231
|
* @member {Neo.component.Base|null} parentComponent_=null
|
274
232
|
* @protected
|
233
|
+
* @reactive
|
275
234
|
*/
|
276
235
|
parentComponent_: null,
|
277
236
|
/**
|
278
237
|
* The parent component id or document.body
|
279
238
|
* @member {String} parentId_='document.body'
|
239
|
+
* @reactive
|
280
240
|
*/
|
281
241
|
parentId_: 'document.body',
|
282
242
|
/**
|
283
243
|
* Array of Plugin Modules and / or config objects
|
284
244
|
* @member {Array|null} plugins_=null
|
285
245
|
* @protected
|
246
|
+
* @reactive
|
286
247
|
*/
|
287
248
|
plugins_: null,
|
288
249
|
/**
|
@@ -290,6 +251,7 @@ class Component extends Base {
|
|
290
251
|
* References will also get mapped into the vdom root (data-ref: value).
|
291
252
|
* @member {String|null} reference_=null
|
292
253
|
* @protected
|
254
|
+
* @reactive
|
293
255
|
*/
|
294
256
|
reference_: null,
|
295
257
|
/**
|
@@ -299,16 +261,11 @@ class Component extends Base {
|
|
299
261
|
* @protected
|
300
262
|
*/
|
301
263
|
responsive_: null,
|
302
|
-
/**
|
303
|
-
* True in case the component is rendering the vnode
|
304
|
-
* @member {Boolean} rendering_=false
|
305
|
-
* @protected
|
306
|
-
*/
|
307
|
-
rendering_: false,
|
308
264
|
/**
|
309
265
|
* Specify a role tag attribute for the vdom root.
|
310
266
|
* See: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles
|
311
267
|
* @member {String|null} role_=null
|
268
|
+
* @reactive
|
312
269
|
*/
|
313
270
|
role_: null,
|
314
271
|
/**
|
@@ -316,17 +273,13 @@ class Component extends Base {
|
|
316
273
|
* Set this to 'x' or 'y' to add style 'overflow-x' or 'overflow-y' to 'auto'
|
317
274
|
* Other than false this will add cls 'neo-scrollable'.
|
318
275
|
* @member {Boolean|"x"|"y"} scrollable_=false
|
276
|
+
* @reactive
|
319
277
|
*/
|
320
278
|
scrollable_: false,
|
321
|
-
/**
|
322
|
-
* Set this to true for bulk updates. Ensure to set it back to false afterwards.
|
323
|
-
* Internally the value will get saved as a number to ensure that child methods won't stop the silent mode too early.
|
324
|
-
* @member {Boolean} silentVdomUpdate_=false
|
325
|
-
*/
|
326
|
-
silentVdomUpdate_: false,
|
327
279
|
/**
|
328
280
|
* Optionally add a state.Provider to share state data with child components
|
329
281
|
* @member {Object|null} stateProvider_=null
|
282
|
+
* @reactive
|
330
283
|
*/
|
331
284
|
stateProvider_: null,
|
332
285
|
/**
|
@@ -342,6 +295,7 @@ class Component extends Base {
|
|
342
295
|
* You can pass a used theme directly to any component,
|
343
296
|
* to style specific component trees differently from your main view.
|
344
297
|
* @member {String|null} theme_=null
|
298
|
+
* @reactive
|
345
299
|
*/
|
346
300
|
theme_: null,
|
347
301
|
/**
|
@@ -349,11 +303,13 @@ class Component extends Base {
|
|
349
303
|
* this shortcut enables us to change the vdom root tag on instance level.
|
350
304
|
* Use cases: switch a Toolbar to a "nav" tag, switch a SideNav to an "aside" tag.
|
351
305
|
* @member {String|null} tag_=null
|
306
|
+
* @reactive
|
352
307
|
*/
|
353
308
|
tag_: null,
|
354
309
|
/**
|
355
310
|
* The top level textContent of the component
|
356
311
|
* @member {String|null} text_=null
|
312
|
+
* @reactive
|
357
313
|
*/
|
358
314
|
text_: null,
|
359
315
|
/**
|
@@ -366,51 +322,36 @@ class Component extends Base {
|
|
366
322
|
* If a widget needs its own instance for any reason, inslude the property `ownInstance : true`
|
367
323
|
* in the tooltip config object.
|
368
324
|
* @member {Object|String} tooltip_=null
|
325
|
+
* @reactive
|
369
326
|
*/
|
370
327
|
tooltip_: null,
|
371
328
|
/**
|
372
329
|
* Add 'primary' and other attributes to make it an outstanding design
|
373
330
|
* @member {String|null} ui_=null
|
331
|
+
* @reactive
|
374
332
|
*/
|
375
333
|
ui_: null,
|
376
|
-
/**
|
377
|
-
* Defines the depth of the vdom tree for the next update cycle.
|
378
|
-
* - The value 1 will only send the current vdom structure as it is
|
379
|
-
* - The value of 2 will include the vdom of direct children
|
380
|
-
* - The value of 3 will include the vdom of grandchildren
|
381
|
-
* - The value of -1 will include the full tree of any depth
|
382
|
-
* @member {Number} updateDepth_=1
|
383
|
-
*/
|
384
|
-
updateDepth_: 1,
|
385
|
-
/**
|
386
|
-
* The component vnode tree. Available after the component got rendered.
|
387
|
-
* @member {Object} vnode_=={[isDescriptor]: true, value: null, isEqual: (a, b) => a === b,}
|
388
|
-
* @protected
|
389
|
-
*/
|
390
|
-
vnode_: {
|
391
|
-
[isDescriptor]: true,
|
392
|
-
clone : 'none',
|
393
|
-
cloneOnGet : 'none',
|
394
|
-
isEqual : (a, b) => a === b, // vnode trees can be huge, and will get compared by the vdom worker.
|
395
|
-
value : null,
|
396
|
-
},
|
397
334
|
/**
|
398
335
|
* Shortcut for style.width, defaults to px
|
399
336
|
* @member {Number|String|null} width_=null
|
337
|
+
* @reactive
|
400
338
|
*/
|
401
339
|
width_: null,
|
402
340
|
/**
|
403
341
|
* The custom windowIs (timestamp) this component belongs to
|
404
342
|
* @member {Number|null} windowId_=null
|
343
|
+
* @reactive
|
405
344
|
*/
|
406
345
|
windowId_: null,
|
407
346
|
/**
|
408
347
|
* @member {String[]|null} wrapperCls_=null
|
348
|
+
* @reactive
|
409
349
|
*/
|
410
350
|
wrapperCls_: null,
|
411
351
|
/**
|
412
352
|
* Top level style attributes. Useful in case getVdomRoot() does not point to the top level DOM node.
|
413
353
|
* @member {Object|null} wrapperStyle_={[isDescriptor]: true, merge: 'shallow', value: null}
|
354
|
+
* @reactive
|
414
355
|
*/
|
415
356
|
wrapperStyle_: {
|
416
357
|
[isDescriptor]: true,
|
@@ -425,21 +366,11 @@ class Component extends Base {
|
|
425
366
|
}
|
426
367
|
|
427
368
|
/**
|
428
|
-
*
|
429
|
-
*
|
430
|
-
*
|
431
|
-
* @member {Object} childUpdateCache={}
|
432
|
-
*/
|
433
|
-
childUpdateCache = {}
|
434
|
-
/**
|
435
|
-
* Stores the updateDepth while an update is running to enable checks for parent update collisions
|
436
|
-
* @member {Number|null} currentUpdateDepth=null
|
437
|
-
*/
|
438
|
-
currentUpdateDepth = null
|
439
|
-
/**
|
440
|
-
* @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
|
441
372
|
*/
|
442
|
-
|
373
|
+
isAwaitingMount = false
|
443
374
|
|
444
375
|
/**
|
445
376
|
* Convenience shortcut to access the App this component belongs to
|
@@ -467,6 +398,33 @@ class Component extends Base {
|
|
467
398
|
this._listeners = value
|
468
399
|
}
|
469
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
|
+
|
470
428
|
/**
|
471
429
|
* Convenience method to access the parent component
|
472
430
|
* @returns {Neo.component.Base|null}
|
@@ -517,21 +475,7 @@ class Component extends Base {
|
|
517
475
|
this.cls = cls
|
518
476
|
}
|
519
477
|
|
520
|
-
/**
|
521
|
-
* Convenience shortcut to add additional dom listeners
|
522
|
-
* @param {Object|Object[]} value
|
523
|
-
*/
|
524
|
-
addDomListeners(value) {
|
525
|
-
if (!Array.isArray(value)) {
|
526
|
-
value = [value]
|
527
|
-
}
|
528
|
-
|
529
|
-
let domListeners = this.domListeners;
|
530
|
-
|
531
|
-
domListeners.push(...value);
|
532
478
|
|
533
|
-
this.domListeners = domListeners
|
534
|
-
}
|
535
479
|
|
536
480
|
/**
|
537
481
|
* Either a string like 'color: red; background-color: blue;'
|
@@ -634,19 +578,7 @@ class Component extends Base {
|
|
634
578
|
this.cls = cls
|
635
579
|
}
|
636
580
|
|
637
|
-
/**
|
638
|
-
* Registers the domListeners inside the Neo.manager.DomEvent
|
639
|
-
* @param {Object[]} value
|
640
|
-
* @param {Object[]} oldValue
|
641
|
-
* @protected
|
642
|
-
*/
|
643
|
-
afterSetDomListeners(value, oldValue) {
|
644
|
-
let me = this;
|
645
581
|
|
646
|
-
if (value?.[0] || oldValue?.[0]) {
|
647
|
-
DomEventManager.updateDomListeners(me, value, oldValue)
|
648
|
-
}
|
649
|
-
}
|
650
582
|
|
651
583
|
/**
|
652
584
|
* Triggered after the droppable config got changed
|
@@ -670,29 +602,6 @@ class Component extends Base {
|
|
670
602
|
}
|
671
603
|
}
|
672
604
|
|
673
|
-
/**
|
674
|
-
* Triggered after the hasUnmountedVdomChanges config got changed
|
675
|
-
* @param {Boolean} value
|
676
|
-
* @param {Boolean} oldValue
|
677
|
-
* @protected
|
678
|
-
*/
|
679
|
-
afterSetHasUnmountedVdomChanges(value, oldValue) {
|
680
|
-
if (value || (!value && oldValue)) {
|
681
|
-
let parentIds = ComponentManager.getParentIds(this),
|
682
|
-
i = 0,
|
683
|
-
len = parentIds.length,
|
684
|
-
parent;
|
685
|
-
|
686
|
-
for (; i < len; i++) {
|
687
|
-
parent = Neo.getComponent(parentIds[i]);
|
688
|
-
|
689
|
-
if (parent) {
|
690
|
-
parent._hasUnmountedVdomChanges = value // silent update
|
691
|
-
}
|
692
|
-
}
|
693
|
-
}
|
694
|
-
}
|
695
|
-
|
696
605
|
/**
|
697
606
|
* Triggered after the height config got changed
|
698
607
|
* @param {Number|String|null} value
|
@@ -786,16 +695,6 @@ class Component extends Base {
|
|
786
695
|
}
|
787
696
|
}
|
788
697
|
|
789
|
-
/**
|
790
|
-
* Triggered after the isVdomUpdating config got changed
|
791
|
-
* @param {Number|null} value
|
792
|
-
* @param {Number|null} oldValue
|
793
|
-
* @protected
|
794
|
-
*/
|
795
|
-
afterSetIsVdomUpdating(value, oldValue) {
|
796
|
-
this.currentUpdateDepth = value ? this.updateDepth : null
|
797
|
-
}
|
798
|
-
|
799
698
|
/**
|
800
699
|
* Triggered after the maxHeight config got changed
|
801
700
|
* @param {Number|String|null} value
|
@@ -851,17 +750,10 @@ class Component extends Base {
|
|
851
750
|
let me = this,
|
852
751
|
{id, windowId} = me;
|
853
752
|
|
854
|
-
if (value) {
|
753
|
+
if (value) { // mount
|
855
754
|
me.hasBeenMounted = true;
|
856
755
|
|
857
|
-
|
858
|
-
// todo: the main thread reply of mount arrives after pushing the task into the queue which does not ensure the dom is mounted
|
859
|
-
me.timeout(150).then(() => {
|
860
|
-
DomEventManager.mountDomListeners(me)
|
861
|
-
})
|
862
|
-
}
|
863
|
-
|
864
|
-
me.doResolveUpdateCache();
|
756
|
+
me.initDomEvents();
|
865
757
|
|
866
758
|
if (me.floating) {
|
867
759
|
me.alignTo();
|
@@ -870,9 +762,15 @@ class Component extends Base {
|
|
870
762
|
me.focus(id, true)
|
871
763
|
}
|
872
764
|
|
873
|
-
me.
|
874
|
-
|
875
|
-
|
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;
|
876
774
|
}
|
877
775
|
}
|
878
776
|
}
|
@@ -1071,26 +969,6 @@ class Component extends Base {
|
|
1071
969
|
me.cls = cls
|
1072
970
|
}
|
1073
971
|
|
1074
|
-
/**
|
1075
|
-
* Triggered after the vdom pseudo-config got changed
|
1076
|
-
* @param {Object} value
|
1077
|
-
* @param {Object|null} oldValue
|
1078
|
-
* @protected
|
1079
|
-
*/
|
1080
|
-
afterSetVdom(value, oldValue) {
|
1081
|
-
this.updateVdom()
|
1082
|
-
}
|
1083
|
-
|
1084
|
-
/**
|
1085
|
-
* Triggered after the vnode config got changed
|
1086
|
-
* @param {Object} value
|
1087
|
-
* @param {Object|null} oldValue
|
1088
|
-
* @protected
|
1089
|
-
*/
|
1090
|
-
afterSetVnode(value, oldValue) {
|
1091
|
-
oldValue !== undefined && this.syncVnodeTree()
|
1092
|
-
}
|
1093
|
-
|
1094
972
|
/**
|
1095
973
|
* Triggered after the width config got changed
|
1096
974
|
* @param {Number|String|null} value
|
@@ -1486,22 +1364,6 @@ class Component extends Base {
|
|
1486
1364
|
}
|
1487
1365
|
}
|
1488
1366
|
|
1489
|
-
/**
|
1490
|
-
* Convenience shortcut to create a component reference
|
1491
|
-
* @returns {Object}
|
1492
|
-
*/
|
1493
|
-
createVdomReference() {
|
1494
|
-
let me = this,
|
1495
|
-
reference = {componentId: me.id},
|
1496
|
-
vdomId = me.vdom.id;
|
1497
|
-
|
1498
|
-
if (vdomId && me.id !== vdomId) {
|
1499
|
-
reference.id = vdomId
|
1500
|
-
}
|
1501
|
-
|
1502
|
-
return reference
|
1503
|
-
}
|
1504
|
-
|
1505
1367
|
/**
|
1506
1368
|
* Unregister this instance from the ComponentManager
|
1507
1369
|
* @param {Boolean} updateParentVdom=false true to remove the component from the parent vdom => real dom
|
@@ -1509,14 +1371,13 @@ class Component extends Base {
|
|
1509
1371
|
* todo: unregister events
|
1510
1372
|
*/
|
1511
1373
|
destroy(updateParentVdom=false, silent=false) {
|
1512
|
-
let me
|
1513
|
-
{parent, parentId}
|
1514
|
-
parentStateProvider = parent?.getStateProvider(),
|
1374
|
+
let me = this,
|
1375
|
+
{parent, parentId} = me,
|
1515
1376
|
parentVdom;
|
1516
1377
|
|
1517
1378
|
me.revertFocus();
|
1518
1379
|
|
1519
|
-
me.
|
1380
|
+
me.removeDomEvents();
|
1520
1381
|
|
1521
1382
|
me.controller = null; // triggers destroy()
|
1522
1383
|
|
@@ -1524,8 +1385,6 @@ class Component extends Base {
|
|
1524
1385
|
|
1525
1386
|
me.stateProvider = null; // triggers destroy()
|
1526
1387
|
|
1527
|
-
me.bind && parentStateProvider?.removeBindings(me.id);
|
1528
|
-
|
1529
1388
|
me.plugins?.forEach(plugin => {
|
1530
1389
|
plugin.destroy()
|
1531
1390
|
});
|
@@ -1550,18 +1409,6 @@ class Component extends Base {
|
|
1550
1409
|
me.unmount = Neo.emptyFn
|
1551
1410
|
}
|
1552
1411
|
|
1553
|
-
/**
|
1554
|
-
* Triggers all stored resolve() callbacks
|
1555
|
-
*/
|
1556
|
-
doResolveUpdateCache() {
|
1557
|
-
let me = this;
|
1558
|
-
|
1559
|
-
if (me.resolveUpdateCache) {
|
1560
|
-
me.resolveUpdateCache.forEach(item => item());
|
1561
|
-
me.resolveUpdateCache = []
|
1562
|
-
}
|
1563
|
-
}
|
1564
|
-
|
1565
1412
|
/**
|
1566
1413
|
* Convenience shortcut for Neo.manager.Component.down
|
1567
1414
|
* @param {Object|String} config
|
@@ -1572,59 +1419,6 @@ class Component extends Base {
|
|
1572
1419
|
return ComponentManager.down(this, config, returnFirstMatch)
|
1573
1420
|
}
|
1574
1421
|
|
1575
|
-
/**
|
1576
|
-
* Internal method to send update requests to the vdom worker
|
1577
|
-
* @param {function} [resolve] used by promiseUpdate()
|
1578
|
-
* @param {function} [reject] used by promiseUpdate()
|
1579
|
-
* @private
|
1580
|
-
*/
|
1581
|
-
#executeVdomUpdate(resolve, reject) {
|
1582
|
-
let me = this,
|
1583
|
-
{vdom, vnode} = me,
|
1584
|
-
opts = {},
|
1585
|
-
deltas;
|
1586
|
-
|
1587
|
-
if (currentWorker.isSharedWorker) {
|
1588
|
-
opts.appName = me.appName;
|
1589
|
-
opts.windowId = me.windowId
|
1590
|
-
}
|
1591
|
-
|
1592
|
-
me.isVdomUpdating = true;
|
1593
|
-
|
1594
|
-
// we can not set the config directly => it could already be false,
|
1595
|
-
// and we still want to pass it further into subtrees
|
1596
|
-
me._needsVdomUpdate = false;
|
1597
|
-
me.afterSetNeedsVdomUpdate?.(false, true);
|
1598
|
-
|
1599
|
-
opts.vdom = ComponentManager.getVdomTree(vdom, me.updateDepth);
|
1600
|
-
opts.vnode = ComponentManager.getVnodeTree(vnode, me.updateDepth);
|
1601
|
-
|
1602
|
-
// Reset the updateDepth to the default value for the next update cycle
|
1603
|
-
me._updateDepth = me.constructor.config.updateDepth;
|
1604
|
-
|
1605
|
-
Neo.vdom.Helper.update(opts).catch(err => {
|
1606
|
-
me.isVdomUpdating = false;
|
1607
|
-
reject?.()
|
1608
|
-
}).then(data => {
|
1609
|
-
// Checking if the component got destroyed before the update cycle is done
|
1610
|
-
if (me.id) {
|
1611
|
-
// It is crucial to delegate the vnode tree before resolving the cycle
|
1612
|
-
me.vnode = data.vnode;
|
1613
|
-
me.isVdomUpdating = false;
|
1614
|
-
|
1615
|
-
deltas = data.deltas;
|
1616
|
-
|
1617
|
-
if (!Neo.config.useVdomWorker && deltas.length > 0) {
|
1618
|
-
Neo.applyDeltas(me.appName, deltas).then(() => {
|
1619
|
-
me.resolveVdomUpdate(resolve)
|
1620
|
-
})
|
1621
|
-
} else {
|
1622
|
-
me.resolveVdomUpdate(resolve)
|
1623
|
-
}
|
1624
|
-
}
|
1625
|
-
})
|
1626
|
-
}
|
1627
|
-
|
1628
1422
|
/**
|
1629
1423
|
* Calls focus() on the top level DOM node of this component or on a given node via id
|
1630
1424
|
* @param {String} id=this.id
|
@@ -1670,7 +1464,8 @@ class Component extends Base {
|
|
1670
1464
|
}
|
1671
1465
|
|
1672
1466
|
if (parentComponent) {
|
1673
|
-
|
1467
|
+
// todo: We need ?. until functional.component.Base supports controllers
|
1468
|
+
return parentComponent.getConfigInstanceByNtype?.(configName, ntype)
|
1674
1469
|
}
|
1675
1470
|
|
1676
1471
|
return null
|
@@ -1718,43 +1513,6 @@ class Component extends Base {
|
|
1718
1513
|
return Rectangle.clone(result)
|
1719
1514
|
}
|
1720
1515
|
|
1721
|
-
/**
|
1722
|
-
* Honors different item roots for mount / render OPs
|
1723
|
-
* @returns {String}
|
1724
|
-
*/
|
1725
|
-
getMountedParentId() {
|
1726
|
-
let parentId = this.parentId,
|
1727
|
-
parent = Neo.getComponent(parentId),
|
1728
|
-
itemsRoot = parent?.getVdomItemsRoot?.();
|
1729
|
-
|
1730
|
-
return itemsRoot ? itemsRoot.id : parentId
|
1731
|
-
}
|
1732
|
-
|
1733
|
-
/**
|
1734
|
-
* Calculate the real parentIndex inside the DOM
|
1735
|
-
* @returns {Number|undefined}
|
1736
|
-
*/
|
1737
|
-
getMountedParentIndex() {
|
1738
|
-
let parent = this.parent,
|
1739
|
-
items = parent?.items || [],
|
1740
|
-
i = 0,
|
1741
|
-
index = 0,
|
1742
|
-
len = items.length,
|
1743
|
-
item;
|
1744
|
-
|
1745
|
-
for (; i < len; i++) {
|
1746
|
-
item = items[i];
|
1747
|
-
|
1748
|
-
if (item === this) {
|
1749
|
-
return index
|
1750
|
-
}
|
1751
|
-
|
1752
|
-
if (!item.hidden && item.hideMode === 'removeDom') {
|
1753
|
-
index++
|
1754
|
-
}
|
1755
|
-
}
|
1756
|
-
}
|
1757
|
-
|
1758
1516
|
/**
|
1759
1517
|
* Get the parent components as an array
|
1760
1518
|
* @returns {Neo.component.Base[]}
|
@@ -1877,44 +1635,6 @@ class Component extends Base {
|
|
1877
1635
|
return Neo.config.themes?.[0]
|
1878
1636
|
}
|
1879
1637
|
|
1880
|
-
/**
|
1881
|
-
* Search a vdom child node by id for a given vdom tree
|
1882
|
-
* @param {String} id
|
1883
|
-
* @param {Object} vdom=this.vdom
|
1884
|
-
* @returns {Object}
|
1885
|
-
*/
|
1886
|
-
getVdomChild(id, vdom=this.vdom) {
|
1887
|
-
return VDomUtil.find(vdom, id)?.vdom
|
1888
|
-
}
|
1889
|
-
|
1890
|
-
/**
|
1891
|
-
* Specify a different vdom root if needed to apply the top level style attributes on a different level.
|
1892
|
-
* Make sure to use getVnodeRoot() as well, to keep the vdom & vnode trees in sync.
|
1893
|
-
* @returns {Object} The new vdom root
|
1894
|
-
*/
|
1895
|
-
getVdomRoot() {
|
1896
|
-
return this.vdom
|
1897
|
-
}
|
1898
|
-
|
1899
|
-
/**
|
1900
|
-
* Specify a different vnode root if needed to apply the top level style attributes on a different level.
|
1901
|
-
* Make sure to use getVdomRoot() as well, to keep the vdom & vnode trees in sync.
|
1902
|
-
* @returns {Object} The new vnode root
|
1903
|
-
*/
|
1904
|
-
getVnodeRoot() {
|
1905
|
-
return this.vnode
|
1906
|
-
}
|
1907
|
-
|
1908
|
-
/**
|
1909
|
-
* Checks if a given updateDepth & distance would result in an update collision
|
1910
|
-
* @param {Number} updateDepth
|
1911
|
-
* @param {Number} distance
|
1912
|
-
* @returns {Boolean}
|
1913
|
-
*/
|
1914
|
-
hasUpdateCollision(updateDepth, distance) {
|
1915
|
-
return updateDepth === -1 ? true : distance < updateDepth
|
1916
|
-
}
|
1917
|
-
|
1918
1638
|
/**
|
1919
1639
|
* Hide the component.
|
1920
1640
|
* hideMode: 'removeDom' uses vdom removeDom.
|
@@ -1983,45 +1703,6 @@ class Component extends Base {
|
|
1983
1703
|
return me.parent.floating
|
1984
1704
|
}
|
1985
1705
|
|
1986
|
-
/**
|
1987
|
-
* Checks for vdom updates inside the parent chain and if found.
|
1988
|
-
* Registers the component for a vdom update once done.
|
1989
|
-
* @param {String} parentId=this.parentId
|
1990
|
-
* @param {Function} [resolve] Gets passed by updateVdom()
|
1991
|
-
* @param {Number} distance=1 Distance inside the component tree
|
1992
|
-
* @returns {Boolean}
|
1993
|
-
*/
|
1994
|
-
isParentUpdating(parentId=this.parentId, resolve, distance=1) {
|
1995
|
-
if (parentId !== 'document.body') {
|
1996
|
-
let me = this,
|
1997
|
-
parent = Neo.getComponent(parentId);
|
1998
|
-
|
1999
|
-
if (parent) {
|
2000
|
-
if (parent.isVdomUpdating) {
|
2001
|
-
if (me.hasUpdateCollision(parent.currentUpdateDepth, distance)) {
|
2002
|
-
if (Neo.config.logVdomUpdateCollisions) {
|
2003
|
-
console.warn('vdom parent update conflict with:', parent, 'for:', me)
|
2004
|
-
}
|
2005
|
-
|
2006
|
-
parent.childUpdateCache[me.id] = {distance, resolve};
|
2007
|
-
|
2008
|
-
// Adding the resolve fn to its own cache, since the parent will trigger
|
2009
|
-
// a new update() directly on this cmp
|
2010
|
-
resolve && me.resolveUpdateCache.push(resolve);
|
2011
|
-
return true
|
2012
|
-
}
|
2013
|
-
|
2014
|
-
// If an update is running and does not have a collision, we do not need to check further parents
|
2015
|
-
return false
|
2016
|
-
}
|
2017
|
-
|
2018
|
-
return me.isParentUpdating(parent.parentId, resolve, distance+1)
|
2019
|
-
}
|
2020
|
-
}
|
2021
|
-
|
2022
|
-
return false
|
2023
|
-
}
|
2024
|
-
|
2025
1706
|
/**
|
2026
1707
|
* @param {Number|String} value
|
2027
1708
|
* @returns {Promise<number>}
|
@@ -2109,34 +1790,6 @@ class Component extends Base {
|
|
2109
1790
|
}
|
2110
1791
|
}
|
2111
1792
|
|
2112
|
-
/**
|
2113
|
-
* Checks the needsVdomUpdate config inside the parent tree
|
2114
|
-
* @param {String} parentId=this.parentId
|
2115
|
-
* @param {Function} [resolve] gets passed by updateVdom()
|
2116
|
-
* @param {Number} distance=1 Distance inside the component tree
|
2117
|
-
* @returns {Boolean}
|
2118
|
-
*/
|
2119
|
-
needsParentUpdate(parentId=this.parentId, resolve, distance=1) {
|
2120
|
-
if (parentId !== 'document.body') {
|
2121
|
-
let me = this,
|
2122
|
-
parent = Neo.getComponent(parentId);
|
2123
|
-
|
2124
|
-
if (parent) {
|
2125
|
-
// We are checking for parent.updateDepth, since we care about the depth of the next update cycle
|
2126
|
-
if (parent.needsVdomUpdate && me.hasUpdateCollision(parent.updateDepth, distance)) {
|
2127
|
-
parent.resolveUpdateCache.push(...me.resolveUpdateCache);
|
2128
|
-
resolve && parent.resolveUpdateCache.push(resolve);
|
2129
|
-
me.resolveUpdateCache = [];
|
2130
|
-
return true
|
2131
|
-
}
|
2132
|
-
|
2133
|
-
return me.needsParentUpdate(parent.parentId, resolve, distance+1)
|
2134
|
-
}
|
2135
|
-
}
|
2136
|
-
|
2137
|
-
return false
|
2138
|
-
}
|
2139
|
-
|
2140
1793
|
/**
|
2141
1794
|
*
|
2142
1795
|
*/
|
@@ -2188,65 +1841,6 @@ class Component extends Base {
|
|
2188
1841
|
* @param {Array} opts.oldPath dom element ids upwards
|
2189
1842
|
*/
|
2190
1843
|
|
2191
|
-
/**
|
2192
|
-
* Gets called from the render() promise success handler
|
2193
|
-
* @param {Object} vnode
|
2194
|
-
* @param {Boolean} autoMount Mount the DOM after the vnode got created
|
2195
|
-
* @protected
|
2196
|
-
*/
|
2197
|
-
onRender(vnode, autoMount) {
|
2198
|
-
let me = this,
|
2199
|
-
{app} = me;
|
2200
|
-
|
2201
|
-
me.rendering = false;
|
2202
|
-
|
2203
|
-
// if app is a check to see if the Component got destroyed while rendering => before onRender got triggered
|
2204
|
-
if (app) {
|
2205
|
-
if (!app.rendered) {
|
2206
|
-
app.rendering = false;
|
2207
|
-
app.rendered = true;
|
2208
|
-
app.fire('render')
|
2209
|
-
}
|
2210
|
-
|
2211
|
-
me.vnode = vnode;
|
2212
|
-
|
2213
|
-
let childIds = ComponentManager.getChildIds(vnode),
|
2214
|
-
i = 0,
|
2215
|
-
len = childIds.length,
|
2216
|
-
child;
|
2217
|
-
|
2218
|
-
for (; i < len; i++) {
|
2219
|
-
child = Neo.getComponent(childIds[i]);
|
2220
|
-
|
2221
|
-
if (child) {
|
2222
|
-
child.rendered = true
|
2223
|
-
}
|
2224
|
-
}
|
2225
|
-
|
2226
|
-
me._rendered = true; // silent update
|
2227
|
-
me.fire('rendered', me.id);
|
2228
|
-
|
2229
|
-
if (autoMount) {
|
2230
|
-
me.mounted = true;
|
2231
|
-
|
2232
|
-
if (!app.mounted) {
|
2233
|
-
app.mounted = true;
|
2234
|
-
app.fire('mounted')
|
2235
|
-
}
|
2236
|
-
}
|
2237
|
-
}
|
2238
|
-
}
|
2239
|
-
|
2240
|
-
/**
|
2241
|
-
* Promise based vdom update
|
2242
|
-
* @returns {Promise<any>}
|
2243
|
-
*/
|
2244
|
-
promiseUpdate() {
|
2245
|
-
return new Promise((resolve, reject) => {
|
2246
|
-
this.updateVdom(resolve, reject)
|
2247
|
-
})
|
2248
|
-
}
|
2249
|
-
|
2250
1844
|
/**
|
2251
1845
|
* Remove a cls from the vdomRoot
|
2252
1846
|
* @param {String} value
|
@@ -2258,32 +1852,7 @@ class Component extends Base {
|
|
2258
1852
|
this.cls = cls
|
2259
1853
|
}
|
2260
1854
|
|
2261
|
-
/**
|
2262
|
-
* @param {Array|Object} value
|
2263
|
-
*/
|
2264
|
-
removeDomListeners(value) {
|
2265
|
-
if (!Array.isArray(value)) {
|
2266
|
-
value = [value];
|
2267
|
-
}
|
2268
|
-
|
2269
|
-
let me = this,
|
2270
|
-
{domListeners} = me,
|
2271
|
-
i, len;
|
2272
1855
|
|
2273
|
-
value.forEach(item => {
|
2274
|
-
i = 0;
|
2275
|
-
len = domListeners.length;
|
2276
|
-
|
2277
|
-
for (; i < len; i++) {
|
2278
|
-
if (Neo.isEqual(item, domListeners[i])) {
|
2279
|
-
domListeners.splice(i, 1);
|
2280
|
-
break
|
2281
|
-
}
|
2282
|
-
}
|
2283
|
-
});
|
2284
|
-
|
2285
|
-
me.domListeners = domListeners
|
2286
|
-
}
|
2287
1856
|
|
2288
1857
|
/**
|
2289
1858
|
* Either a string like 'color' or an array containing style attributes to remove
|
@@ -2312,110 +1881,6 @@ class Component extends Base {
|
|
2312
1881
|
return style
|
2313
1882
|
}
|
2314
1883
|
|
2315
|
-
/**
|
2316
|
-
* Creates the vnode tree for this component and mounts the component in case
|
2317
|
-
* - you pass true for the mount param
|
2318
|
-
* - or the autoMount config is set to true
|
2319
|
-
* @param {Boolean} [mount] Mount the DOM after the vnode got created
|
2320
|
-
*/
|
2321
|
-
async render(mount) {
|
2322
|
-
let me = this,
|
2323
|
-
autoMount = mount || me.autoMount,
|
2324
|
-
{app} = me,
|
2325
|
-
{unitTestMode, useVdomWorker} = Neo.config;
|
2326
|
-
|
2327
|
-
if (unitTestMode) return;
|
2328
|
-
|
2329
|
-
// Verify that the critical rendering path => CSS files for the new tree is in place
|
2330
|
-
if (autoMount && currentWorker.countLoadingThemeFiles !== 0) {
|
2331
|
-
currentWorker.on('themeFilesLoaded', function() {
|
2332
|
-
!me.mounted && me.render(mount)
|
2333
|
-
}, me, {once: true});
|
2334
|
-
|
2335
|
-
return
|
2336
|
-
}
|
2337
|
-
|
2338
|
-
me.rendering = true;
|
2339
|
-
|
2340
|
-
if (!app.rendered) {
|
2341
|
-
app.rendering = true
|
2342
|
-
}
|
2343
|
-
|
2344
|
-
if (me.vdom) {
|
2345
|
-
me.isVdomUpdating = true;
|
2346
|
-
|
2347
|
-
delete me.vdom.removeDom;
|
2348
|
-
|
2349
|
-
me._needsVdomUpdate = false;
|
2350
|
-
me.afterSetNeedsVdomUpdate?.(false, true);
|
2351
|
-
|
2352
|
-
const data = await Neo.vdom.Helper.create({
|
2353
|
-
appName : me.appName,
|
2354
|
-
autoMount,
|
2355
|
-
parentId : autoMount ? me.getMountedParentId() : undefined,
|
2356
|
-
parentIndex: autoMount ? me.getMountedParentIndex() : undefined,
|
2357
|
-
vdom : ComponentManager.getVdomTree(me.vdom),
|
2358
|
-
windowId : me.windowId
|
2359
|
-
});
|
2360
|
-
|
2361
|
-
me.onRender(data.vnode, useVdomWorker ? autoMount : false);
|
2362
|
-
me.isVdomUpdating = false;
|
2363
|
-
|
2364
|
-
autoMount && !useVdomWorker && me.mount();
|
2365
|
-
|
2366
|
-
me.resolveVdomUpdate()
|
2367
|
-
}
|
2368
|
-
}
|
2369
|
-
|
2370
|
-
/**
|
2371
|
-
* Internal helper fn to resolve the Promise for updateVdom()
|
2372
|
-
* @param {Function|undefined} resolve
|
2373
|
-
* @protected
|
2374
|
-
*/
|
2375
|
-
resolveVdomUpdate(resolve) {
|
2376
|
-
let me = this,
|
2377
|
-
hasChildUpdateCache = !Neo.isEmpty(me.childUpdateCache),
|
2378
|
-
component;
|
2379
|
-
|
2380
|
-
me.doResolveUpdateCache();
|
2381
|
-
|
2382
|
-
resolve?.();
|
2383
|
-
|
2384
|
-
if (me.needsVdomUpdate) {
|
2385
|
-
if (hasChildUpdateCache) {
|
2386
|
-
Object.entries(me.childUpdateCache).forEach(([key, value]) => {
|
2387
|
-
component = Neo.getComponent(key);
|
2388
|
-
|
2389
|
-
// The component might already got destroyed
|
2390
|
-
if (component) {
|
2391
|
-
// Pass callbacks to the resolver cache => getting executed once the following update is done
|
2392
|
-
value.resolve && NeoArray.add(me.resolveUpdateCache, value.resolve);
|
2393
|
-
|
2394
|
-
// Adjust the updateDepth to include the depth of all merged child updates
|
2395
|
-
if (me.updateDepth !== -1) {
|
2396
|
-
if (component.updateDepth === -1) {
|
2397
|
-
me.updateDepth = -1
|
2398
|
-
} else {
|
2399
|
-
// Since updateDepth is 1-based, we need to subtract 1 level
|
2400
|
-
me.updateDepth = me.updateDepth + value.distance + component.updateDepth - 1
|
2401
|
-
}
|
2402
|
-
}
|
2403
|
-
}
|
2404
|
-
});
|
2405
|
-
|
2406
|
-
me.childUpdateCache = {}
|
2407
|
-
}
|
2408
|
-
|
2409
|
-
me.update()
|
2410
|
-
} else if (hasChildUpdateCache) {
|
2411
|
-
Object.keys(me.childUpdateCache).forEach(key => {
|
2412
|
-
Neo.getComponent(key)?.update()
|
2413
|
-
});
|
2414
|
-
|
2415
|
-
me.childUpdateCache = {}
|
2416
|
-
}
|
2417
|
-
}
|
2418
|
-
|
2419
1884
|
/**
|
2420
1885
|
*
|
2421
1886
|
*/
|
@@ -2434,33 +1899,33 @@ class Component extends Base {
|
|
2434
1899
|
* @returns {Promise<*>}
|
2435
1900
|
*/
|
2436
1901
|
set(values={}, silent=false) {
|
2437
|
-
|
2438
|
-
|
2439
|
-
|
2440
|
-
me.silentVdomUpdate = true;
|
2441
|
-
|
2442
|
-
super.set(values);
|
1902
|
+
const
|
1903
|
+
me = this,
|
1904
|
+
wasHidden = me.hidden;
|
2443
1905
|
|
2444
|
-
me.
|
1906
|
+
me.setSilent(values);
|
2445
1907
|
|
2446
|
-
if (silent
|
2447
|
-
|
2448
|
-
} else {
|
2449
|
-
if (needsRendering) {
|
1908
|
+
if (!silent && me.needsVdomUpdate) {
|
1909
|
+
if (wasHidden && !me.hidden) {
|
2450
1910
|
me.show();
|
2451
1911
|
return Promise.resolve()
|
2452
1912
|
}
|
2453
1913
|
|
2454
1914
|
return me.promiseUpdate()
|
2455
1915
|
}
|
1916
|
+
|
1917
|
+
return Promise.resolve()
|
2456
1918
|
}
|
2457
1919
|
|
2458
1920
|
/**
|
2459
|
-
*
|
1921
|
+
* A silent version of set(), which does not trigger a vdom update at the end.
|
1922
|
+
* Useful for batching multiple config changes.
|
2460
1923
|
* @param {Object} values={}
|
2461
1924
|
*/
|
2462
|
-
setSilent(values
|
2463
|
-
|
1925
|
+
setSilent(values={}) {
|
1926
|
+
this.silentVdomUpdate = true;
|
1927
|
+
super.set(values);
|
1928
|
+
this.silentVdomUpdate = false
|
2464
1929
|
}
|
2465
1930
|
|
2466
1931
|
/**
|
@@ -2499,78 +1964,6 @@ class Component extends Base {
|
|
2499
1964
|
me._hidden = false
|
2500
1965
|
}
|
2501
1966
|
|
2502
|
-
/**
|
2503
|
-
* Placeholder method for util.VDom.syncVdomIds to allow overriding (disabling) it
|
2504
|
-
* @param {Neo.vdom.VNode} [vnode=this.vnode]
|
2505
|
-
* @param {Object} [vdom=this.vdom]
|
2506
|
-
* @param {Boolean} force=false
|
2507
|
-
*/
|
2508
|
-
syncVdomIds(vnode=this.vnode, vdom=this.vdom, force=false) {
|
2509
|
-
VDomUtil.syncVdomIds(vnode, vdom, force)
|
2510
|
-
}
|
2511
|
-
|
2512
|
-
/**
|
2513
|
-
* In case a component receives a new vnode, we want to do:
|
2514
|
-
* - sync the vdom ids
|
2515
|
-
* - setting rendered to true for child components
|
2516
|
-
* - updating the parent component to ensure that the vnode tree stays persistent
|
2517
|
-
* @param {Neo.vdom.VNode} [vnode=this.vnode]
|
2518
|
-
*/
|
2519
|
-
syncVnodeTree(vnode=this.vnode) {
|
2520
|
-
let me = this,
|
2521
|
-
childComponents = ComponentManager.getChildren(me),
|
2522
|
-
debug = false,
|
2523
|
-
map = {},
|
2524
|
-
childVnode, start;
|
2525
|
-
|
2526
|
-
if (debug) {
|
2527
|
-
start = performance.now()
|
2528
|
-
}
|
2529
|
-
|
2530
|
-
me.syncVdomIds();
|
2531
|
-
|
2532
|
-
if (vnode && me.id !== vnode.id) {
|
2533
|
-
ComponentManager.registerWrapperNode(vnode.id, me)
|
2534
|
-
}
|
2535
|
-
|
2536
|
-
// we need one separate iteration first to ensure all wrapper nodes get registered
|
2537
|
-
childComponents.forEach(component => {
|
2538
|
-
childVnode = VNodeUtil.find(me.vnode, component.vdom.id)?.vnode;
|
2539
|
-
|
2540
|
-
if (childVnode) {
|
2541
|
-
map[component.id] = childVnode;
|
2542
|
-
|
2543
|
-
if (component.id !== childVnode.id) {
|
2544
|
-
ComponentManager.registerWrapperNode(childVnode.id, component)
|
2545
|
-
}
|
2546
|
-
}
|
2547
|
-
});
|
2548
|
-
|
2549
|
-
// delegate the latest node updates to all possible child components found inside the vnode tree
|
2550
|
-
childComponents.forEach(component => {
|
2551
|
-
childVnode = map[component.id];
|
2552
|
-
|
2553
|
-
if (childVnode) {
|
2554
|
-
// silent update
|
2555
|
-
component._vnode = ComponentManager.addVnodeComponentReferences(childVnode, component.id);
|
2556
|
-
|
2557
|
-
if (!component.rendered) {
|
2558
|
-
component._rendered = true;
|
2559
|
-
component.fire('rendered', component.id)
|
2560
|
-
}
|
2561
|
-
|
2562
|
-
component.mounted = true
|
2563
|
-
} else {
|
2564
|
-
console.warn('syncVnodeTree: Could not replace the child vnode for', component.id)
|
2565
|
-
}
|
2566
|
-
});
|
2567
|
-
|
2568
|
-
// silent update
|
2569
|
-
me._vnode = vnode ? ComponentManager.addVnodeComponentReferences(vnode, me.id) : null;
|
2570
|
-
|
2571
|
-
debug && console.log('syncVnodeTree', me.id, performance.now() - start)
|
2572
|
-
}
|
2573
|
-
|
2574
1967
|
/**
|
2575
1968
|
* Toggle a cls inside the vdomRoot of the component
|
2576
1969
|
* @param {String} value
|
@@ -2606,13 +1999,6 @@ class Component extends Base {
|
|
2606
1999
|
return ComponentManager.up(this.id, config)
|
2607
2000
|
}
|
2608
2001
|
|
2609
|
-
/**
|
2610
|
-
*
|
2611
|
-
*/
|
2612
|
-
update() {
|
2613
|
-
this.afterSetVdom(this.vdom, null)
|
2614
|
-
}
|
2615
|
-
|
2616
2002
|
/**
|
2617
2003
|
*
|
2618
2004
|
*/
|
@@ -2631,59 +2017,6 @@ class Component extends Base {
|
|
2631
2017
|
me.update()
|
2632
2018
|
}
|
2633
2019
|
|
2634
|
-
/**
|
2635
|
-
* Gets called after the vdom config gets changed in case the component is already mounted (delta updates).
|
2636
|
-
* @param {function} [resolve] used by promiseUpdate()
|
2637
|
-
* @param {function} [reject] used by promiseUpdate()
|
2638
|
-
* @protected
|
2639
|
-
*/
|
2640
|
-
updateVdom(resolve, reject) {
|
2641
|
-
if (Neo.config.unitTestMode) {
|
2642
|
-
reject?.();
|
2643
|
-
return
|
2644
|
-
}
|
2645
|
-
|
2646
|
-
let me = this,
|
2647
|
-
{app, mounted, parentId, vnode} = me;
|
2648
|
-
|
2649
|
-
if (me.isVdomUpdating || me.silentVdomUpdate) {
|
2650
|
-
resolve && me.resolveUpdateCache.push(resolve);
|
2651
|
-
me.needsVdomUpdate = true
|
2652
|
-
} else {
|
2653
|
-
if (!mounted && me.isConstructed && !me.hasRenderingListener && app?.rendering === true) {
|
2654
|
-
me.hasRenderingListener = true;
|
2655
|
-
|
2656
|
-
app.on('mounted', () => {
|
2657
|
-
me.timeout(50).then(() => {
|
2658
|
-
me.vnode && me.updateVdom(resolve, reject)
|
2659
|
-
})
|
2660
|
-
}, me, {once: true})
|
2661
|
-
} else {
|
2662
|
-
if (resolve && (!mounted || !vnode)) {
|
2663
|
-
me.resolveUpdateCache.push(resolve)
|
2664
|
-
}
|
2665
|
-
|
2666
|
-
if (
|
2667
|
-
!me.needsParentUpdate(parentId, resolve)
|
2668
|
-
&& !me.isParentUpdating(parentId, resolve)
|
2669
|
-
&& mounted
|
2670
|
-
&& vnode
|
2671
|
-
) {
|
2672
|
-
// Verify that the critical rendering path => CSS files for the new tree is in place
|
2673
|
-
if (currentWorker.countLoadingThemeFiles !== 0) {
|
2674
|
-
currentWorker.on('themeFilesLoaded', function() {
|
2675
|
-
me.updateVdom(resolve, reject)
|
2676
|
-
}, me, {once: true})
|
2677
|
-
} else {
|
2678
|
-
me.#executeVdomUpdate(resolve, reject)
|
2679
|
-
}
|
2680
|
-
}
|
2681
|
-
}
|
2682
|
-
}
|
2683
|
-
|
2684
|
-
me.hasUnmountedVdomChanges = !mounted && me.hasBeenMounted
|
2685
|
-
}
|
2686
|
-
|
2687
2020
|
/**
|
2688
2021
|
* In case you are sure a DOMRect exists, use getDomRect()
|
2689
2022
|
* Otherwise you can wait for it using this method.
|