@shortfuse/materialdesignweb 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -24
- package/bin/mdw-css.js +1 -1
- package/components/Badge.js +12 -5
- package/components/Body.js +3 -0
- package/components/BottomAppBar.js +1 -8
- package/components/BottomSheet.js +424 -0
- package/components/Box.js +11 -49
- package/components/Button.js +61 -82
- package/components/Card.js +56 -61
- package/components/Checkbox.js +7 -25
- package/components/CheckboxIcon.js +10 -28
- package/components/Chip.js +13 -11
- package/components/Dialog.js +49 -98
- package/components/Display.js +55 -0
- package/components/Fab.js +83 -17
- package/components/FabContainer.js +48 -0
- package/components/FilterChip.js +34 -32
- package/components/Grid.js +176 -0
- package/components/Headline.js +5 -28
- package/components/Icon.js +54 -69
- package/components/IconButton.js +71 -120
- package/components/Input.js +669 -83
- package/components/InputChip.js +161 -0
- package/components/Label.js +3 -0
- package/components/List.js +1 -5
- package/components/ListItem.js +39 -23
- package/components/ListOption.js +79 -62
- package/components/Listbox.js +19 -10
- package/components/Menu.js +8 -18
- package/components/MenuItem.js +25 -26
- package/components/NavBar.js +53 -19
- package/components/NavDrawer.js +15 -15
- package/components/NavDrawerItem.js +2 -4
- package/components/NavItem.js +40 -33
- package/components/NavRail.js +23 -21
- package/components/NavRailItem.js +5 -2
- package/components/Page.js +105 -0
- package/components/Pane.js +18 -0
- package/components/Popup.js +17 -8
- package/components/Radio.js +2 -5
- package/components/RadioIcon.js +10 -14
- package/components/Ripple.js +11 -7
- package/components/Root.js +209 -0
- package/components/Scrim.js +87 -0
- package/components/Search.js +12 -20
- package/components/SegmentedButton.js +33 -36
- package/components/SegmentedButtonGroup.js +9 -3
- package/components/Select.js +6 -7
- package/components/Shape.js +5 -65
- package/components/SideSheet.js +308 -0
- package/components/Slider.js +71 -34
- package/components/Snackbar.js +22 -16
- package/components/SnackbarContainer.js +42 -0
- package/components/Surface.js +15 -10
- package/components/Switch.js +3 -16
- package/components/SwitchIcon.js +40 -32
- package/components/Tab.js +57 -38
- package/components/TabContent.js +1 -0
- package/components/TabList.js +60 -32
- package/components/TabPanel.js +1 -1
- package/components/Table.js +116 -0
- package/components/TextArea.js +16 -15
- package/components/Title.js +4 -9
- package/components/Tooltip.js +43 -21
- package/components/TopAppBar.js +56 -78
- package/constants/shapes.js +36 -0
- package/constants/typography.js +127 -0
- package/core/Composition.js +354 -192
- package/core/CompositionAdapter.js +11 -12
- package/core/CustomElement.js +588 -236
- package/core/css.js +117 -12
- package/core/customTypes.js +120 -25
- package/core/dom.js +17 -11
- package/core/jsonMergePatch.js +12 -10
- package/core/observe.js +298 -253
- package/core/optimizations.js +9 -9
- package/core/template.js +14 -57
- package/dist/index.min.js +85 -115
- package/dist/index.min.js.map +4 -4
- package/dist/meta.json +1 -1
- package/dom/HTMLOptionsCollectionProxy.js +106 -0
- package/{theming/themableMixinLoader.js → loaders/palette.js} +4 -3
- package/loaders/theme.js +12 -0
- package/mixins/AriaReflectorMixin.js +53 -13
- package/mixins/AriaToolbarMixin.js +3 -0
- package/mixins/ControlMixin.js +76 -33
- package/mixins/DelegatesFocusMixin.js +54 -0
- package/mixins/DensityMixin.js +2 -2
- package/mixins/ElevationMixin.js +62 -0
- package/mixins/FlexableMixin.js +66 -37
- package/mixins/FormAssociatedMixin.js +60 -8
- package/mixins/HyperlinkMixin.js +66 -0
- package/mixins/InputMixin.js +205 -32
- package/mixins/KeyboardNavMixin.js +8 -6
- package/mixins/NavigationListenerMixin.js +33 -0
- package/mixins/PopupMixin.js +176 -208
- package/mixins/ResizeObserverMixin.js +16 -4
- package/mixins/RippleMixin.js +8 -6
- package/mixins/ScrollListenerMixin.js +1 -1
- package/mixins/SemiStickyMixin.js +44 -98
- package/mixins/ShapeMaskedMixin.js +117 -0
- package/mixins/ShapeMixin.js +22 -204
- package/mixins/StateMixin.js +70 -34
- package/mixins/TextFieldMixin.js +107 -143
- package/mixins/ThemableMixin.js +44 -56
- package/mixins/TooltipTriggerMixin.js +291 -359
- package/mixins/TouchTargetMixin.js +1 -1
- package/mixins/TypographyMixin.js +121 -0
- package/package.json +110 -74
- package/services/rtl.js +10 -0
- package/services/svgAlias.js +17 -0
- package/{theming/index.js → services/theme.js} +24 -174
- package/types/bin/mdw-css.d.ts +3 -0
- package/types/bin/mdw-css.d.ts.map +1 -0
- package/types/components/Badge.d.ts +39 -0
- package/types/components/Badge.d.ts.map +1 -0
- package/types/components/Body.d.ts +29 -0
- package/types/components/Body.d.ts.map +1 -0
- package/types/components/BottomAppBar.d.ts +73 -0
- package/types/components/BottomAppBar.d.ts.map +1 -0
- package/types/components/BottomSheet.d.ts +109 -0
- package/types/components/BottomSheet.d.ts.map +1 -0
- package/types/components/Box.d.ts +16 -0
- package/types/components/Box.d.ts.map +1 -0
- package/types/components/Button.d.ts +714 -0
- package/types/components/Button.d.ts.map +1 -0
- package/types/components/Card.d.ts +412 -0
- package/types/components/Card.d.ts.map +1 -0
- package/types/components/Checkbox.d.ts +205 -0
- package/types/components/Checkbox.d.ts.map +1 -0
- package/types/components/CheckboxIcon.d.ts +44 -0
- package/types/components/CheckboxIcon.d.ts.map +1 -0
- package/types/components/Chip.d.ts +1425 -0
- package/types/components/Chip.d.ts.map +1 -0
- package/types/components/Dialog.d.ts +286 -0
- package/types/components/Dialog.d.ts.map +1 -0
- package/types/components/DialogActions.d.ts +4 -0
- package/types/components/DialogActions.d.ts.map +1 -0
- package/types/components/Display.d.ts +45 -0
- package/types/components/Display.d.ts.map +1 -0
- package/types/components/Divider.d.ts +10 -0
- package/types/components/Divider.d.ts.map +1 -0
- package/types/components/Fab.d.ts +741 -0
- package/types/components/Fab.d.ts.map +1 -0
- package/types/components/FabContainer.d.ts +10 -0
- package/types/components/FabContainer.d.ts.map +1 -0
- package/types/components/FilterChip.d.ts +4283 -0
- package/types/components/FilterChip.d.ts.map +1 -0
- package/types/components/Grid.d.ts +37 -0
- package/types/components/Grid.d.ts.map +1 -0
- package/types/components/Headline.d.ts +47 -0
- package/types/components/Headline.d.ts.map +1 -0
- package/types/components/Icon.d.ts +103 -0
- package/types/components/Icon.d.ts.map +1 -0
- package/types/components/IconButton.d.ts +1486 -0
- package/types/components/IconButton.d.ts.map +1 -0
- package/types/components/Input.d.ts +51288 -0
- package/types/components/Input.d.ts.map +1 -0
- package/types/components/InputChip.d.ts +243 -0
- package/types/components/InputChip.d.ts.map +1 -0
- package/types/components/Label.d.ts +29 -0
- package/types/components/Label.d.ts.map +1 -0
- package/types/components/List.d.ts +31 -0
- package/types/components/List.d.ts.map +1 -0
- package/types/components/ListItem.d.ts +349 -0
- package/types/components/ListItem.d.ts.map +1 -0
- package/types/components/ListOption.d.ts +1493 -0
- package/types/components/ListOption.d.ts.map +1 -0
- package/types/components/Listbox.d.ts +12012 -0
- package/types/components/Listbox.d.ts.map +1 -0
- package/types/components/Menu.d.ts +119 -0
- package/types/components/Menu.d.ts.map +1 -0
- package/types/components/MenuItem.d.ts +3109 -0
- package/types/components/MenuItem.d.ts.map +1 -0
- package/types/components/NavBar.d.ts +18 -0
- package/types/components/NavBar.d.ts.map +1 -0
- package/types/components/NavBarItem.d.ts +186 -0
- package/types/components/NavBarItem.d.ts.map +1 -0
- package/types/components/NavDrawer.d.ts +108 -0
- package/types/components/NavDrawer.d.ts.map +1 -0
- package/types/components/NavDrawerItem.d.ts +186 -0
- package/types/components/NavDrawerItem.d.ts.map +1 -0
- package/types/components/NavItem.d.ts +190 -0
- package/types/components/NavItem.d.ts.map +1 -0
- package/types/components/NavRail.d.ts +109 -0
- package/types/components/NavRail.d.ts.map +1 -0
- package/types/components/NavRailItem.d.ts +186 -0
- package/types/components/NavRailItem.d.ts.map +1 -0
- package/types/components/Page.d.ts +24 -0
- package/types/components/Page.d.ts.map +1 -0
- package/types/components/Pane.d.ts +44 -0
- package/types/components/Pane.d.ts.map +1 -0
- package/types/components/Popup.d.ts +76 -0
- package/types/components/Popup.d.ts.map +1 -0
- package/types/components/Progress.d.ts +19 -0
- package/types/components/Progress.d.ts.map +1 -0
- package/types/components/Radio.d.ts +199 -0
- package/types/components/Radio.d.ts.map +1 -0
- package/types/components/RadioIcon.d.ts +46 -0
- package/types/components/RadioIcon.d.ts.map +1 -0
- package/types/components/Ripple.d.ts +34 -0
- package/types/components/Ripple.d.ts.map +1 -0
- package/types/components/Root.d.ts +68 -0
- package/types/components/Root.d.ts.map +1 -0
- package/types/components/Scrim.d.ts +6 -0
- package/types/components/Scrim.d.ts.map +1 -0
- package/types/components/Search.d.ts +16 -0
- package/types/components/Search.d.ts.map +1 -0
- package/types/components/SegmentedButton.d.ts +718 -0
- package/types/components/SegmentedButton.d.ts.map +1 -0
- package/types/components/SegmentedButtonGroup.d.ts +44 -0
- package/types/components/SegmentedButtonGroup.d.ts.map +1 -0
- package/types/components/Select.d.ts +1361 -0
- package/types/components/Select.d.ts.map +1 -0
- package/types/components/Shape.d.ts +10 -0
- package/types/components/Shape.d.ts.map +1 -0
- package/types/components/SideSheet.d.ts +106 -0
- package/types/components/SideSheet.d.ts.map +1 -0
- package/types/components/Slider.d.ts +382 -0
- package/types/components/Slider.d.ts.map +1 -0
- package/types/components/Snackbar.d.ts +65 -0
- package/types/components/Snackbar.d.ts.map +1 -0
- package/types/components/SnackbarContainer.d.ts +6 -0
- package/types/components/SnackbarContainer.d.ts.map +1 -0
- package/types/components/Surface.d.ts +45 -0
- package/types/components/Surface.d.ts.map +1 -0
- package/types/components/Switch.d.ts +183 -0
- package/types/components/Switch.d.ts.map +1 -0
- package/types/components/SwitchIcon.d.ts +169 -0
- package/types/components/SwitchIcon.d.ts.map +1 -0
- package/types/components/Tab.d.ts +879 -0
- package/types/components/Tab.d.ts.map +1 -0
- package/types/components/TabContent.d.ts +122 -0
- package/types/components/TabContent.d.ts.map +1 -0
- package/types/components/TabList.d.ts +6266 -0
- package/types/components/TabList.d.ts.map +1 -0
- package/types/components/TabPanel.d.ts +28 -0
- package/types/components/TabPanel.d.ts.map +1 -0
- package/types/components/Table.d.ts +2 -0
- package/types/components/Table.d.ts.map +1 -0
- package/types/components/TextArea.d.ts +1394 -0
- package/types/components/TextArea.d.ts.map +1 -0
- package/types/components/Title.d.ts +47 -0
- package/types/components/Title.d.ts.map +1 -0
- package/types/components/Tooltip.d.ts +49 -0
- package/types/components/Tooltip.d.ts.map +1 -0
- package/types/components/TopAppBar.d.ts +130 -0
- package/types/components/TopAppBar.d.ts.map +1 -0
- package/types/constants/colorKeywords.d.ts +2 -0
- package/types/constants/colorKeywords.d.ts.map +1 -0
- package/types/constants/shapes.d.ts +38 -0
- package/types/constants/shapes.d.ts.map +1 -0
- package/types/constants/typography.d.ts +212 -0
- package/types/constants/typography.d.ts.map +1 -0
- package/types/core/Composition.d.ts +252 -0
- package/types/core/Composition.d.ts.map +1 -0
- package/types/core/CompositionAdapter.d.ts +92 -0
- package/types/core/CompositionAdapter.d.ts.map +1 -0
- package/types/core/CustomElement.d.ts +302 -0
- package/types/core/CustomElement.d.ts.map +1 -0
- package/types/core/css.d.ts +44 -0
- package/types/core/css.d.ts.map +1 -0
- package/types/core/customTypes.d.ts +26 -0
- package/types/core/customTypes.d.ts.map +1 -0
- package/types/core/dom.d.ts +32 -0
- package/types/core/dom.d.ts.map +1 -0
- package/types/core/jsonMergePatch.d.ts +31 -0
- package/types/core/jsonMergePatch.d.ts.map +1 -0
- package/types/core/observe.d.ts +113 -0
- package/types/core/observe.d.ts.map +1 -0
- package/types/core/optimizations.d.ts +7 -0
- package/types/core/optimizations.d.ts.map +1 -0
- package/types/core/template.d.ts +47 -0
- package/types/core/template.d.ts.map +1 -0
- package/types/core/uid.d.ts +6 -0
- package/types/core/uid.d.ts.map +1 -0
- package/types/dom/HTMLOptionsCollectionProxy.d.ts +18 -0
- package/types/dom/HTMLOptionsCollectionProxy.d.ts.map +1 -0
- package/types/index.d.ts +88 -0
- package/types/index.d.ts.map +1 -0
- package/types/loaders/palette.d.ts +2 -0
- package/types/loaders/palette.d.ts.map +1 -0
- package/types/loaders/theme.d.ts +2 -0
- package/types/loaders/theme.d.ts.map +1 -0
- package/types/mixins/AriaReflectorMixin.d.ts +23 -0
- package/types/mixins/AriaReflectorMixin.d.ts.map +1 -0
- package/types/mixins/AriaToolbarMixin.d.ts +32 -0
- package/types/mixins/AriaToolbarMixin.d.ts.map +1 -0
- package/types/mixins/ControlMixin.d.ts +124 -0
- package/types/mixins/ControlMixin.d.ts.map +1 -0
- package/types/mixins/DelegatesFocusMixin.d.ts +5 -0
- package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -0
- package/types/mixins/DensityMixin.d.ts +5 -0
- package/types/mixins/DensityMixin.d.ts.map +1 -0
- package/types/mixins/ElevationMixin.d.ts +33 -0
- package/types/mixins/ElevationMixin.d.ts.map +1 -0
- package/types/mixins/FlexableMixin.d.ts +13 -0
- package/types/mixins/FlexableMixin.d.ts.map +1 -0
- package/types/mixins/FormAssociatedMixin.d.ts +122 -0
- package/types/mixins/FormAssociatedMixin.d.ts.map +1 -0
- package/types/mixins/HyperlinkMixin.d.ts +22 -0
- package/types/mixins/HyperlinkMixin.d.ts.map +1 -0
- package/types/mixins/InputMixin.d.ts +179 -0
- package/types/mixins/InputMixin.d.ts.map +1 -0
- package/types/mixins/KeyboardNavMixin.d.ts +47 -0
- package/types/mixins/KeyboardNavMixin.d.ts.map +1 -0
- package/types/mixins/NavigationListenerMixin.d.ts +8 -0
- package/types/mixins/NavigationListenerMixin.d.ts.map +1 -0
- package/types/mixins/PopupMixin.d.ts +82 -0
- package/types/mixins/PopupMixin.d.ts.map +1 -0
- package/types/mixins/RTLObserverMixin.d.ts +7 -0
- package/types/mixins/RTLObserverMixin.d.ts.map +1 -0
- package/types/mixins/ResizeObserverMixin.d.ts +12 -0
- package/types/mixins/ResizeObserverMixin.d.ts.map +1 -0
- package/types/mixins/RippleMixin.d.ts +92 -0
- package/types/mixins/RippleMixin.d.ts.map +1 -0
- package/types/mixins/ScrollListenerMixin.d.ts +41 -0
- package/types/mixins/ScrollListenerMixin.d.ts.map +1 -0
- package/types/mixins/SemiStickyMixin.d.ts +50 -0
- package/types/mixins/SemiStickyMixin.d.ts.map +1 -0
- package/types/mixins/ShapeMaskedMixin.d.ts +9 -0
- package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -0
- package/types/mixins/ShapeMixin.d.ts +38 -0
- package/types/mixins/ShapeMixin.d.ts.map +1 -0
- package/types/mixins/StateMixin.d.ts +27 -0
- package/types/mixins/StateMixin.d.ts.map +1 -0
- package/types/mixins/TextFieldMixin.d.ts +1354 -0
- package/types/mixins/TextFieldMixin.d.ts.map +1 -0
- package/types/mixins/ThemableMixin.d.ts +9 -0
- package/types/mixins/ThemableMixin.d.ts.map +1 -0
- package/types/mixins/TooltipTriggerMixin.d.ts +106 -0
- package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -0
- package/types/mixins/TouchTargetMixin.d.ts +3 -0
- package/types/mixins/TouchTargetMixin.d.ts.map +1 -0
- package/types/mixins/TypographyMixin.d.ts +17 -0
- package/types/mixins/TypographyMixin.d.ts.map +1 -0
- package/types/services/rtl.d.ts +3 -0
- package/types/services/rtl.d.ts.map +1 -0
- package/types/services/svgAlias.d.ts +13 -0
- package/types/services/svgAlias.d.ts.map +1 -0
- package/types/services/theme.d.ts +45 -0
- package/types/services/theme.d.ts.map +1 -0
- package/types/utils/cli.d.ts +3 -0
- package/types/utils/cli.d.ts.map +1 -0
- package/types/utils/function.d.ts +3 -0
- package/types/utils/function.d.ts.map +1 -0
- package/types/utils/jsx-runtime.d.ts +20 -0
- package/types/utils/jsx-runtime.d.ts.map +1 -0
- package/types/utils/material-color/blend.d.ts +34 -0
- package/types/utils/material-color/blend.d.ts.map +1 -0
- package/types/utils/material-color/hct/Cam16.d.ts +142 -0
- package/types/utils/material-color/hct/Cam16.d.ts.map +1 -0
- package/types/utils/material-color/hct/Hct.d.ts +93 -0
- package/types/utils/material-color/hct/Hct.d.ts.map +1 -0
- package/types/utils/material-color/hct/ViewingConditions.d.ts +69 -0
- package/types/utils/material-color/hct/ViewingConditions.d.ts.map +1 -0
- package/types/utils/material-color/hct/hctSolver.d.ts +30 -0
- package/types/utils/material-color/hct/hctSolver.d.ts.map +1 -0
- package/types/utils/material-color/helper.d.ts +8 -0
- package/types/utils/material-color/helper.d.ts.map +1 -0
- package/types/utils/material-color/palettes/CorePalette.d.ts +75 -0
- package/types/utils/material-color/palettes/CorePalette.d.ts.map +1 -0
- package/types/utils/material-color/palettes/TonalPalette.d.ts +38 -0
- package/types/utils/material-color/palettes/TonalPalette.d.ts.map +1 -0
- package/types/utils/material-color/scheme/Scheme.d.ts +264 -0
- package/types/utils/material-color/scheme/Scheme.d.ts.map +1 -0
- package/types/utils/material-color/utils/color.d.ts +172 -0
- package/types/utils/material-color/utils/color.d.ts.map +1 -0
- package/types/utils/material-color/utils/math.d.ts +94 -0
- package/types/utils/material-color/utils/math.d.ts.map +1 -0
- package/types/utils/pixelmatch.d.ts +22 -0
- package/types/utils/pixelmatch.d.ts.map +1 -0
- package/types/utils/popup.d.ts +106 -0
- package/types/utils/popup.d.ts.map +1 -0
- package/types/utils/searchParams.d.ts +3 -0
- package/types/utils/searchParams.d.ts.map +1 -0
- package/types/utils/svg.d.ts +7 -0
- package/types/utils/svg.d.ts.map +1 -0
- package/utils/material-color/scheme/Scheme.js +1 -1
- package/utils/pixelmatch.js +360 -0
- package/utils/popup.js +86 -10
- package/utils/searchParams.js +19 -0
- package/components/ExtendedFab.js +0 -32
- package/components/Layout.js +0 -504
- package/components/Nav.js +0 -38
- package/core/DomAdapter.js +0 -586
- package/core/ICustomElement.d.ts +0 -291
- package/core/ICustomElement.js +0 -1
- package/core/test.js +0 -126
- package/core/typings.d.ts +0 -142
- package/core/typings.js +0 -1
- package/mixins/SurfaceMixin.js +0 -127
- package/theming/loader.js +0 -22
- /package/{utils/color_keywords.js → constants/colorKeywords.js} +0 -0
package/core/Composition.js
CHANGED
|
@@ -22,12 +22,90 @@ import { generateUID } from './uid.js';
|
|
|
22
22
|
/**
|
|
23
23
|
* @template T
|
|
24
24
|
* @typedef {Object} RenderOptions
|
|
25
|
+
* @prop {T} [defaults] what
|
|
25
26
|
* @prop {T} [store] what
|
|
26
|
-
* @prop {DocumentFragment|
|
|
27
|
+
* @prop {DocumentFragment|HTMLElement|Element} [target] where
|
|
28
|
+
* @prop {ShadowRoot} [shadowRoot] where
|
|
27
29
|
* @prop {any} [context] `this` on callbacks/events
|
|
28
30
|
* @prop {any} [injections]
|
|
29
31
|
*/
|
|
30
32
|
|
|
33
|
+
/** @typedef {HTMLElementEventMap & { input: InputEvent; } } HTMLElementEventMapFixed */
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @typedef {(
|
|
37
|
+
* Pick<HTMLElementEventMapFixed,
|
|
38
|
+
* 'auxclick' |
|
|
39
|
+
* 'beforeinput' |
|
|
40
|
+
* 'click' |
|
|
41
|
+
* 'compositionstart' |
|
|
42
|
+
* 'contextmenu' |
|
|
43
|
+
* 'drag' |
|
|
44
|
+
* 'dragenter' |
|
|
45
|
+
* 'dragover' |
|
|
46
|
+
* 'dragstart' |
|
|
47
|
+
* 'drop' |
|
|
48
|
+
* 'invalid' |
|
|
49
|
+
* 'keydown' |
|
|
50
|
+
* 'keypress' |
|
|
51
|
+
* 'keyup' |
|
|
52
|
+
* 'mousedown' |
|
|
53
|
+
* 'mousemove' |
|
|
54
|
+
* 'mouseout' |
|
|
55
|
+
* 'mouseover' |
|
|
56
|
+
* 'mouseup' |
|
|
57
|
+
* 'pointerdown' |
|
|
58
|
+
* 'pointermove' |
|
|
59
|
+
* 'pointerout' |
|
|
60
|
+
* 'pointerover' |
|
|
61
|
+
* 'pointerup' |
|
|
62
|
+
* 'reset' |
|
|
63
|
+
* 'selectstart' |
|
|
64
|
+
* 'submit' |
|
|
65
|
+
* 'touchend' |
|
|
66
|
+
* 'touchmove' |
|
|
67
|
+
* 'touchstart' |
|
|
68
|
+
* 'wheel'
|
|
69
|
+
* >
|
|
70
|
+
* )} HTMLElementCancellableEventMap
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @typedef {(
|
|
75
|
+
* HTMLElementEventMapFixed
|
|
76
|
+
* & {[P in keyof HTMLElementCancellableEventMap as `~${P}`]: HTMLElementCancellableEventMap[P]}
|
|
77
|
+
* & Record<string, Event|CustomEvent>
|
|
78
|
+
* )} CompositionEventMap
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @template {any} T
|
|
83
|
+
* @template {keyof CompositionEventMap} [K = keyof CompositionEventMap]
|
|
84
|
+
* @typedef {{
|
|
85
|
+
* type?: K
|
|
86
|
+
* tag?: string,
|
|
87
|
+
* capture?: boolean;
|
|
88
|
+
* once?: boolean;
|
|
89
|
+
* passive?: boolean;
|
|
90
|
+
* signal?: AbortSignal;
|
|
91
|
+
* handleEvent?: (
|
|
92
|
+
* this: T,
|
|
93
|
+
* event: (K extends keyof CompositionEventMap ? CompositionEventMap[K] : Event) & {currentTarget:HTMLElement}
|
|
94
|
+
* ) => any;
|
|
95
|
+
* prop?: string;
|
|
96
|
+
* deepProp?: string[],
|
|
97
|
+
* }} CompositionEventListener
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @template T
|
|
102
|
+
* @typedef {{
|
|
103
|
+
* [P in keyof CompositionEventMap]?: (keyof T & string)
|
|
104
|
+
* | ((this: T, event: CompositionEventMap[P] & {currentTarget:HTMLElement}) => any)
|
|
105
|
+
* | CompositionEventListener<T, P>
|
|
106
|
+
* }} CompositionEventListenerObject
|
|
107
|
+
*/
|
|
108
|
+
|
|
31
109
|
/**
|
|
32
110
|
* @template {any} T
|
|
33
111
|
* @typedef {Object} NodeBindEntry
|
|
@@ -41,7 +119,7 @@ import { generateUID } from './uid.js';
|
|
|
41
119
|
* @prop {boolean} [doubleNegate]
|
|
42
120
|
* @prop {Function} [expression]
|
|
43
121
|
* @prop {(options: RenderOptions<?>, element: Element, changes:any, data:any) => any} [render] custom render function
|
|
44
|
-
* @prop {
|
|
122
|
+
* @prop {CompositionEventListener<T>[]} [listeners]
|
|
45
123
|
* @prop {Composition<any>} [composition] // Sub composition templating (eg: array)
|
|
46
124
|
* @prop {T} defaultValue
|
|
47
125
|
*/
|
|
@@ -52,8 +130,7 @@ import { generateUID } from './uid.js';
|
|
|
52
130
|
* @typedef RenderGraphSearch
|
|
53
131
|
* @prop {(state:InitializationState, changes:any, data:any) => any} invocation
|
|
54
132
|
* @prop {number} cacheIndex
|
|
55
|
-
* @prop {number}
|
|
56
|
-
* @prop {number} dirtyIndex
|
|
133
|
+
* @prop {number} searchIndex
|
|
57
134
|
* @prop {string | Function | string[]} query
|
|
58
135
|
* @prop {Function} [expression]
|
|
59
136
|
* @prop {string} prop
|
|
@@ -79,10 +156,10 @@ import { generateUID } from './uid.js';
|
|
|
79
156
|
* @type {RenderGraphAction['invocation']}
|
|
80
157
|
* @this {RenderGraphAction}
|
|
81
158
|
*/
|
|
82
|
-
function writeDOMAttribute(
|
|
159
|
+
function writeDOMAttribute({ nodes }, value) {
|
|
83
160
|
const { nodeIndex, attrName } = this;
|
|
84
161
|
/** @type {Element} */
|
|
85
|
-
const element =
|
|
162
|
+
const element = nodes[nodeIndex];
|
|
86
163
|
switch (value) {
|
|
87
164
|
case undefined:
|
|
88
165
|
case null:
|
|
@@ -102,43 +179,97 @@ function writeDOMAttribute(state, value) {
|
|
|
102
179
|
* @type {RenderGraphAction['invocation']}
|
|
103
180
|
* @this {RenderGraphAction}
|
|
104
181
|
*/
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
|
|
182
|
+
function writeDynamicNode({ nodeStates, comments, nodes }, value) {
|
|
183
|
+
const { commentIndex, nodeIndex } = this;
|
|
184
|
+
const nodeState = nodeStates[nodeIndex];
|
|
185
|
+
// eslint-disable-next-line no-bitwise
|
|
186
|
+
const hidden = nodeState & 0b0001;
|
|
187
|
+
const show = value != null && value !== false;
|
|
188
|
+
if (!show) {
|
|
189
|
+
// Should be hidden
|
|
190
|
+
if (hidden) return;
|
|
191
|
+
// Replace whatever node is there with the comment
|
|
192
|
+
let comment = comments[commentIndex];
|
|
193
|
+
if (!comment) {
|
|
194
|
+
comment = createEmptyComment();
|
|
195
|
+
comments[commentIndex] = comment;
|
|
196
|
+
}
|
|
197
|
+
nodes[nodeIndex].replaceWith(comment);
|
|
198
|
+
// eslint-disable-next-line no-bitwise
|
|
199
|
+
nodeStates[nodeIndex] |= 0b0001;
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
// Must be shown
|
|
203
|
+
// Update node first (offscreen rendering)
|
|
204
|
+
const node = nodes[nodeIndex];
|
|
205
|
+
// eslint-disable-next-line no-bitwise
|
|
206
|
+
const isDynamicNode = nodeState & 0b0010;
|
|
207
|
+
|
|
208
|
+
if (typeof value === 'object') {
|
|
209
|
+
// Not string data, need to replace
|
|
210
|
+
console.warn('Dynamic nodes not supported yet');
|
|
211
|
+
} else if (isDynamicNode) {
|
|
212
|
+
const textNode = new Text(value);
|
|
213
|
+
node.replaceWith(textNode);
|
|
214
|
+
nodes[nodeIndex] = textNode;
|
|
215
|
+
// eslint-disable-next-line no-bitwise
|
|
216
|
+
nodeStates[nodeIndex] &= ~0b0010;
|
|
217
|
+
} else {
|
|
218
|
+
node.data = value;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Updated, now set hidden state
|
|
222
|
+
|
|
223
|
+
if (hidden) {
|
|
224
|
+
const comment = comments[commentIndex];
|
|
225
|
+
comment.replaceWith(node);
|
|
226
|
+
// eslint-disable-next-line no-bitwise
|
|
227
|
+
nodeStates[nodeIndex] &= ~0b0001;
|
|
228
|
+
}
|
|
229
|
+
// Done
|
|
108
230
|
}
|
|
109
231
|
|
|
110
232
|
/**
|
|
111
233
|
* @type {RenderGraphAction['invocation']}
|
|
112
234
|
* @this {RenderGraphAction}
|
|
113
235
|
*/
|
|
114
|
-
function writeDOMElementAttachedState(
|
|
236
|
+
function writeDOMElementAttachedState({ nodeStates, nodes, comments }, value) {
|
|
115
237
|
const { commentIndex, nodeIndex } = this;
|
|
116
|
-
|
|
238
|
+
// eslint-disable-next-line no-bitwise
|
|
239
|
+
const hidden = nodeStates[nodeIndex] & 1;
|
|
240
|
+
const show = value != null && value !== false;
|
|
241
|
+
if (show === !hidden) return;
|
|
242
|
+
|
|
243
|
+
const element = nodes[nodeIndex];
|
|
244
|
+
let comment = comments[commentIndex];
|
|
117
245
|
if (!comment) {
|
|
118
246
|
comment = createEmptyComment();
|
|
119
|
-
|
|
247
|
+
comments[commentIndex] = comment;
|
|
120
248
|
}
|
|
121
|
-
const element = state.nodes[nodeIndex];
|
|
122
|
-
const show = value != null && value !== false;
|
|
123
249
|
if (show) {
|
|
124
250
|
comment.replaceWith(element);
|
|
251
|
+
// eslint-disable-next-line no-bitwise
|
|
252
|
+
nodeStates[nodeIndex] &= ~0b0001;
|
|
125
253
|
} else {
|
|
126
254
|
element.replaceWith(comment);
|
|
255
|
+
// eslint-disable-next-line no-bitwise
|
|
256
|
+
nodeStates[nodeIndex] |= 0b0001;
|
|
127
257
|
}
|
|
128
|
-
return show;
|
|
129
258
|
}
|
|
130
259
|
|
|
131
260
|
/**
|
|
132
261
|
* @type {RenderGraphAction['invocation']}
|
|
133
262
|
* @this {RenderGraphAction}
|
|
134
263
|
*/
|
|
135
|
-
function
|
|
264
|
+
function writeDOMHideNodeOnInit({ comments, nodeStates, nodes }) {
|
|
136
265
|
const { commentIndex, nodeIndex } = this;
|
|
137
266
|
|
|
138
267
|
const comment = createEmptyComment();
|
|
139
|
-
|
|
268
|
+
comments[commentIndex] = comment;
|
|
269
|
+
// eslint-disable-next-line no-bitwise
|
|
270
|
+
nodeStates[nodeIndex] |= 1;
|
|
140
271
|
|
|
141
|
-
|
|
272
|
+
nodes[nodeIndex].replaceWith(comment);
|
|
142
273
|
}
|
|
143
274
|
|
|
144
275
|
/**
|
|
@@ -146,37 +277,50 @@ function writeDOMHideElementOnInit(state) {
|
|
|
146
277
|
* @param {Parameters<RenderGraphSearch['invocation']>} args
|
|
147
278
|
*/
|
|
148
279
|
function executeSearch(search, ...args) {
|
|
149
|
-
const [
|
|
150
|
-
const
|
|
151
|
-
|
|
280
|
+
const [{ caches, searchStates }] = args;
|
|
281
|
+
const { cacheIndex, searchIndex, subSearch, invocation } = search;
|
|
282
|
+
const cachedValue = caches[cacheIndex];
|
|
283
|
+
const searchState = searchStates[searchIndex];
|
|
284
|
+
|
|
285
|
+
// Ran = 0b0001
|
|
286
|
+
// Dirty = 0b0010
|
|
287
|
+
// eslint-disable-next-line no-bitwise
|
|
288
|
+
if (searchState & 0b0001) {
|
|
152
289
|
// Return last result
|
|
153
290
|
return {
|
|
154
291
|
value: cachedValue,
|
|
155
|
-
|
|
292
|
+
// eslint-disable-next-line no-bitwise
|
|
293
|
+
dirty: ((searchState & 0b0010) === 0b0010),
|
|
156
294
|
};
|
|
157
295
|
}
|
|
158
|
-
|
|
296
|
+
|
|
297
|
+
// eslint-disable-next-line no-bitwise
|
|
298
|
+
searchStates[searchIndex] |= 0b0001;
|
|
159
299
|
let result;
|
|
160
|
-
if (
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
300
|
+
if (invocation) {
|
|
301
|
+
if (subSearch) {
|
|
302
|
+
const subResult = executeSearch(subSearch, ...args);
|
|
303
|
+
// Use last cached value (if any)
|
|
304
|
+
if (!subResult.dirty && cachedValue !== undefined) {
|
|
305
|
+
// eslint-disable-next-line no-bitwise
|
|
306
|
+
searchStates[searchIndex] &= ~0b0010;
|
|
307
|
+
return { value: cachedValue, dirty: false };
|
|
308
|
+
}
|
|
309
|
+
// Pass from subquery
|
|
310
|
+
result = search.invocation(subResult.value);
|
|
311
|
+
} else {
|
|
312
|
+
result = search.invocation(...args);
|
|
313
|
+
}
|
|
314
|
+
if ((result === undefined) || (cachedValue === result)) {
|
|
315
|
+
// Return from cache
|
|
316
|
+
return { value: result, dirty: false };
|
|
166
317
|
}
|
|
167
|
-
// Pass from subquery
|
|
168
|
-
result = search.invocation(subResult.value);
|
|
169
|
-
} else {
|
|
170
|
-
result = search.invocation(...args);
|
|
171
|
-
}
|
|
172
|
-
if ((result === undefined) || (cachedValue === result)) {
|
|
173
|
-
// Returnf rom cache
|
|
174
|
-
return { value: result, dirty: false };
|
|
175
318
|
}
|
|
176
319
|
|
|
177
320
|
// Overwrite cache and flag as dirty
|
|
178
|
-
|
|
179
|
-
|
|
321
|
+
caches[cacheIndex] = result;
|
|
322
|
+
// eslint-disable-next-line no-bitwise
|
|
323
|
+
searchStates[searchIndex] |= 0b0010;
|
|
180
324
|
return { value: result, dirty: true };
|
|
181
325
|
}
|
|
182
326
|
|
|
@@ -184,11 +328,11 @@ function executeSearch(search, ...args) {
|
|
|
184
328
|
* @type {RenderGraphSearch['invocation']}
|
|
185
329
|
* @this {RenderGraphSearch}
|
|
186
330
|
*/
|
|
187
|
-
function searchWithExpression(
|
|
331
|
+
function searchWithExpression({ options: { context, store, injections } }, changes, data) {
|
|
188
332
|
return this.expression.call(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
333
|
+
context,
|
|
334
|
+
store ?? data,
|
|
335
|
+
injections,
|
|
192
336
|
);
|
|
193
337
|
}
|
|
194
338
|
|
|
@@ -196,7 +340,7 @@ function searchWithExpression(state, changes, data) {
|
|
|
196
340
|
* @type {RenderGraphSearch['invocation']}
|
|
197
341
|
* @this {RenderGraphSearch}
|
|
198
342
|
*/
|
|
199
|
-
function searchWithProp(state, changes
|
|
343
|
+
function searchWithProp(state, changes) {
|
|
200
344
|
return changes[this.prop];
|
|
201
345
|
}
|
|
202
346
|
|
|
@@ -216,23 +360,21 @@ function searchWithDeepProp(state, changes, data) {
|
|
|
216
360
|
|
|
217
361
|
/**
|
|
218
362
|
* @typedef InterpolateOptions
|
|
219
|
-
* @prop {
|
|
363
|
+
* @prop {Record<string,any>} [defaults] Default values to use for interpolation
|
|
220
364
|
* @prop {{iterable:string} & Record<string,any>} [injections] Context-specific injected properties. (Experimental)
|
|
221
365
|
*/
|
|
222
366
|
|
|
223
367
|
/**
|
|
224
368
|
* @typedef InitializationState
|
|
225
369
|
* @prop {Element} lastElement
|
|
226
|
-
* @prop {boolean} isShadowRoot
|
|
227
370
|
* @prop {ChildNode} lastChildNode
|
|
228
371
|
* @prop {(Element|Text)[]} nodes
|
|
229
372
|
* @prop {any[]} caches
|
|
230
373
|
* @prop {Comment[]} comments
|
|
231
|
-
* @prop {
|
|
232
|
-
* @prop {
|
|
374
|
+
* @prop {Uint8Array} nodeStates
|
|
375
|
+
* @prop {Uint8Array} searchStates
|
|
233
376
|
* @prop {Element[]} refs
|
|
234
377
|
* @prop {number} lastChildNodeIndex
|
|
235
|
-
* @prop {DocumentFragment} instanceFragment
|
|
236
378
|
* @prop {RenderOptions<?>} options
|
|
237
379
|
*/
|
|
238
380
|
|
|
@@ -242,7 +384,6 @@ const STRING_INTERPOLATION_REGEX = /{([^}]*)}/g;
|
|
|
242
384
|
/**
|
|
243
385
|
* Returns event listener bound to shadow root host.
|
|
244
386
|
* Use this function to avoid generating extra closures
|
|
245
|
-
*
|
|
246
387
|
* @this {HTMLElement}
|
|
247
388
|
* @param {Function} fn
|
|
248
389
|
*/
|
|
@@ -317,13 +458,16 @@ function valueFromPropName(prop, source) {
|
|
|
317
458
|
return value;
|
|
318
459
|
}
|
|
319
460
|
|
|
461
|
+
const compositionCache = new Map();
|
|
462
|
+
|
|
320
463
|
/** @template T */
|
|
321
464
|
export default class Composition {
|
|
322
|
-
|
|
465
|
+
static EVENT_PREFIX_REGEX = /^([*1~]+)?(.*)$/;
|
|
466
|
+
|
|
467
|
+
_interpolationState = {
|
|
323
468
|
nodeIndex: -1,
|
|
324
|
-
|
|
469
|
+
searchIndex: 0,
|
|
325
470
|
cacheIndex: 0,
|
|
326
|
-
dirtyIndex: 0,
|
|
327
471
|
commentIndex: 0,
|
|
328
472
|
/** @type {this['nodesToBind'][0]} */
|
|
329
473
|
nodeEntry: null,
|
|
@@ -346,48 +490,34 @@ export default class Composition {
|
|
|
346
490
|
|
|
347
491
|
/**
|
|
348
492
|
* Index of searches by query (dotted notation for deep props)
|
|
349
|
-
*
|
|
350
493
|
* @type {Map<Function|string, RenderGraphSearch>}
|
|
351
494
|
*/
|
|
352
|
-
searchByQuery
|
|
495
|
+
searchByQuery;
|
|
353
496
|
|
|
354
497
|
/**
|
|
355
498
|
* Index of searches by query (dotted notation for deep props)
|
|
356
|
-
*
|
|
357
499
|
* @type {Map<string, RenderGraphAction[]>}
|
|
358
500
|
*/
|
|
359
|
-
actionsByPropsUsed
|
|
360
|
-
|
|
361
|
-
/** @type {RenderGraphAction[]} */
|
|
362
|
-
actions = [];
|
|
501
|
+
actionsByPropsUsed;
|
|
363
502
|
|
|
364
503
|
/** @type {RenderGraphAction[]} */
|
|
365
504
|
postInitActions = [];
|
|
366
505
|
|
|
367
506
|
/** @type {Set<string>} */
|
|
368
|
-
tagsWithBindings
|
|
507
|
+
tagsWithBindings;
|
|
369
508
|
|
|
370
509
|
/**
|
|
371
510
|
* Array of element tags
|
|
372
|
-
*
|
|
373
511
|
* @type {string[]}
|
|
374
512
|
*/
|
|
375
513
|
tags = [];
|
|
376
514
|
|
|
377
|
-
/**
|
|
378
|
-
* Array of property bindings sorted by tag/subnode
|
|
379
|
-
*
|
|
380
|
-
* @type {Set<string>}
|
|
381
|
-
*/
|
|
382
|
-
watchedProps = new Set();
|
|
383
|
-
|
|
384
515
|
/**
|
|
385
516
|
* Data of arrays used in templates
|
|
386
517
|
* Usage of a [mdw-for] will create an ArrayLike expectation based on key
|
|
387
518
|
* Only store metadata, not actual data. Currently only needs length.
|
|
388
519
|
* TBD if more is needed later
|
|
389
520
|
* Referenced by property key (string)
|
|
390
|
-
*
|
|
391
521
|
* @type {CompositionAdapter}
|
|
392
522
|
*/
|
|
393
523
|
adapter;
|
|
@@ -395,16 +525,14 @@ export default class Composition {
|
|
|
395
525
|
/**
|
|
396
526
|
* Collection of events to bind.
|
|
397
527
|
* Indexed by ID
|
|
398
|
-
*
|
|
399
|
-
* @type {Map<string|symbol, import('./typings.js').CompositionEventListener<any>[]>}
|
|
528
|
+
* @type {Map<string|symbol, CompositionEventListener<any>[]>}
|
|
400
529
|
*/
|
|
401
|
-
events
|
|
530
|
+
events;
|
|
402
531
|
|
|
403
532
|
/**
|
|
404
533
|
* Snapshot of composition at initial state.
|
|
405
534
|
* This fragment can be cloned for first rendering, instead of calling
|
|
406
535
|
* of using `render()` to construct the initial DOM tree.
|
|
407
|
-
*
|
|
408
536
|
* @type {DocumentFragment}
|
|
409
537
|
*/
|
|
410
538
|
cloneable;
|
|
@@ -421,7 +549,6 @@ export default class Composition {
|
|
|
421
549
|
/**
|
|
422
550
|
* List of IDs used by template elements
|
|
423
551
|
* May be needed to be removed when adding to non-DocumentFragment
|
|
424
|
-
*
|
|
425
552
|
* @type {string[]}
|
|
426
553
|
*/
|
|
427
554
|
allIds = [];
|
|
@@ -430,7 +557,8 @@ export default class Composition {
|
|
|
430
557
|
* Collection of IDs used for referencing elements
|
|
431
558
|
* Not meant for live DOM. Removed before attaching to document
|
|
432
559
|
*/
|
|
433
|
-
|
|
560
|
+
/** @type {Set<string>} */
|
|
561
|
+
temporaryIds;
|
|
434
562
|
|
|
435
563
|
/** Flag set when template and styles have been interpolated */
|
|
436
564
|
interpolated = false;
|
|
@@ -453,6 +581,24 @@ export default class Composition {
|
|
|
453
581
|
yield this.template;
|
|
454
582
|
}
|
|
455
583
|
|
|
584
|
+
/**
|
|
585
|
+
* @template T
|
|
586
|
+
* @param {ConstructorParameters<typeof Composition<T>>} parts
|
|
587
|
+
* @return {Composition<T>}
|
|
588
|
+
*/
|
|
589
|
+
static compose(...parts) {
|
|
590
|
+
for (const [cache, comp] of compositionCache) {
|
|
591
|
+
if (cache.length !== parts.length) continue;
|
|
592
|
+
if (parts.every((part, index) => part === cache[index])) {
|
|
593
|
+
return comp;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
const composition = new Composition(...parts);
|
|
598
|
+
compositionCache.set(parts, composition);
|
|
599
|
+
return composition;
|
|
600
|
+
}
|
|
601
|
+
|
|
456
602
|
/**
|
|
457
603
|
* @param {CompositionPart<T>[]} parts
|
|
458
604
|
*/
|
|
@@ -472,13 +618,15 @@ export default class Composition {
|
|
|
472
618
|
return this;
|
|
473
619
|
}
|
|
474
620
|
|
|
475
|
-
/** @param {
|
|
621
|
+
/** @param {CompositionEventListener<T>} listener */
|
|
476
622
|
addCompositionEventListener(listener) {
|
|
477
623
|
const key = listener.tag ?? '';
|
|
478
|
-
|
|
479
|
-
|
|
624
|
+
// eslint-disable-next-line no-multi-assign
|
|
625
|
+
const events = (this.events ??= new Map());
|
|
626
|
+
if (events.has(key)) {
|
|
627
|
+
events.get(key).push(listener);
|
|
480
628
|
} else {
|
|
481
|
-
|
|
629
|
+
events.set(key, [listener]);
|
|
482
630
|
}
|
|
483
631
|
return this;
|
|
484
632
|
}
|
|
@@ -490,7 +638,7 @@ export default class Composition {
|
|
|
490
638
|
* @return {void}
|
|
491
639
|
*/
|
|
492
640
|
#bindCompositionEventListeners(tag, target, context) {
|
|
493
|
-
if (!this.events
|
|
641
|
+
if (!this.events?.has(tag)) return;
|
|
494
642
|
for (const event of this.events.get(tag)) {
|
|
495
643
|
let listener;
|
|
496
644
|
if (event.handleEvent) {
|
|
@@ -508,7 +656,6 @@ export default class Composition {
|
|
|
508
656
|
* TODO: Add types and clean up closure leak
|
|
509
657
|
* Updates component nodes based on data.
|
|
510
658
|
* Expects data in JSON Merge Patch format
|
|
511
|
-
*
|
|
512
659
|
* @see https://www.rfc-editor.org/rfc/rfc7386
|
|
513
660
|
* @template {Object} T
|
|
514
661
|
* @param {Partial<T>} changes what specifically
|
|
@@ -519,41 +666,53 @@ export default class Composition {
|
|
|
519
666
|
render(changes, data, options = {}) {
|
|
520
667
|
// console.log('render', changes, options);
|
|
521
668
|
if (!this.interpolated) {
|
|
522
|
-
this.interpolate({
|
|
669
|
+
this.interpolate({
|
|
670
|
+
defaults: data ?? changes,
|
|
671
|
+
...options,
|
|
672
|
+
});
|
|
523
673
|
}
|
|
524
674
|
|
|
525
675
|
const instanceFragment = /** @type {DocumentFragment} */ (this.cloneable.cloneNode(true));
|
|
526
676
|
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
const isShadowRoot = target instanceof ShadowRoot;
|
|
677
|
+
const shadowRoot = options.shadowRoot;
|
|
678
|
+
const target = shadowRoot ?? options.target ?? instanceFragment.firstElementChild;
|
|
530
679
|
|
|
531
680
|
/** @type {InitializationState} */
|
|
532
681
|
const initState = {
|
|
533
|
-
instanceFragment,
|
|
534
682
|
lastChildNode: null,
|
|
535
683
|
lastChildNodeIndex: 0,
|
|
536
684
|
lastElement: null,
|
|
537
|
-
|
|
538
|
-
|
|
685
|
+
nodeStates: new Uint8Array(this._interpolationState.nodeIndex + 1),
|
|
686
|
+
searchStates: new Uint8Array(this._interpolationState.searchIndex),
|
|
539
687
|
comments: [],
|
|
540
688
|
nodes: [],
|
|
541
689
|
caches: this.initCache.slice(),
|
|
542
|
-
dirtyFlags: [],
|
|
543
690
|
refs: [],
|
|
544
691
|
options,
|
|
545
692
|
};
|
|
546
693
|
|
|
547
|
-
const nodes = initState
|
|
694
|
+
const { nodes, refs, searchStates, caches } = initState;
|
|
548
695
|
for (const { tag, textNodes } of this.nodesToBind) {
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
696
|
+
/** @type {Text} */
|
|
697
|
+
let textNode;
|
|
698
|
+
if (tag === '') {
|
|
699
|
+
if (!textNodes.length) {
|
|
700
|
+
console.warn('why was root tagged?');
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
console.warn('found empty tag??');
|
|
704
|
+
refs.push(null);
|
|
705
|
+
nodes.push(null);
|
|
706
|
+
textNode = instanceFragment.firstChild;
|
|
707
|
+
} else {
|
|
708
|
+
const element = instanceFragment.getElementById(tag);
|
|
709
|
+
refs.push(element);
|
|
710
|
+
nodes.push(element);
|
|
711
|
+
this.#bindCompositionEventListeners(tag, element, options.context);
|
|
712
|
+
if (!textNodes.length) continue;
|
|
713
|
+
textNode = element.firstChild;
|
|
714
|
+
}
|
|
555
715
|
|
|
556
|
-
let textNode = element.firstChild;
|
|
557
716
|
let currentIndex = 0;
|
|
558
717
|
for (const index of textNodes) {
|
|
559
718
|
while (index !== currentIndex) {
|
|
@@ -570,32 +729,35 @@ export default class Composition {
|
|
|
570
729
|
action.invocation(initState);
|
|
571
730
|
}
|
|
572
731
|
|
|
732
|
+
/**
|
|
733
|
+
* @param {Partial<T>} changes
|
|
734
|
+
* @param {T} data
|
|
735
|
+
*/
|
|
573
736
|
const draw = (changes, data) => {
|
|
574
737
|
let ranSearch = false;
|
|
575
738
|
for (const prop of this.props) {
|
|
576
|
-
if (!this.actionsByPropsUsed
|
|
739
|
+
if (!this.actionsByPropsUsed?.has(prop)) continue;
|
|
577
740
|
if (!(prop in changes)) continue;
|
|
578
741
|
const actions = this.actionsByPropsUsed.get(prop);
|
|
579
742
|
for (const action of actions) {
|
|
580
743
|
ranSearch = true;
|
|
581
|
-
const
|
|
582
|
-
if (
|
|
583
|
-
// console.log('dirty, updating from batch', initState.nodes[action.nodeIndex], 'with',
|
|
584
|
-
action.invocation(initState,
|
|
744
|
+
const { dirty, value } = executeSearch(action.search, initState, changes, data);
|
|
745
|
+
if (dirty) {
|
|
746
|
+
// console.log('dirty, updating from batch', initState.nodes[action.nodeIndex], 'with', value);
|
|
747
|
+
action.invocation(initState, value, changes, data);
|
|
585
748
|
}
|
|
586
749
|
}
|
|
587
750
|
}
|
|
588
751
|
if (!ranSearch) return;
|
|
589
|
-
|
|
590
|
-
initState.dirtyFlags.fill(false);
|
|
752
|
+
searchStates.fill(0);
|
|
591
753
|
};
|
|
592
754
|
|
|
593
|
-
if (
|
|
594
|
-
options.context ??=
|
|
595
|
-
if ('adoptedStyleSheets' in
|
|
755
|
+
if (shadowRoot) {
|
|
756
|
+
options.context ??= shadowRoot.host;
|
|
757
|
+
if ('adoptedStyleSheets' in shadowRoot) {
|
|
596
758
|
if (this.adoptedStyleSheets.length) {
|
|
597
|
-
|
|
598
|
-
...
|
|
759
|
+
shadowRoot.adoptedStyleSheets = [
|
|
760
|
+
...shadowRoot.adoptedStyleSheets,
|
|
599
761
|
...this.adoptedStyleSheets,
|
|
600
762
|
];
|
|
601
763
|
}
|
|
@@ -611,26 +773,32 @@ export default class Composition {
|
|
|
611
773
|
draw(changes, data);
|
|
612
774
|
}
|
|
613
775
|
|
|
614
|
-
if (
|
|
615
|
-
|
|
776
|
+
if (shadowRoot) {
|
|
777
|
+
shadowRoot.append(instanceFragment);
|
|
778
|
+
customElements.upgrade(shadowRoot);
|
|
616
779
|
}
|
|
617
780
|
|
|
618
781
|
draw.target = target;
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* @param {keyof T & string} prop
|
|
785
|
+
* @param {any} value
|
|
786
|
+
* @param {Partial<T>} [data]
|
|
787
|
+
*/
|
|
619
788
|
draw.byProp = (prop, value, data) => {
|
|
620
|
-
if (!this.actionsByPropsUsed
|
|
789
|
+
if (!this.actionsByPropsUsed?.has(prop)) return;
|
|
621
790
|
let ranSearch = false;
|
|
622
791
|
|
|
623
792
|
// Update search
|
|
624
|
-
if (this.searchByQuery
|
|
793
|
+
if (this.searchByQuery?.has(prop)) {
|
|
625
794
|
ranSearch = true;
|
|
626
795
|
const search = this.searchByQuery.get(prop);
|
|
627
|
-
const cachedValue =
|
|
796
|
+
const cachedValue = caches[search.cacheIndex];
|
|
628
797
|
if (cachedValue === value) {
|
|
629
798
|
return;
|
|
630
799
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
initState.dirtyFlags[search.dirtyIndex] = true;
|
|
800
|
+
caches[search.cacheIndex] = value;
|
|
801
|
+
searchStates[search.searchIndex] = 0b0011;
|
|
634
802
|
}
|
|
635
803
|
|
|
636
804
|
let changes;
|
|
@@ -651,8 +819,7 @@ export default class Composition {
|
|
|
651
819
|
}
|
|
652
820
|
|
|
653
821
|
if (!ranSearch) return;
|
|
654
|
-
|
|
655
|
-
initState.dirtyFlags.fill(false);
|
|
822
|
+
searchStates.fill(0);
|
|
656
823
|
};
|
|
657
824
|
draw.state = initState;
|
|
658
825
|
return draw;
|
|
@@ -660,7 +827,7 @@ export default class Composition {
|
|
|
660
827
|
|
|
661
828
|
/**
|
|
662
829
|
* @param {Attr|Text} node
|
|
663
|
-
* @param {Element} element
|
|
830
|
+
* @param {Element|null} [element]
|
|
664
831
|
* @param {InterpolateOptions} [options]
|
|
665
832
|
* @param {string} [parsedValue]
|
|
666
833
|
* @return {true|undefined} remove node
|
|
@@ -683,7 +850,7 @@ export default class Composition {
|
|
|
683
850
|
if (!nodeValue) return;
|
|
684
851
|
const trimmed = nodeValue.trim();
|
|
685
852
|
if (!trimmed) return;
|
|
686
|
-
if (attr) {
|
|
853
|
+
if (attr || element?.tagName === 'STYLE') {
|
|
687
854
|
if (trimmed[0] !== '{') return;
|
|
688
855
|
const { length } = trimmed;
|
|
689
856
|
if (trimmed[length - 1] !== '}') return;
|
|
@@ -798,7 +965,7 @@ export default class Composition {
|
|
|
798
965
|
/** @type {RenderGraphSearch} */
|
|
799
966
|
let search;
|
|
800
967
|
|
|
801
|
-
if (this.searchByQuery
|
|
968
|
+
if (this.searchByQuery?.has(query)) {
|
|
802
969
|
search = this.searchByQuery.get(query);
|
|
803
970
|
} else {
|
|
804
971
|
// Has subquery?
|
|
@@ -806,7 +973,7 @@ export default class Composition {
|
|
|
806
973
|
const isSubquery = subquery !== query;
|
|
807
974
|
/** @type {RenderGraphSearch} */
|
|
808
975
|
let subSearch;
|
|
809
|
-
if (isSubquery && this.searchByQuery
|
|
976
|
+
if (isSubquery && this.searchByQuery?.has(subquery)) {
|
|
810
977
|
subSearch = this.searchByQuery.get(subquery);
|
|
811
978
|
} else {
|
|
812
979
|
// Construct subsearch, even is not subquery.
|
|
@@ -846,7 +1013,7 @@ export default class Composition {
|
|
|
846
1013
|
}
|
|
847
1014
|
if (defaultValue == null && options?.injections) {
|
|
848
1015
|
defaultValue = valueFromPropName(parsedValue, options.injections);
|
|
849
|
-
console.log('default value from injection', parsedValue, { defaultValue });
|
|
1016
|
+
// console.log('default value from injection', parsedValue, { defaultValue });
|
|
850
1017
|
}
|
|
851
1018
|
}
|
|
852
1019
|
|
|
@@ -893,9 +1060,8 @@ export default class Composition {
|
|
|
893
1060
|
inlineFunctionOptions.deepProps = deepPropsUsed;
|
|
894
1061
|
}
|
|
895
1062
|
subSearch = {
|
|
896
|
-
cacheIndex: this
|
|
897
|
-
|
|
898
|
-
ranFlagIndex: this.#interpolationState.ranFlagIndex++,
|
|
1063
|
+
cacheIndex: this._interpolationState.cacheIndex++,
|
|
1064
|
+
searchIndex: this._interpolationState.searchIndex++,
|
|
899
1065
|
query: subquery,
|
|
900
1066
|
defaultValue,
|
|
901
1067
|
subSearch: null,
|
|
@@ -910,9 +1076,8 @@ export default class Composition {
|
|
|
910
1076
|
}
|
|
911
1077
|
if (isSubquery) {
|
|
912
1078
|
search = {
|
|
913
|
-
cacheIndex: this
|
|
914
|
-
|
|
915
|
-
ranFlagIndex: this.#interpolationState.ranFlagIndex++,
|
|
1079
|
+
cacheIndex: this._interpolationState.cacheIndex++,
|
|
1080
|
+
searchIndex: this._interpolationState.searchIndex++,
|
|
916
1081
|
query,
|
|
917
1082
|
subSearch,
|
|
918
1083
|
negate,
|
|
@@ -942,7 +1107,6 @@ export default class Composition {
|
|
|
942
1107
|
let subnode = null;
|
|
943
1108
|
let defaultValue = search.defaultValue;
|
|
944
1109
|
if (text) {
|
|
945
|
-
text.data = defaultValue;
|
|
946
1110
|
subnode = textNodeIndex;
|
|
947
1111
|
} else if (nodeName === 'mdw-if') {
|
|
948
1112
|
tag = this.#tagElement(element);
|
|
@@ -960,15 +1124,15 @@ export default class Composition {
|
|
|
960
1124
|
tag ??= this.#tagElement(element);
|
|
961
1125
|
|
|
962
1126
|
// Node entry
|
|
963
|
-
let nodeEntry = this
|
|
1127
|
+
let nodeEntry = this._interpolationState.nodeEntry;
|
|
964
1128
|
if (!nodeEntry || nodeEntry.tag !== tag) {
|
|
965
1129
|
nodeEntry = {
|
|
966
1130
|
tag,
|
|
967
1131
|
textNodes: [],
|
|
968
1132
|
};
|
|
969
|
-
this
|
|
1133
|
+
this._interpolationState.nodeEntry = nodeEntry;
|
|
970
1134
|
this.nodesToBind.push(nodeEntry);
|
|
971
|
-
this
|
|
1135
|
+
this._interpolationState.nodeIndex++;
|
|
972
1136
|
}
|
|
973
1137
|
|
|
974
1138
|
/** @type {RenderGraphAction} */
|
|
@@ -978,16 +1142,18 @@ export default class Composition {
|
|
|
978
1142
|
if (text) {
|
|
979
1143
|
nodeEntry.textNodes.push(textNodeIndex);
|
|
980
1144
|
|
|
981
|
-
this
|
|
1145
|
+
this._interpolationState.nodeIndex++;
|
|
982
1146
|
action = {
|
|
983
|
-
nodeIndex: this
|
|
984
|
-
|
|
1147
|
+
nodeIndex: this._interpolationState.nodeIndex,
|
|
1148
|
+
commentIndex: this._interpolationState.commentIndex++,
|
|
1149
|
+
invocation: writeDynamicNode,
|
|
985
1150
|
defaultValue,
|
|
986
1151
|
search,
|
|
987
1152
|
};
|
|
1153
|
+
text.data = typeof defaultValue === 'string' ? defaultValue : '';
|
|
988
1154
|
} else if (subnode) {
|
|
989
1155
|
action = {
|
|
990
|
-
nodeIndex: this
|
|
1156
|
+
nodeIndex: this._interpolationState.nodeIndex,
|
|
991
1157
|
attrName: subnode,
|
|
992
1158
|
defaultValue,
|
|
993
1159
|
invocation: writeDOMAttribute,
|
|
@@ -995,8 +1161,8 @@ export default class Composition {
|
|
|
995
1161
|
};
|
|
996
1162
|
} else {
|
|
997
1163
|
action = {
|
|
998
|
-
nodeIndex: this
|
|
999
|
-
commentIndex: this
|
|
1164
|
+
nodeIndex: this._interpolationState.nodeIndex,
|
|
1165
|
+
commentIndex: this._interpolationState.commentIndex++,
|
|
1000
1166
|
defaultValue,
|
|
1001
1167
|
invocation: writeDOMElementAttachedState,
|
|
1002
1168
|
search,
|
|
@@ -1004,13 +1170,15 @@ export default class Composition {
|
|
|
1004
1170
|
if (!defaultValue) {
|
|
1005
1171
|
this.postInitActions.push({
|
|
1006
1172
|
...action,
|
|
1007
|
-
invocation:
|
|
1173
|
+
invocation: writeDOMHideNodeOnInit,
|
|
1008
1174
|
});
|
|
1009
1175
|
}
|
|
1010
1176
|
}
|
|
1011
1177
|
|
|
1012
1178
|
this.addAction(action);
|
|
1013
|
-
|
|
1179
|
+
// eslint-disable-next-line no-multi-assign
|
|
1180
|
+
const tagsWithBindings = (this.tagsWithBindings ??= new Set());
|
|
1181
|
+
tagsWithBindings.add(tag);
|
|
1014
1182
|
}
|
|
1015
1183
|
|
|
1016
1184
|
/**
|
|
@@ -1018,6 +1186,7 @@ export default class Composition {
|
|
|
1018
1186
|
* @return {string}
|
|
1019
1187
|
*/
|
|
1020
1188
|
#tagElement(element) {
|
|
1189
|
+
if (!element) return '';
|
|
1021
1190
|
let id = element.id;
|
|
1022
1191
|
if (id) {
|
|
1023
1192
|
if (!this.allIds.includes(id)) {
|
|
@@ -1025,7 +1194,9 @@ export default class Composition {
|
|
|
1025
1194
|
}
|
|
1026
1195
|
} else {
|
|
1027
1196
|
id = generateUID();
|
|
1028
|
-
|
|
1197
|
+
// eslint-disable-next-line no-multi-assign
|
|
1198
|
+
const temporaryIds = (this.temporaryIds ??= new Set());
|
|
1199
|
+
temporaryIds.add(id);
|
|
1029
1200
|
this.allIds.push(id);
|
|
1030
1201
|
element.id = id;
|
|
1031
1202
|
}
|
|
@@ -1034,11 +1205,10 @@ export default class Composition {
|
|
|
1034
1205
|
|
|
1035
1206
|
/**
|
|
1036
1207
|
* TODO: Subtemplating lacks optimization, though functional.
|
|
1037
|
-
*
|
|
1208
|
+
* - Would benefit from custom type handler for arrays
|
|
1038
1209
|
* to avoid multi-iteration change-detection.
|
|
1039
|
-
*
|
|
1040
|
-
*
|
|
1041
|
-
*
|
|
1210
|
+
* - Could benefit from debounced/throttled render
|
|
1211
|
+
* - Consider remap of {item.prop} as {array[index].prop}
|
|
1042
1212
|
* @param {Element} element
|
|
1043
1213
|
* @param {InterpolateOptions} options
|
|
1044
1214
|
* @return {?Composition<?>}
|
|
@@ -1066,21 +1236,20 @@ export default class Composition {
|
|
|
1066
1236
|
element.removeAttribute('mdw-for');
|
|
1067
1237
|
// Create a new composition targetting element as root
|
|
1068
1238
|
|
|
1069
|
-
const elementAnchor =
|
|
1239
|
+
const elementAnchor = element.ownerDocument.createElement('template');
|
|
1070
1240
|
element.replaceWith(elementAnchor);
|
|
1071
1241
|
const tag = this.#tagElement(elementAnchor);
|
|
1072
1242
|
// console.log('tagging placeholder element with', elementAnchor, tag);
|
|
1073
1243
|
|
|
1074
|
-
let nodeEntry = this
|
|
1244
|
+
let nodeEntry = this._interpolationState.nodeEntry;
|
|
1075
1245
|
if (!nodeEntry || nodeEntry.tag !== tag) {
|
|
1076
1246
|
nodeEntry = {
|
|
1077
1247
|
tag,
|
|
1078
1248
|
textNodes: [],
|
|
1079
1249
|
};
|
|
1080
|
-
this
|
|
1250
|
+
this._interpolationState.nodeEntry = nodeEntry;
|
|
1081
1251
|
this.nodesToBind.push(nodeEntry);
|
|
1082
|
-
this
|
|
1083
|
-
console.log('adding node entry', tag, this.#interpolationState.nodeIndex);
|
|
1252
|
+
this._interpolationState.nodeIndex++;
|
|
1084
1253
|
}
|
|
1085
1254
|
|
|
1086
1255
|
const newComposition = new Composition();
|
|
@@ -1095,24 +1264,20 @@ export default class Composition {
|
|
|
1095
1264
|
const propsUsed = [iterableName];
|
|
1096
1265
|
/** @type {RenderGraphSearch} */
|
|
1097
1266
|
const search = {
|
|
1098
|
-
cacheIndex: this
|
|
1099
|
-
|
|
1100
|
-
ranFlagIndex: this.#interpolationState.ranFlagIndex++,
|
|
1267
|
+
cacheIndex: this._interpolationState.cacheIndex++,
|
|
1268
|
+
searchIndex: this._interpolationState.searchIndex++,
|
|
1101
1269
|
propsUsed,
|
|
1102
1270
|
deepPropsUsed: [[iterableName]],
|
|
1103
1271
|
defaultValue: {},
|
|
1104
|
-
invocation
|
|
1105
|
-
// Return unique to always specify dirty
|
|
1106
|
-
return {};
|
|
1107
|
-
},
|
|
1272
|
+
invocation: null,
|
|
1108
1273
|
};
|
|
1109
1274
|
|
|
1110
1275
|
/** @type {RenderGraphAction} */
|
|
1111
1276
|
const action = {
|
|
1112
1277
|
defaultValue: null,
|
|
1113
|
-
nodeIndex: this
|
|
1278
|
+
nodeIndex: this._interpolationState.nodeIndex,
|
|
1114
1279
|
search,
|
|
1115
|
-
commentIndex: this
|
|
1280
|
+
commentIndex: this._interpolationState.commentIndex++,
|
|
1116
1281
|
injections,
|
|
1117
1282
|
invocation(state, value, changes, data) {
|
|
1118
1283
|
if (!newComposition.adapter) {
|
|
@@ -1120,7 +1285,7 @@ export default class Composition {
|
|
|
1120
1285
|
const instanceAnchorElement = state.nodes[this.nodeIndex];
|
|
1121
1286
|
const anchorNode = createEmptyComment();
|
|
1122
1287
|
// Avoid leak
|
|
1123
|
-
state.
|
|
1288
|
+
state.comments[this.commentIndex] = anchorNode;
|
|
1124
1289
|
instanceAnchorElement.replaceWith(anchorNode);
|
|
1125
1290
|
newComposition.adapter = new CompositionAdapter({
|
|
1126
1291
|
anchorNode,
|
|
@@ -1145,8 +1310,9 @@ export default class Composition {
|
|
|
1145
1310
|
const needTargetAll = newComposition.props.some((prop) => prop !== iterableName && prop in changes);
|
|
1146
1311
|
|
|
1147
1312
|
adapter.startBatch();
|
|
1148
|
-
|
|
1149
|
-
|
|
1313
|
+
let isArray;
|
|
1314
|
+
if (!needTargetAll && !(isArray = Array.isArray(changeList))) {
|
|
1315
|
+
const iterator = isArray ? changeList.entries() : Object.entries(changeList);
|
|
1150
1316
|
// console.log('changeList render', iterator);
|
|
1151
1317
|
for (const [key, change] of iterator) {
|
|
1152
1318
|
if (key === 'length') continue;
|
|
@@ -1204,7 +1370,9 @@ export default class Composition {
|
|
|
1204
1370
|
propsUsed.push(...newComposition.props);
|
|
1205
1371
|
this.addSearch(search);
|
|
1206
1372
|
this.addAction(action);
|
|
1207
|
-
|
|
1373
|
+
// eslint-disable-next-line no-multi-assign
|
|
1374
|
+
const tagsWithBindings = (this.tagsWithBindings ??= new Set());
|
|
1375
|
+
tagsWithBindings.add(tag);
|
|
1208
1376
|
// console.log('adding', iterable, 'bind to', this);
|
|
1209
1377
|
// this.addBinding(iterable, entry);
|
|
1210
1378
|
return newComposition;
|
|
@@ -1232,30 +1400,21 @@ export default class Composition {
|
|
|
1232
1400
|
switch (node.nodeType) {
|
|
1233
1401
|
case Node.ELEMENT_NODE:
|
|
1234
1402
|
element = /** @type {Element} */ (node);
|
|
1235
|
-
if (element
|
|
1236
|
-
node = treeWalker.
|
|
1403
|
+
if (element.tagName === 'TEMPLATE') {
|
|
1404
|
+
while (element.contains(node = treeWalker.nextNode()));
|
|
1237
1405
|
continue;
|
|
1238
1406
|
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
if (node.parentNode === this.cloneable) {
|
|
1242
|
-
this.styles.push(node);
|
|
1243
|
-
node.remove();
|
|
1244
|
-
node = treeWalker.nextSibling();
|
|
1245
|
-
continue;
|
|
1246
|
-
}
|
|
1247
|
-
console.warn('<style> element not moved');
|
|
1248
|
-
}
|
|
1249
|
-
if (node instanceof HTMLScriptElement) {
|
|
1407
|
+
|
|
1408
|
+
if (element.tagName === 'SCRIPT') {
|
|
1250
1409
|
console.warn('<script> element found.');
|
|
1251
|
-
node.
|
|
1252
|
-
node = treeWalker.nextSibling();
|
|
1410
|
+
while (element.contains(node = treeWalker.nextNode()));
|
|
1253
1411
|
continue;
|
|
1254
1412
|
}
|
|
1255
1413
|
|
|
1256
1414
|
if (element.hasAttribute('mdw-for')) {
|
|
1257
|
-
node = treeWalker.
|
|
1415
|
+
while (element.contains(node = treeWalker.nextNode()));
|
|
1258
1416
|
this.#interpolateIterable(element, options);
|
|
1417
|
+
continue;
|
|
1259
1418
|
} else {
|
|
1260
1419
|
const idAttr = element.attributes.id;
|
|
1261
1420
|
if (idAttr) {
|
|
@@ -1270,14 +1429,13 @@ export default class Composition {
|
|
|
1270
1429
|
|
|
1271
1430
|
break;
|
|
1272
1431
|
case Node.TEXT_NODE:
|
|
1273
|
-
element = node.
|
|
1432
|
+
element = node.parentElement;
|
|
1274
1433
|
if (this.#interpolateNode(/** @type {Text} */ (node), element, options)) {
|
|
1275
1434
|
const nextNode = treeWalker.nextNode();
|
|
1276
1435
|
node.remove();
|
|
1277
1436
|
node = nextNode;
|
|
1278
1437
|
continue;
|
|
1279
1438
|
}
|
|
1280
|
-
|
|
1281
1439
|
break;
|
|
1282
1440
|
default:
|
|
1283
1441
|
throw new Error(`Unexpected node type: ${node.nodeType}`);
|
|
@@ -1296,10 +1454,12 @@ export default class Composition {
|
|
|
1296
1454
|
);
|
|
1297
1455
|
}
|
|
1298
1456
|
|
|
1299
|
-
this.props =
|
|
1457
|
+
this.props = this.actionsByPropsUsed
|
|
1458
|
+
? [...this.actionsByPropsUsed.keys()]
|
|
1459
|
+
: [];
|
|
1300
1460
|
|
|
1301
1461
|
for (const id of this.allIds) {
|
|
1302
|
-
if (!this.tagsWithBindings
|
|
1462
|
+
if (!this.tagsWithBindings?.has(id)) {
|
|
1303
1463
|
this.nodesToBind.push({
|
|
1304
1464
|
tag: id,
|
|
1305
1465
|
textNodes: [],
|
|
@@ -1308,7 +1468,6 @@ export default class Composition {
|
|
|
1308
1468
|
}
|
|
1309
1469
|
|
|
1310
1470
|
this.tags = this.nodesToBind.map((n) => n.tag);
|
|
1311
|
-
|
|
1312
1471
|
this.interpolated = true;
|
|
1313
1472
|
|
|
1314
1473
|
// console.log('Cloneable', [...this.cloneable.children].map((child) => child.outerHTML).join('\n'));
|
|
@@ -1321,7 +1480,9 @@ export default class Composition {
|
|
|
1321
1480
|
addSearch(search) {
|
|
1322
1481
|
this.searches.push(search);
|
|
1323
1482
|
if (search.query) {
|
|
1324
|
-
|
|
1483
|
+
// eslint-disable-next-line no-multi-assign
|
|
1484
|
+
const searchByQuery = (this.searchByQuery ??= new Map());
|
|
1485
|
+
searchByQuery.set(search.query, search);
|
|
1325
1486
|
this.initCache[search.cacheIndex] = search.defaultValue;
|
|
1326
1487
|
}
|
|
1327
1488
|
return search;
|
|
@@ -1332,12 +1493,13 @@ export default class Composition {
|
|
|
1332
1493
|
* @return {RenderGraphAction}
|
|
1333
1494
|
*/
|
|
1334
1495
|
addAction(action) {
|
|
1335
|
-
|
|
1496
|
+
// eslint-disable-next-line no-multi-assign
|
|
1497
|
+
const actionsByPropsUsed = (this.actionsByPropsUsed ??= new Map());
|
|
1336
1498
|
for (const prop of action.search.propsUsed) {
|
|
1337
|
-
if (
|
|
1338
|
-
|
|
1499
|
+
if (actionsByPropsUsed.has(prop)) {
|
|
1500
|
+
actionsByPropsUsed.get(prop).push(action);
|
|
1339
1501
|
} else {
|
|
1340
|
-
|
|
1502
|
+
actionsByPropsUsed.set(prop, [action]);
|
|
1341
1503
|
}
|
|
1342
1504
|
}
|
|
1343
1505
|
return action;
|