@supersoniks/concorde 4.9.98-visual-stack.1 → 4.9.98-visual-stack.3
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/.gitlab-ci.yml +0 -13
- package/build-infos.json +1 -1
- package/concorde-3d.bundle.js +1 -1
- package/concorde-3d.es.js +2 -2
- package/concorde-core.bundle.js +557 -622
- package/concorde-core.es.js +6025 -5575
- package/concorde-hugging-face-infer.bundle.js +1 -1
- package/concorde-hugging-face-infer.es.js +1 -1
- package/concorde-interactive.bundle.js +1162 -0
- package/concorde-interactive.es.js +10723 -0
- package/concorde-shader.bundle.js +1 -1
- package/concorde-shader.es.js +2 -2
- package/concorde-webgpu.bundle.js +1 -1
- package/concorde-webgpu.es.js +2 -2
- package/dist/concorde-3d.bundle.js +1 -1
- package/dist/concorde-3d.es.js +2 -2
- package/dist/concorde-core.bundle.js +557 -622
- package/dist/concorde-core.es.js +6025 -5575
- package/dist/concorde-hugging-face-infer.bundle.js +1 -1
- package/dist/concorde-hugging-face-infer.es.js +1 -1
- package/dist/concorde-interactive.bundle.js +1162 -0
- package/dist/concorde-interactive.es.js +10723 -0
- package/dist/concorde-shader.bundle.js +1 -1
- package/dist/concorde-shader.es.js +2 -2
- package/dist/concorde-webgpu.bundle.js +1 -1
- package/dist/concorde-webgpu.es.js +2 -2
- package/dist/docs-mock-api-sw.js +5 -1
- package/dist/docs-mock-api-sw.js.map +2 -2
- package/dist/js/addons/interactive.js +6 -0
- package/dist/js/addons/interactive.js.map +1 -0
- package/dist/js/core/components/functional/if/if.js +65 -7
- package/dist/js/core/components/functional/if/if.js.map +1 -1
- package/dist/js/core/components/functional/interactive/action.js +96 -0
- package/dist/js/core/components/functional/interactive/action.js.map +1 -0
- package/dist/js/core/components/functional/interactive/gamepad.js +206 -0
- package/dist/js/core/components/functional/interactive/gamepad.js.map +1 -0
- package/dist/js/core/components/functional/interactive/gesture.js +148 -0
- package/dist/js/core/components/functional/interactive/gesture.js.map +1 -0
- package/dist/js/core/components/functional/interactive/helpers.js +82 -0
- package/dist/js/core/components/functional/interactive/helpers.js.map +1 -0
- package/dist/js/core/components/functional/interactive/index.js +20 -0
- package/dist/js/core/components/functional/interactive/index.js.map +1 -0
- package/dist/js/core/components/functional/interactive/keyboard.js +183 -0
- package/dist/js/core/components/functional/interactive/keyboard.js.map +1 -0
- package/dist/js/core/components/functional/interactive/matrix.js +201 -0
- package/dist/js/core/components/functional/interactive/matrix.js.map +1 -0
- package/dist/js/core/components/functional/interactive/registry.js +28 -0
- package/dist/js/core/components/functional/interactive/registry.js.map +1 -0
- package/dist/js/core/components/functional/interactive/store.js +264 -0
- package/dist/js/core/components/functional/interactive/store.js.map +1 -0
- package/dist/js/core/components/functional/interactive/ticker.js +182 -0
- package/dist/js/core/components/functional/interactive/ticker.js.map +1 -0
- package/dist/js/core/components/functional/value/value.js +49 -4
- package/dist/js/core/components/functional/value/value.js.map +1 -1
- package/dist/js/core/components/ui/_css/rounded.js +34 -0
- package/dist/js/core/components/ui/_css/rounded.js.map +1 -0
- package/dist/js/core/components/ui/_css/type.js +44 -0
- package/dist/js/core/components/ui/_css/type.js.map +1 -1
- package/dist/js/core/components/ui/_i18n/ui-aria-labels.js +95 -0
- package/dist/js/core/components/ui/_i18n/ui-aria-labels.js.map +1 -0
- package/dist/js/core/components/ui/alert/alert.js +72 -87
- package/dist/js/core/components/ui/alert/alert.js.map +1 -1
- package/dist/js/core/components/ui/alert-messages/alert-messages.js +1 -0
- package/dist/js/core/components/ui/alert-messages/alert-messages.js.map +1 -1
- package/dist/js/core/components/ui/badge/badge.js +29 -80
- package/dist/js/core/components/ui/badge/badge.js.map +1 -1
- package/dist/js/core/components/ui/button/button.js +8 -7
- package/dist/js/core/components/ui/button/button.js.map +1 -1
- package/dist/js/core/components/ui/card/card-header.js +7 -2
- package/dist/js/core/components/ui/card/card-header.js.map +1 -1
- package/dist/js/core/components/ui/divider/divider.js +1 -1
- package/dist/js/core/components/ui/divider/divider.js.map +1 -1
- package/dist/js/core/components/ui/form/checkbox/checkbox.js +4 -20
- package/dist/js/core/components/ui/form/checkbox/checkbox.js.map +1 -1
- package/dist/js/core/components/ui/form/fieldset/legend-description.js +1 -1
- package/dist/js/core/components/ui/form/fieldset/legend.js +1 -1
- package/dist/js/core/components/ui/form/input/input.js +12 -15
- package/dist/js/core/components/ui/form/input/input.js.map +1 -1
- package/dist/js/core/components/ui/form/input-autocomplete/input-autocomplete.js +363 -158
- package/dist/js/core/components/ui/form/input-autocomplete/input-autocomplete.js.map +1 -1
- package/dist/js/core/components/ui/form/radio/radio.js +1 -1
- package/dist/js/core/components/ui/form/select/select.js +3 -6
- package/dist/js/core/components/ui/form/select/select.js.map +1 -1
- package/dist/js/core/components/ui/form/textarea/textarea.js +1 -2
- package/dist/js/core/components/ui/form/textarea/textarea.js.map +1 -1
- package/dist/js/core/components/ui/image/image.js +9 -37
- package/dist/js/core/components/ui/image/image.js.map +1 -1
- package/dist/js/core/components/ui/link/link.js +25 -26
- package/dist/js/core/components/ui/link/link.js.map +1 -1
- package/dist/js/core/components/ui/modal/modal-close.js +3 -12
- package/dist/js/core/components/ui/modal/modal-close.js.map +1 -1
- package/dist/js/core/components/ui/modal/modal.js +18 -18
- package/dist/js/core/components/ui/modal/modal.js.map +1 -1
- package/dist/js/core/components/ui/pop/pop.js +131 -112
- package/dist/js/core/components/ui/pop/pop.js.map +1 -1
- package/dist/js/core/components/ui/table/table.js.map +1 -1
- package/dist/js/core/components/ui/theme/theme.js +1 -1
- package/dist/js/core/components/ui/toast/dismissed.js +9 -0
- package/dist/js/core/components/ui/toast/dismissed.js.map +1 -0
- package/dist/js/core/components/ui/toast/render-content.js +14 -0
- package/dist/js/core/components/ui/toast/render-content.js.map +1 -0
- package/dist/js/core/components/ui/toast/toast-item.js +150 -96
- package/dist/js/core/components/ui/toast/toast-item.js.map +1 -1
- package/dist/js/core/components/ui/toast/toast.js +41 -13
- package/dist/js/core/components/ui/toast/toast.js.map +1 -1
- package/dist/js/core/components/ui/tooltip/tooltip.js +144 -143
- package/dist/js/core/components/ui/tooltip/tooltip.js.map +1 -1
- package/dist/js/core/decorators/subscriber/ancestorAttribute.js.map +1 -1
- package/dist/js/core/decorators/subscriber/derive.js +3 -1
- package/dist/js/core/decorators/subscriber/derive.js.map +1 -1
- package/dist/js/core/mixins/Fetcher.js.map +1 -1
- package/dist/js/core/mixins/FormCheckable.js +1 -8
- package/dist/js/core/mixins/FormCheckable.js.map +1 -1
- package/dist/js/core/mixins/FormElement.js +26 -53
- package/dist/js/core/mixins/FormElement.js.map +1 -1
- package/dist/js/core/utils/AncestorAttributeObserver.js +130 -55
- package/dist/js/core/utils/AncestorAttributeObserver.js.map +1 -1
- package/dist/js/core/utils/LocationHandler.js +1 -1
- package/dist/js/core/utils/LocationHandler.js.map +1 -1
- package/dist/js/core/utils/dismissed.js +23 -0
- package/dist/js/core/utils/dismissed.js.map +1 -0
- package/dist/js/core/utils/positioning.js +110 -0
- package/dist/js/core/utils/positioning.js.map +1 -0
- package/dist/js/directives.js +1 -2
- package/dist/js/directives.js.map +1 -1
- package/dist/types/addons/interactive.d.ts +6 -0
- package/dist/types/addons/interactive.d.ts.map +1 -0
- package/dist/types/core/components/functional/if/if.d.ts +14 -5
- package/dist/types/core/components/functional/if/if.d.ts.map +1 -1
- package/dist/types/core/components/functional/interactive/action.d.ts +22 -0
- package/dist/types/core/components/functional/interactive/action.d.ts.map +1 -0
- package/dist/types/core/components/functional/interactive/gamepad.d.ts +37 -0
- package/dist/types/core/components/functional/interactive/gamepad.d.ts.map +1 -0
- package/dist/types/core/components/functional/interactive/gesture.d.ts +26 -0
- package/dist/types/core/components/functional/interactive/gesture.d.ts.map +1 -0
- package/dist/types/core/components/functional/interactive/helpers.d.ts +23 -0
- package/dist/types/core/components/functional/interactive/helpers.d.ts.map +1 -0
- package/dist/types/core/components/functional/interactive/index.d.ts +20 -0
- package/dist/types/core/components/functional/interactive/index.d.ts.map +1 -0
- package/dist/types/core/components/functional/interactive/keyboard.d.ts +37 -0
- package/dist/types/core/components/functional/interactive/keyboard.d.ts.map +1 -0
- package/dist/types/core/components/functional/interactive/matrix.d.ts +31 -0
- package/dist/types/core/components/functional/interactive/matrix.d.ts.map +1 -0
- package/dist/types/core/components/functional/interactive/registry.d.ts +23 -0
- package/dist/types/core/components/functional/interactive/registry.d.ts.map +1 -0
- package/dist/types/core/components/functional/interactive/store.d.ts +46 -0
- package/dist/types/core/components/functional/interactive/store.d.ts.map +1 -0
- package/dist/types/core/components/functional/interactive/ticker.d.ts +33 -0
- package/dist/types/core/components/functional/interactive/ticker.d.ts.map +1 -0
- package/dist/types/core/components/functional/value/value.d.ts +6 -0
- package/dist/types/core/components/functional/value/value.d.ts.map +1 -1
- package/dist/types/core/components/ui/_css/rounded.d.ts +3 -0
- package/dist/types/core/components/ui/_css/rounded.d.ts.map +1 -0
- package/dist/types/core/components/ui/_css/type.d.ts +13 -0
- package/dist/types/core/components/ui/_css/type.d.ts.map +1 -1
- package/dist/types/core/components/ui/_i18n/ui-aria-labels.d.ts +83 -0
- package/dist/types/core/components/ui/_i18n/ui-aria-labels.d.ts.map +1 -0
- package/dist/types/core/components/ui/alert/alert.d.ts +14 -12
- package/dist/types/core/components/ui/alert/alert.d.ts.map +1 -1
- package/dist/types/core/components/ui/alert-messages/alert-messages.d.ts.map +1 -1
- package/dist/types/core/components/ui/badge/badge.d.ts +1 -1
- package/dist/types/core/components/ui/badge/badge.d.ts.map +1 -1
- package/dist/types/core/components/ui/button/button.d.ts +13 -29
- package/dist/types/core/components/ui/button/button.d.ts.map +1 -1
- package/dist/types/core/components/ui/card/card-header.d.ts.map +1 -1
- package/dist/types/core/components/ui/divider/divider.d.ts +2 -1
- package/dist/types/core/components/ui/divider/divider.d.ts.map +1 -1
- package/dist/types/core/components/ui/form/checkbox/checkbox.d.ts +25 -73
- package/dist/types/core/components/ui/form/checkbox/checkbox.d.ts.map +1 -1
- package/dist/types/core/components/ui/form/input/input.d.ts +14 -29
- package/dist/types/core/components/ui/form/input/input.d.ts.map +1 -1
- package/dist/types/core/components/ui/form/input-autocomplete/input-autocomplete.d.ts +63 -65
- package/dist/types/core/components/ui/form/input-autocomplete/input-autocomplete.d.ts.map +1 -1
- package/dist/types/core/components/ui/form/radio/radio.d.ts +1 -1
- package/dist/types/core/components/ui/form/select/select.d.ts +3 -5
- package/dist/types/core/components/ui/form/select/select.d.ts.map +1 -1
- package/dist/types/core/components/ui/form/textarea/textarea.d.ts +12 -28
- package/dist/types/core/components/ui/form/textarea/textarea.d.ts.map +1 -1
- package/dist/types/core/components/ui/image/image.d.ts +2 -1
- package/dist/types/core/components/ui/image/image.d.ts.map +1 -1
- package/dist/types/core/components/ui/link/link.d.ts +10 -9
- package/dist/types/core/components/ui/link/link.d.ts.map +1 -1
- package/dist/types/core/components/ui/modal/modal-close.d.ts +2 -2
- package/dist/types/core/components/ui/modal/modal-close.d.ts.map +1 -1
- package/dist/types/core/components/ui/pop/pop.d.ts +12 -4
- package/dist/types/core/components/ui/pop/pop.d.ts.map +1 -1
- package/dist/types/core/components/ui/table/table.d.ts +2 -1
- package/dist/types/core/components/ui/table/table.d.ts.map +1 -1
- package/dist/types/core/components/ui/toast/dismissed.d.ts +3 -0
- package/dist/types/core/components/ui/toast/dismissed.d.ts.map +1 -0
- package/dist/types/core/components/ui/toast/render-content.d.ts +7 -0
- package/dist/types/core/components/ui/toast/render-content.d.ts.map +1 -0
- package/dist/types/core/components/ui/toast/toast-item.d.ts +26 -9
- package/dist/types/core/components/ui/toast/toast-item.d.ts.map +1 -1
- package/dist/types/core/components/ui/toast/toast.d.ts +6 -3
- package/dist/types/core/components/ui/toast/toast.d.ts.map +1 -1
- package/dist/types/core/components/ui/toast/types.d.ts +12 -2
- package/dist/types/core/components/ui/toast/types.d.ts.map +1 -1
- package/dist/types/core/components/ui/tooltip/tooltip.d.ts +19 -11
- package/dist/types/core/components/ui/tooltip/tooltip.d.ts.map +1 -1
- package/dist/types/core/decorators/subscriber/ancestorAttribute.d.ts +3 -4
- package/dist/types/core/decorators/subscriber/ancestorAttribute.d.ts.map +1 -1
- package/dist/types/core/decorators/subscriber/derive.d.ts.map +1 -1
- package/dist/types/core/mixins/FormCheckable.d.ts +10 -27
- package/dist/types/core/mixins/FormCheckable.d.ts.map +1 -1
- package/dist/types/core/mixins/FormElement.d.ts +21 -10
- package/dist/types/core/mixins/FormElement.d.ts.map +1 -1
- package/dist/types/core/mixins/FormInput.d.ts +11 -27
- package/dist/types/core/mixins/FormInput.d.ts.map +1 -1
- package/dist/types/core/utils/AncestorAttributeObserver.d.ts +17 -9
- package/dist/types/core/utils/AncestorAttributeObserver.d.ts.map +1 -1
- package/dist/types/core/utils/LocationHandler.d.ts +3 -2
- package/dist/types/core/utils/LocationHandler.d.ts.map +1 -1
- package/dist/types/core/utils/dismissed.d.ts +3 -0
- package/dist/types/core/utils/dismissed.d.ts.map +1 -0
- package/dist/types/core/utils/positioning.d.ts +44 -0
- package/dist/types/core/utils/positioning.d.ts.map +1 -0
- package/dist/types/directives.d.ts +1 -3
- package/dist/types/directives.d.ts.map +1 -1
- package/dist/types/mixins.d.ts +22 -55
- package/dist/types/mixins.d.ts.map +1 -1
- package/docs/assets/{index-FmK4JaIM.js → index-D8MVWqY6.js} +946 -687
- package/docs/assets/index-DiD0qYvE.css +1 -0
- package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +17 -85
- package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +1 -1
- package/docs/crawl/hubs/form-components.html +13 -11
- package/docs/docs-mock-api-sw.js +5 -1
- package/docs/docs-mock-api-sw.js.map +2 -2
- package/docs/index.html +2 -2
- package/docs/llms-full.txt +12 -38
- package/docs/llms.txt +1 -1
- package/docs/src/core/components/functional/sdui/sdui.md +0 -0
- package/docs/src/core/components/ui/form/checkbox/checkbox.md +0 -0
- package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +14 -118
- package/docs/src/docs/_getting-started/create-a-component.md +0 -0
- package/docs/src/docs/_misc/formelement-subscriber-removal.md +1 -1
- package/docs/src/docs/search/docs-search.json +195 -200
- package/docs/src/tsconfig.json +324 -0
- package/gitlab/job_tests.sh +25 -12
- package/index.html +3 -3
- package/package.json +182 -10
- package/public/docs-mock-api-sw.js +5 -1
- package/public/docs-mock-api-sw.js.map +2 -2
- package/scripts/build-addons.mjs +2 -2
- package/scripts/post-build.mjs +9 -0
- package/src/addons/interactive.ts +5 -0
- package/src/core/components/functional/if/if.ts +54 -7
- package/src/core/components/functional/interactive/action.ts +84 -0
- package/src/core/components/functional/interactive/gamepad.ts +197 -0
- package/src/core/components/functional/interactive/gesture.ts +136 -0
- package/src/core/components/functional/interactive/helpers.spec.ts +50 -0
- package/src/core/components/functional/interactive/helpers.ts +97 -0
- package/src/core/components/functional/interactive/index.ts +25 -0
- package/src/core/components/functional/interactive/interactive.md +33 -0
- package/src/core/components/functional/interactive/keyboard.ts +171 -0
- package/src/core/components/functional/interactive/matrix.ts +185 -0
- package/src/core/components/functional/interactive/registry.ts +46 -0
- package/src/core/components/functional/interactive/store.ts +270 -0
- package/src/core/components/functional/interactive/ticker.ts +171 -0
- package/src/core/components/functional/list/list.ts +0 -0
- package/src/core/components/functional/subscriber/subscriber.ts +0 -0
- package/src/core/components/functional/value/value.ts +44 -4
- package/src/core/components/ui/_css/rounded.ts +36 -0
- package/src/core/components/ui/_css/type.ts +49 -0
- package/src/core/components/ui/_i18n/ui-aria-labels.ts +104 -0
- package/src/core/components/ui/alert/alert.md +128 -72
- package/src/core/components/ui/alert/alert.spec.ts +145 -0
- package/src/core/components/ui/alert/alert.ts +86 -91
- package/src/core/components/ui/alert-messages/alert-messages.ts +1 -1
- package/src/core/components/ui/badge/badge.md +126 -78
- package/src/core/components/ui/badge/badge.ts +29 -81
- package/src/core/components/ui/button/button.md +1 -0
- package/src/core/components/ui/button/button.ts +12 -10
- package/src/core/components/ui/card/card-header.ts +7 -2
- package/src/core/components/ui/card/card.md +120 -65
- package/src/core/components/ui/divider/divider.ts +4 -9
- package/src/core/components/ui/form/checkbox/checkbox.md +1 -1
- package/src/core/components/ui/form/checkbox/checkbox.ts +4 -20
- package/src/core/components/ui/form/fieldset/legend-description.ts +1 -1
- package/src/core/components/ui/form/fieldset/legend.ts +1 -1
- package/src/core/components/ui/form/input/input.md +1 -1
- package/src/core/components/ui/form/input/input.ts +25 -27
- package/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +14 -118
- package/src/core/components/ui/form/input-autocomplete/input-autocomplete.ts +419 -187
- package/src/core/components/ui/form/radio/radio.ts +1 -1
- package/src/core/components/ui/form/select/select.ts +3 -6
- package/src/core/components/ui/form/textarea/textarea.md +1 -1
- package/src/core/components/ui/form/textarea/textarea.ts +1 -2
- package/src/core/components/ui/image/image.md +147 -53
- package/src/core/components/ui/image/image.ts +10 -44
- package/src/core/components/ui/link/link.md +2 -2
- package/src/core/components/ui/link/link.ts +42 -37
- package/src/core/components/ui/modal/modal-close.ts +8 -12
- package/src/core/components/ui/modal/modal.ts +18 -18
- package/src/core/components/ui/pop/pop.md +105 -1
- package/src/core/components/ui/pop/pop.ts +145 -141
- package/src/core/components/ui/table/table.ts +2 -8
- package/src/core/components/ui/theme/theme.ts +1 -1
- package/src/core/components/ui/toast/dismissed.ts +14 -0
- package/src/core/components/ui/toast/render-content.ts +13 -0
- package/src/core/components/ui/toast/toast-item.ts +179 -103
- package/src/core/components/ui/toast/toast.ts +58 -21
- package/src/core/components/ui/toast/types.ts +14 -2
- package/src/core/components/ui/tooltip/tooltip.ts +176 -154
- package/src/core/decorators/subscriber/ancestorAttribute.spec.ts +26 -0
- package/src/core/decorators/subscriber/ancestorAttribute.ts +3 -4
- package/src/core/decorators/subscriber/derive.ts +3 -3
- package/src/core/mixins/Fetcher.ts +1 -1
- package/src/core/mixins/FormCheckable.ts +1 -8
- package/src/core/mixins/FormElement.ts +74 -76
- package/src/core/mixins/Subscriber.ts +5 -1
- package/src/core/utils/AncestorAttributeObserver.ts +183 -70
- package/src/core/utils/DataBindObserver.ts +0 -0
- package/src/core/utils/LocationHandler.ts +12 -5
- package/src/core/utils/Objects.ts +0 -0
- package/src/core/utils/dismissed.ts +22 -0
- package/src/core/utils/positioning.spec.ts +208 -0
- package/src/core/utils/positioning.ts +183 -0
- package/src/directives.ts +1 -3
- package/src/docs/_core-concept/dataFlow.md +1 -1
- package/src/docs/_decorators/ancestor-attribute.md +3 -2
- package/src/docs/_getting-started/cdn-addons.md +1 -0
- package/src/docs/_getting-started/concorde-outside.md +3 -3
- package/src/docs/_misc/formelement-subscriber-removal.md +115 -0
- package/src/docs/_misc/html-integration.md +2 -0
- package/src/docs/code.ts +3 -1
- package/src/docs/components/docs-demo-sources.ts +60 -0
- package/src/docs/docs.ts +1 -0
- package/src/docs/example/docs-input-autocomplete-demos.ts +110 -0
- package/src/docs/mock-api/router.ts +17 -1
- package/src/docs/navigation/navigation.ts +8 -0
- package/src/docs/search/docs-search.json +956 -243
- package/src/docs/tailwind/css/tailwind.css +13 -6
- package/src/tsconfig.json +135 -6
- package/src/tsconfig.tsbuildinfo +1 -1
- package/tailwind.config.js +50 -3
- package/vite/config.js +23 -35
- package/vite.config.mts +5 -0
- package/vitest.setup.ts +49 -13
- package/docs/assets/index-BZiZXMU-.css +0 -1
|
@@ -1,55 +1,73 @@
|
|
|
1
1
|
import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
2
2
|
import { property } from "lit/decorators.js";
|
|
3
|
-
import { SubscriberInterface } from "@supersoniks/concorde/core/mixins/Subscriber";
|
|
4
3
|
import Objects from "@supersoniks/concorde/core/utils/Objects";
|
|
5
4
|
import { traverseDotNotation } from "@supersoniks/concorde/core/utils/Objects";
|
|
5
|
+
import HTML from "@supersoniks/concorde/core/utils/HTML";
|
|
6
|
+
import { LitElement } from "lit";
|
|
6
7
|
import {
|
|
7
8
|
PublisherInterface,
|
|
8
9
|
HTMLFormControl,
|
|
9
10
|
CoreJSType,
|
|
11
|
+
MixinArgsType,
|
|
10
12
|
} from "../_types/types";
|
|
11
|
-
|
|
13
|
+
|
|
12
14
|
type Constructor<T> = new (...args: MixinArgsType[]) => T;
|
|
15
|
+
|
|
13
16
|
export type FormElementValue = string | string[] | object | null | undefined;
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
|
|
18
|
+
export interface FormElementInterface {
|
|
19
|
+
getFormPublisher(): PublisherInterface | null;
|
|
16
20
|
updateDataValue(): void;
|
|
17
21
|
handleChange(e?: Event): void;
|
|
18
22
|
handleBlur(e?: Event): void;
|
|
19
23
|
getValueForFormPublisher(): FormElementValue;
|
|
20
|
-
setValueFromPublisher(value: FormElementValue): void;
|
|
21
24
|
setFormPublisherValue(value: FormElementValue): void;
|
|
22
25
|
getFormPublisherValue(): FormElementValue;
|
|
26
|
+
setFormValueFromPublisher(value: FormElementValue): void;
|
|
23
27
|
unsetOnDisconnect(): boolean;
|
|
24
28
|
unset(): void;
|
|
25
|
-
|
|
26
29
|
validateFormElement(): void;
|
|
27
30
|
focus?: () => void;
|
|
28
31
|
forceAutoFill: boolean;
|
|
29
|
-
shadowRoot
|
|
32
|
+
shadowRoot: ShadowRoot | null;
|
|
30
33
|
error: boolean;
|
|
31
34
|
autofocus: boolean;
|
|
32
35
|
required: boolean;
|
|
33
36
|
disabled: boolean;
|
|
34
37
|
formDataProvider: string;
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
ariaLabel: string | null;
|
|
39
|
+
ariaLabelledby: string | null;
|
|
37
40
|
_value: FormElementValue;
|
|
38
41
|
get value(): FormElementValue;
|
|
39
42
|
set value(value: FormElementValue);
|
|
40
43
|
_name: string;
|
|
41
44
|
get name(): string;
|
|
42
45
|
set name(value: string);
|
|
46
|
+
getAncestorAttributeValue(attributeName: string): string;
|
|
47
|
+
hasAncestorAttribute(attributeName: string): boolean;
|
|
48
|
+
isConnected: boolean;
|
|
49
|
+
requestUpdate(): void;
|
|
50
|
+
getAttribute(name: string): string | null;
|
|
51
|
+
hasAttribute(attributeName: string): boolean;
|
|
52
|
+
setAttribute(name: string, value: string): void;
|
|
53
|
+
removeAttribute(name: string): void;
|
|
54
|
+
addEventListener(
|
|
55
|
+
type: string,
|
|
56
|
+
listener: EventListenerOrEventListenerObject,
|
|
57
|
+
options?: boolean | AddEventListenerOptions
|
|
58
|
+
): void;
|
|
59
|
+
dispatchEvent(event: Event): void;
|
|
60
|
+
connectedCallback(): void;
|
|
61
|
+
disconnectedCallback(): void;
|
|
43
62
|
}
|
|
63
|
+
|
|
44
64
|
const keyboardLoops = new Map<string, Array<FormElementInterface>>();
|
|
45
|
-
|
|
65
|
+
|
|
66
|
+
const Form = <T extends Constructor<LitElement>>(superClass: T) => {
|
|
46
67
|
/**
|
|
47
|
-
* ## FormElement
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* * On peut cependant décider de mettre à jour la donnée à une autre adresse en renseignent l'attribut *formDataProvider*.
|
|
51
|
-
* * Par conséquent, on peut par exemple le lier à un composant *queue* (via sa propriété *dataFilterProvider*) de manière à appeller en auto une api avec des filtres.
|
|
52
|
-
*
|
|
68
|
+
* ## FormElement — mixin des champs de formulaire Concorde (et sonic-button).
|
|
69
|
+
* Synchronise `value` avec `formDataProvider` + `name` uniquement
|
|
70
|
+
* (plus de canal `dataProvider` / mixin Subscriber).
|
|
53
71
|
*/
|
|
54
72
|
class FormElement extends superClass implements FormElementInterface {
|
|
55
73
|
@property({ type: Boolean, reflect: true }) touched = false;
|
|
@@ -61,19 +79,16 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
61
79
|
|
|
62
80
|
/* Attribut data-aria-label pour passer aria-label */
|
|
63
81
|
@property({ type: String, attribute: "data-aria-label" })
|
|
64
|
-
ariaLabel
|
|
82
|
+
ariaLabel: string | null = null;
|
|
65
83
|
@property({ type: String, attribute: "data-aria-labelledby" })
|
|
66
|
-
ariaLabelledby
|
|
84
|
+
ariaLabelledby: string | null = null;
|
|
67
85
|
|
|
68
|
-
onValueAssign?: (v: string) => void;
|
|
69
86
|
onFormValueAssign?: (v: string) => void;
|
|
70
87
|
onFormDataInValidate?: VoidFunction;
|
|
88
|
+
|
|
71
89
|
constructor(...args: MixinArgsType[]) {
|
|
72
90
|
super();
|
|
73
91
|
args;
|
|
74
|
-
this.onValueAssign = (value) => {
|
|
75
|
-
this.setValueFromPublisher(value);
|
|
76
|
-
};
|
|
77
92
|
this.onFormValueAssign = async (value) => {
|
|
78
93
|
this.setFormValueFromPublisher(value);
|
|
79
94
|
};
|
|
@@ -85,24 +100,41 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
85
100
|
this.validateFormElement();
|
|
86
101
|
};
|
|
87
102
|
}
|
|
103
|
+
|
|
104
|
+
@property({ type: String })
|
|
88
105
|
formDataProvider = "";
|
|
89
106
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
107
|
+
hasAncestorAttribute(attributeName: string) {
|
|
108
|
+
return HTML.getAncestorAttributeValue(
|
|
109
|
+
this as unknown as HTMLElement,
|
|
110
|
+
attributeName
|
|
111
|
+
) != null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
getAncestorAttributeValue(attributeName: string) {
|
|
115
|
+
return (
|
|
116
|
+
HTML.getAncestorAttributeValue(
|
|
117
|
+
this as unknown as HTMLElement,
|
|
118
|
+
attributeName
|
|
119
|
+
) || ""
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
93
123
|
_name = "";
|
|
94
124
|
@property() get name(): string {
|
|
95
125
|
return this._name;
|
|
96
126
|
}
|
|
97
127
|
set name(value: string) {
|
|
98
128
|
if (this.hasAttribute("name") && !this.forceAutoFill)
|
|
99
|
-
value = this.getAttribute("name");
|
|
129
|
+
value = this.getAttribute("name") as string;
|
|
100
130
|
this._name = value;
|
|
101
131
|
this.requestUpdate();
|
|
102
132
|
}
|
|
133
|
+
|
|
103
134
|
validateFormElement() {
|
|
104
|
-
//Implémentation dans une sous
|
|
135
|
+
// Implémentation dans une sous-classe
|
|
105
136
|
}
|
|
137
|
+
|
|
106
138
|
unsetOnDisconnect() {
|
|
107
139
|
return this.hasAttribute("unsetOnDisconnect");
|
|
108
140
|
}
|
|
@@ -117,15 +149,15 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
117
149
|
}
|
|
118
150
|
}
|
|
119
151
|
}
|
|
152
|
+
|
|
120
153
|
getFormPublisher() {
|
|
121
154
|
if (!this.formDataProvider)
|
|
122
155
|
this.formDataProvider =
|
|
123
|
-
this.getAncestorAttributeValue("formDataProvider");
|
|
156
|
+
this.getAncestorAttributeValue("formDataProvider") || "";
|
|
124
157
|
if (this.formDataProvider) {
|
|
125
158
|
return PublisherManager.get(this.formDataProvider);
|
|
126
159
|
}
|
|
127
160
|
return null;
|
|
128
|
-
//else return this.publisher;
|
|
129
161
|
}
|
|
130
162
|
|
|
131
163
|
setFormPublisherValue(value: FormElementValue): void {
|
|
@@ -143,31 +175,14 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
143
175
|
return null;
|
|
144
176
|
}
|
|
145
177
|
|
|
146
|
-
/**
|
|
147
|
-
* Mise en forme de la valeur fournie au formPublisher associé au composant
|
|
148
|
-
* Destinée à être surchargée si besoin (cf Form-checkable)
|
|
149
|
-
*/
|
|
150
178
|
getValueForFormPublisher() {
|
|
151
179
|
return this.value;
|
|
152
180
|
}
|
|
153
|
-
/**
|
|
154
|
-
* Mise à jour de la valeur interne du composant en fonction de la valeur venant du publisher associé au composant
|
|
155
|
-
* Destinée à être surchargée si besoin (cf Form-checkable)
|
|
156
|
-
*/
|
|
157
|
-
setValueFromPublisher(value: FormElementValue) {
|
|
158
|
-
this.value = value;
|
|
159
|
-
}
|
|
160
181
|
|
|
161
|
-
/**
|
|
162
|
-
* Mise à jour de la valeur interne du composant en fonction de la valeur venant du formPublisher associé au composant
|
|
163
|
-
* Destinée à être surchargée si besoin (cf Form-checkable)
|
|
164
|
-
*/
|
|
165
182
|
setFormValueFromPublisher(value: FormElementValue) {
|
|
166
183
|
this.value = value;
|
|
167
184
|
}
|
|
168
|
-
|
|
169
|
-
* La valeur du champ avec des caractéristiques similaire à un input html classique :
|
|
170
|
-
*/
|
|
185
|
+
|
|
171
186
|
_value: FormElementValue = "";
|
|
172
187
|
@property() get value() {
|
|
173
188
|
return this._value;
|
|
@@ -188,7 +203,8 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
188
203
|
this.updateDataValue();
|
|
189
204
|
this.requestUpdate();
|
|
190
205
|
}
|
|
191
|
-
|
|
206
|
+
|
|
207
|
+
initFormPublisher() {
|
|
192
208
|
let formPublisher = this.getFormPublisher();
|
|
193
209
|
const value =
|
|
194
210
|
this.hasAncestorAttribute("initFromPublisher") &&
|
|
@@ -196,22 +212,12 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
196
212
|
this.getFormPublisherValue()
|
|
197
213
|
? this.getFormPublisherValue()
|
|
198
214
|
: this.getAttribute("value");
|
|
199
|
-
if (this._name && this.publisher)
|
|
200
|
-
traverseDotNotation(this.publisher, this._name).offAssign(
|
|
201
|
-
this.onValueAssign
|
|
202
|
-
);
|
|
203
215
|
if (this._name && formPublisher)
|
|
204
216
|
traverseDotNotation(formPublisher, this._name).offAssign(
|
|
205
217
|
this.onFormValueAssign
|
|
206
218
|
);
|
|
207
|
-
|
|
208
|
-
if (!this.name) this._name = this.getAttribute("name");
|
|
219
|
+
if (!this.name) this._name = this.getAttribute("name") || "";
|
|
209
220
|
if (!this.value) this._value = this.getAttribute("value");
|
|
210
|
-
if (this.publisher && this._name) {
|
|
211
|
-
traverseDotNotation(this.publisher, this._name).onAssign(
|
|
212
|
-
this.onValueAssign
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
221
|
formPublisher = this.getFormPublisher();
|
|
216
222
|
if (this._name && formPublisher) {
|
|
217
223
|
traverseDotNotation(formPublisher, this._name).onAssign(
|
|
@@ -225,7 +231,6 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
225
231
|
|
|
226
232
|
handleBlur() {
|
|
227
233
|
this.touched = true;
|
|
228
|
-
// this.validateFormElement();
|
|
229
234
|
}
|
|
230
235
|
|
|
231
236
|
handleChange(e: Event) {
|
|
@@ -233,16 +238,10 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
233
238
|
const event = new Event("change");
|
|
234
239
|
this.dispatchEvent(event);
|
|
235
240
|
}
|
|
236
|
-
|
|
237
|
-
* Ajoute un comportement de navigation au clavier pour les éléments de formulaire
|
|
238
|
-
* data-keyboard-nav peut contenir plusieurs valeurs qui identifient les boucles de navigation auquelles est attaché cet élément.
|
|
239
|
-
* Les valeurs sont séparées par des espaces.
|
|
240
|
-
* En appuyant sur la touche "Down", le composant va se déplacer dans la boucle de navigation correspondante en suivant le flux.
|
|
241
|
-
* En appuyant sur la touche "Up", le déplacement inverse est effectué.
|
|
242
|
-
*/
|
|
241
|
+
|
|
243
242
|
addKeyboardNavigation() {
|
|
244
243
|
const keyboardLoopIds: string =
|
|
245
|
-
this.getAncestorAttributeValue("data-keyboard-nav");
|
|
244
|
+
this.getAncestorAttributeValue("data-keyboard-nav") || "";
|
|
246
245
|
if (!keyboardLoopIds) return;
|
|
247
246
|
|
|
248
247
|
const split = keyboardLoopIds.split(" ");
|
|
@@ -277,7 +276,7 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
277
276
|
);
|
|
278
277
|
});
|
|
279
278
|
|
|
280
|
-
let next:
|
|
279
|
+
let next: FormElementInterface | null = null;
|
|
281
280
|
if (keyboardEvent.key == "ArrowDown" && loop) {
|
|
282
281
|
const index = loop.indexOf(this);
|
|
283
282
|
if (index == loop.length - 1) {
|
|
@@ -317,13 +316,16 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
317
316
|
}
|
|
318
317
|
|
|
319
318
|
connectedCallback(): void {
|
|
320
|
-
this.formDataProvider
|
|
321
|
-
|
|
322
|
-
|
|
319
|
+
if (!this.formDataProvider) {
|
|
320
|
+
this.formDataProvider =
|
|
321
|
+
this.getAncestorAttributeValue("formDataProvider") || "";
|
|
322
|
+
}
|
|
323
323
|
|
|
324
324
|
super.connectedCallback();
|
|
325
|
+
this.initFormPublisher();
|
|
325
326
|
this.addKeyboardNavigation();
|
|
326
327
|
}
|
|
328
|
+
|
|
327
329
|
unset() {
|
|
328
330
|
this.value = null;
|
|
329
331
|
}
|
|
@@ -333,10 +335,6 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
|
|
|
333
335
|
this.unset();
|
|
334
336
|
}
|
|
335
337
|
super.disconnectedCallback();
|
|
336
|
-
if (this._name && this.publisher)
|
|
337
|
-
traverseDotNotation(this.publisher, this._name).offAssign(
|
|
338
|
-
this.onValueAssign
|
|
339
|
-
);
|
|
340
338
|
const formPublisher = this.getFormPublisher();
|
|
341
339
|
if (this._name && formPublisher) {
|
|
342
340
|
traverseDotNotation(formPublisher, this._name).offAssign(
|
|
@@ -154,7 +154,11 @@ const Subscriber = <
|
|
|
154
154
|
typeof value == "string" &&
|
|
155
155
|
["{", "["].includes(value.trim().charAt(0))
|
|
156
156
|
) {
|
|
157
|
-
|
|
157
|
+
try {
|
|
158
|
+
value = JSON.parse(value);
|
|
159
|
+
} catch {
|
|
160
|
+
/* keep raw string (ex. score/label leaf, not a JSON attr) */
|
|
161
|
+
}
|
|
158
162
|
}
|
|
159
163
|
if (value == this._props) return;
|
|
160
164
|
|
|
@@ -3,13 +3,14 @@ import HTML, { SearchableDomElement } from "./HTML";
|
|
|
3
3
|
/**
|
|
4
4
|
* Observateur pour `@ancestorAttribute({ dynamic: true })`.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* `watchScopedConfiguration` dans `api.ts`.
|
|
6
|
+
* ## Perf (FF / listes denses d'icônes)
|
|
7
|
+
* Ancien modèle : 1 MO/abonnement avec `childList` sur **toute** la chaîne +
|
|
8
|
+
* `reconnect()` à chaque mutation → O(n²) quand une list insert des siblings.
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* Modèle actuel :
|
|
11
|
+
* 1. **MO attributs partagés** — 1 observer par `(ancêtre, attributeName)`.
|
|
12
|
+
* 2. **Reparent** — 1 MO `childList` partagé sur le parent direct ; on ne
|
|
13
|
+
* réagit que si *notre* nœud est dans added/removed (insert sibling → no-op).
|
|
13
14
|
*/
|
|
14
15
|
|
|
15
16
|
type SyncOptions = {
|
|
@@ -22,7 +23,18 @@ type Subscription = {
|
|
|
22
23
|
attributeName: string;
|
|
23
24
|
propertyKey: string;
|
|
24
25
|
syncOptions: SyncOptions;
|
|
25
|
-
|
|
26
|
+
watchedAncestors: Element[];
|
|
27
|
+
parentForReparent: Element | null;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type AttrSlot = {
|
|
31
|
+
observer: MutationObserver;
|
|
32
|
+
subscriptions: Set<Subscription>;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type ParentSlot = {
|
|
36
|
+
observer: MutationObserver;
|
|
37
|
+
byComponent: Map<Element, Set<Subscription>>;
|
|
26
38
|
};
|
|
27
39
|
|
|
28
40
|
/** Chaîne composant → ancêtres, en traversant les shadow roots. */
|
|
@@ -40,58 +52,17 @@ function walkAncestorElements(node: Node): Element[] {
|
|
|
40
52
|
return elements;
|
|
41
53
|
}
|
|
42
54
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
subscription: Subscription,
|
|
49
|
-
onMutation: () => void,
|
|
50
|
-
): () => void {
|
|
51
|
-
const observers: MutationObserver[] = [];
|
|
52
|
-
let disconnected = false;
|
|
53
|
-
const attributeFilter = HTML.scopeAttributeNames(subscription.attributeName);
|
|
54
|
-
|
|
55
|
-
const reconnect = () => {
|
|
56
|
-
for (const observer of observers) {
|
|
57
|
-
observer.disconnect();
|
|
58
|
-
}
|
|
59
|
-
observers.length = 0;
|
|
60
|
-
if (disconnected) return;
|
|
61
|
-
|
|
62
|
-
for (const element of walkAncestorElements(subscription.component)) {
|
|
63
|
-
const observer = new MutationObserver((records) => {
|
|
64
|
-
if (disconnected) return;
|
|
65
|
-
if (records.some((record) => record.type === "childList")) {
|
|
66
|
-
reconnect();
|
|
67
|
-
}
|
|
68
|
-
onMutation();
|
|
69
|
-
});
|
|
70
|
-
observer.observe(element, {
|
|
71
|
-
attributes: true,
|
|
72
|
-
attributeFilter,
|
|
73
|
-
childList: true,
|
|
74
|
-
subtree: false,
|
|
75
|
-
});
|
|
76
|
-
observers.push(observer);
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
reconnect();
|
|
81
|
-
|
|
82
|
-
return () => {
|
|
83
|
-
disconnected = true;
|
|
84
|
-
for (const observer of observers) {
|
|
85
|
-
observer.disconnect();
|
|
86
|
-
}
|
|
87
|
-
observers.length = 0;
|
|
88
|
-
};
|
|
55
|
+
function directParentElement(component: HTMLElement): Element | null {
|
|
56
|
+
const parent =
|
|
57
|
+
component.parentNode ||
|
|
58
|
+
((component.getRootNode() as ShadowRoot)?.host ?? null);
|
|
59
|
+
return parent instanceof Element ? parent : null;
|
|
89
60
|
}
|
|
90
61
|
|
|
91
62
|
/**
|
|
92
63
|
* Point unique de synchronisation DOM → propriété du composant.
|
|
93
64
|
* N'assigne que si la valeur change (`Object.is`) pour limiter les re-renders Lit
|
|
94
|
-
* et éviter de reboucler inutilement `observeDynamicProperty` (@bind /
|
|
65
|
+
* et éviter de reboucler inutilement `observeDynamicProperty` (@bind / `@subscribe`).
|
|
95
66
|
*/
|
|
96
67
|
export function syncAncestorAttributeValue(
|
|
97
68
|
component: object,
|
|
@@ -115,8 +86,11 @@ export default class AncestorAttributeObserver {
|
|
|
115
86
|
private static pendingRefresh = new Set<Subscription>();
|
|
116
87
|
private static animationFrameId: number | null = null;
|
|
117
88
|
|
|
89
|
+
private static attrSlots = new WeakMap<Element, Map<string, AttrSlot>>();
|
|
90
|
+
private static parentSlots = new WeakMap<Element, ParentSlot>();
|
|
91
|
+
|
|
118
92
|
/**
|
|
119
|
-
* Enregistre un composant en mode `{ dynamic: true }
|
|
93
|
+
* Enregistre un composant en mode `{ dynamic: true }` (attributs + reparent).
|
|
120
94
|
* Le `unsubscribe` retourné doit être appelé au `disconnectedCallback`.
|
|
121
95
|
*/
|
|
122
96
|
static subscribe(
|
|
@@ -130,32 +104,172 @@ export default class AncestorAttributeObserver {
|
|
|
130
104
|
attributeName,
|
|
131
105
|
propertyKey,
|
|
132
106
|
syncOptions,
|
|
133
|
-
|
|
107
|
+
watchedAncestors: [],
|
|
108
|
+
parentForReparent: null,
|
|
134
109
|
};
|
|
135
110
|
|
|
136
|
-
subscription.disconnectObservers = attachAncestorChainObservers(
|
|
137
|
-
subscription,
|
|
138
|
-
() => {
|
|
139
|
-
if (!AncestorAttributeObserver.subscriptions.has(subscription)) return;
|
|
140
|
-
AncestorAttributeObserver.pendingRefresh.add(subscription);
|
|
141
|
-
AncestorAttributeObserver.scheduleRefresh();
|
|
142
|
-
},
|
|
143
|
-
);
|
|
144
|
-
|
|
145
111
|
AncestorAttributeObserver.subscriptions.add(subscription);
|
|
112
|
+
AncestorAttributeObserver.bindSubscription(subscription);
|
|
146
113
|
|
|
147
114
|
return () => {
|
|
148
115
|
AncestorAttributeObserver.unsubscribe(subscription);
|
|
149
116
|
};
|
|
150
117
|
}
|
|
151
118
|
|
|
152
|
-
|
|
119
|
+
private static bindSubscription(subscription: Subscription): void {
|
|
120
|
+
AncestorAttributeObserver.unbindWatchers(subscription);
|
|
121
|
+
|
|
122
|
+
const ancestors = walkAncestorElements(subscription.component);
|
|
123
|
+
subscription.watchedAncestors = ancestors;
|
|
124
|
+
|
|
125
|
+
for (const ancestor of ancestors) {
|
|
126
|
+
AncestorAttributeObserver.addAttrSlot(
|
|
127
|
+
ancestor,
|
|
128
|
+
subscription.attributeName,
|
|
129
|
+
subscription,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const parent = directParentElement(subscription.component);
|
|
134
|
+
subscription.parentForReparent = parent;
|
|
135
|
+
if (parent) {
|
|
136
|
+
AncestorAttributeObserver.addParentSlot(parent, subscription);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
AncestorAttributeObserver.pendingRefresh.add(subscription);
|
|
140
|
+
AncestorAttributeObserver.scheduleRefresh();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private static unbindWatchers(subscription: Subscription): void {
|
|
144
|
+
for (const ancestor of subscription.watchedAncestors) {
|
|
145
|
+
AncestorAttributeObserver.removeAttrSlot(
|
|
146
|
+
ancestor,
|
|
147
|
+
subscription.attributeName,
|
|
148
|
+
subscription,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
subscription.watchedAncestors = [];
|
|
152
|
+
|
|
153
|
+
if (subscription.parentForReparent) {
|
|
154
|
+
AncestorAttributeObserver.removeParentSlot(
|
|
155
|
+
subscription.parentForReparent,
|
|
156
|
+
subscription,
|
|
157
|
+
);
|
|
158
|
+
subscription.parentForReparent = null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private static addAttrSlot(
|
|
163
|
+
element: Element,
|
|
164
|
+
attributeName: string,
|
|
165
|
+
subscription: Subscription,
|
|
166
|
+
): void {
|
|
167
|
+
let byAttr = AncestorAttributeObserver.attrSlots.get(element);
|
|
168
|
+
if (!byAttr) {
|
|
169
|
+
byAttr = new Map();
|
|
170
|
+
AncestorAttributeObserver.attrSlots.set(element, byAttr);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let slot = byAttr.get(attributeName);
|
|
174
|
+
if (!slot) {
|
|
175
|
+
const attributeFilter = HTML.scopeAttributeNames(attributeName);
|
|
176
|
+
const subscriptions = new Set<Subscription>();
|
|
177
|
+
const observer = new MutationObserver(() => {
|
|
178
|
+
for (const sub of subscriptions) {
|
|
179
|
+
if (!AncestorAttributeObserver.subscriptions.has(sub)) continue;
|
|
180
|
+
AncestorAttributeObserver.pendingRefresh.add(sub);
|
|
181
|
+
}
|
|
182
|
+
AncestorAttributeObserver.scheduleRefresh();
|
|
183
|
+
});
|
|
184
|
+
observer.observe(element, {
|
|
185
|
+
attributes: true,
|
|
186
|
+
attributeFilter,
|
|
187
|
+
});
|
|
188
|
+
slot = { observer, subscriptions };
|
|
189
|
+
byAttr.set(attributeName, slot);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
slot.subscriptions.add(subscription);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private static removeAttrSlot(
|
|
196
|
+
element: Element,
|
|
197
|
+
attributeName: string,
|
|
198
|
+
subscription: Subscription,
|
|
199
|
+
): void {
|
|
200
|
+
const byAttr = AncestorAttributeObserver.attrSlots.get(element);
|
|
201
|
+
if (!byAttr) return;
|
|
202
|
+
const slot = byAttr.get(attributeName);
|
|
203
|
+
if (!slot) return;
|
|
204
|
+
|
|
205
|
+
slot.subscriptions.delete(subscription);
|
|
206
|
+
if (slot.subscriptions.size > 0) return;
|
|
207
|
+
|
|
208
|
+
slot.observer.disconnect();
|
|
209
|
+
byAttr.delete(attributeName);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private static addParentSlot(
|
|
213
|
+
parent: Element,
|
|
214
|
+
subscription: Subscription,
|
|
215
|
+
): void {
|
|
216
|
+
let slot = AncestorAttributeObserver.parentSlots.get(parent);
|
|
217
|
+
if (!slot) {
|
|
218
|
+
const byComponent = new Map<Element, Set<Subscription>>();
|
|
219
|
+
const observer = new MutationObserver((records) => {
|
|
220
|
+
const touched = new Set<Element>();
|
|
221
|
+
for (const record of records) {
|
|
222
|
+
record.removedNodes.forEach((n) => {
|
|
223
|
+
if (n instanceof Element) touched.add(n);
|
|
224
|
+
});
|
|
225
|
+
record.addedNodes.forEach((n) => {
|
|
226
|
+
if (n instanceof Element) touched.add(n);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
for (const el of touched) {
|
|
230
|
+
const subs = byComponent.get(el);
|
|
231
|
+
if (!subs) continue;
|
|
232
|
+
for (const sub of [...subs]) {
|
|
233
|
+
if (!AncestorAttributeObserver.subscriptions.has(sub)) continue;
|
|
234
|
+
AncestorAttributeObserver.bindSubscription(sub);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
observer.observe(parent, { childList: true });
|
|
239
|
+
slot = { observer, byComponent };
|
|
240
|
+
AncestorAttributeObserver.parentSlots.set(parent, slot);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
let set = slot.byComponent.get(subscription.component);
|
|
244
|
+
if (!set) {
|
|
245
|
+
set = new Set();
|
|
246
|
+
slot.byComponent.set(subscription.component, set);
|
|
247
|
+
}
|
|
248
|
+
set.add(subscription);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private static removeParentSlot(
|
|
252
|
+
parent: Element,
|
|
253
|
+
subscription: Subscription,
|
|
254
|
+
): void {
|
|
255
|
+
const slot = AncestorAttributeObserver.parentSlots.get(parent);
|
|
256
|
+
if (!slot) return;
|
|
257
|
+
|
|
258
|
+
const set = slot.byComponent.get(subscription.component);
|
|
259
|
+
if (set) {
|
|
260
|
+
set.delete(subscription);
|
|
261
|
+
if (set.size === 0) slot.byComponent.delete(subscription.component);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (slot.byComponent.size > 0) return;
|
|
265
|
+
slot.observer.disconnect();
|
|
266
|
+
AncestorAttributeObserver.parentSlots.delete(parent);
|
|
267
|
+
}
|
|
268
|
+
|
|
153
269
|
private static unsubscribe(subscription: Subscription): void {
|
|
154
270
|
if (!AncestorAttributeObserver.subscriptions.has(subscription)) return;
|
|
155
271
|
|
|
156
|
-
|
|
157
|
-
subscription.disconnectObservers = null;
|
|
158
|
-
|
|
272
|
+
AncestorAttributeObserver.unbindWatchers(subscription);
|
|
159
273
|
AncestorAttributeObserver.subscriptions.delete(subscription);
|
|
160
274
|
AncestorAttributeObserver.pendingRefresh.delete(subscription);
|
|
161
275
|
|
|
@@ -187,7 +301,6 @@ export default class AncestorAttributeObserver {
|
|
|
187
301
|
|
|
188
302
|
for (const subscription of subscriptions) {
|
|
189
303
|
if (!AncestorAttributeObserver.subscriptions.has(subscription)) continue;
|
|
190
|
-
if (!subscription.component.isConnected) continue;
|
|
191
304
|
syncAncestorAttributeValue(
|
|
192
305
|
subscription.component,
|
|
193
306
|
subscription.attributeName,
|
|
File without changes
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import { Route } from "./route";
|
|
2
2
|
|
|
3
|
+
export type AutoActiveMode =
|
|
4
|
+
| "strict"
|
|
5
|
+
| "partial"
|
|
6
|
+
| "disabled"
|
|
7
|
+
| "strict-path-only";
|
|
8
|
+
|
|
3
9
|
declare type Listener = {
|
|
4
10
|
location: string;
|
|
5
11
|
};
|
|
6
|
-
|
|
12
|
+
|
|
13
|
+
export type ActivableLink = HTMLElement & {
|
|
7
14
|
location?: string;
|
|
8
15
|
href?: Route | string;
|
|
9
16
|
goBack?: Route | string | null;
|
|
10
|
-
autoActive?:
|
|
17
|
+
autoActive?: AutoActiveMode;
|
|
11
18
|
setAttribute(name: string, value: string): void;
|
|
12
19
|
removeAttribute(name: string): void;
|
|
13
20
|
};
|
|
@@ -22,7 +29,7 @@ export default class LocationHandler {
|
|
|
22
29
|
static listening = false;
|
|
23
30
|
static prevURL: string = document.location?.href.replace(
|
|
24
31
|
document.location.origin,
|
|
25
|
-
""
|
|
32
|
+
"",
|
|
26
33
|
);
|
|
27
34
|
static listen() {
|
|
28
35
|
if (!LocationHandler.listening) {
|
|
@@ -30,7 +37,7 @@ export default class LocationHandler {
|
|
|
30
37
|
}
|
|
31
38
|
const newURL = document.location?.href.replace(
|
|
32
39
|
document.location.origin,
|
|
33
|
-
""
|
|
40
|
+
"",
|
|
34
41
|
);
|
|
35
42
|
if (LocationHandler.prevURL && LocationHandler.prevURL != newURL) {
|
|
36
43
|
LocationHandler.prevURL = newURL;
|
|
@@ -116,7 +123,7 @@ export default class LocationHandler {
|
|
|
116
123
|
prevSp = sp;
|
|
117
124
|
}
|
|
118
125
|
|
|
119
|
-
to = "/" + newPathName.join("/") + url.search + (url.hash ?
|
|
126
|
+
to = "/" + newPathName.join("/") + url.search + (url.hash ? url.hash : "");
|
|
120
127
|
if (component.hasAttribute("pushState")) {
|
|
121
128
|
history.pushState(null, "", to);
|
|
122
129
|
} else if (component.hasAttribute("replaceState")) {
|
|
File without changes
|