@qualified-salesforce/web 0.0.1-oidc-bootstrap
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/41842993ec71d6628e4949e9a22b146b.svg +3 -0
- package/7271f3433ed82fc7f56adcd9e30275f4.svg +17 -0
- package/LICENSE.txt +82 -0
- package/components/helpers/entriesStringValidations.js +69 -0
- package/components/helpers/languages.js +32 -0
- package/components/shared/assertUnreachable.js +5 -0
- package/components/shared/controls/imageCropperHelpers.js +43 -0
- package/components/shared/meetingLoadingProgressSpec.js +116 -0
- package/constants.generated.js +9883 -0
- package/css/widget/multimodal_v2/host.split-css.css +162 -0
- package/css/widget/multimodal_v2/index.split-css.panda.css +5240 -0
- package/css/widget/widget.split-css.css +100 -0
- package/fonts/inter/Inter-Black.woff +0 -0
- package/fonts/inter/Inter-Black.woff2 +0 -0
- package/fonts/inter/Inter-BlackItalic.woff +0 -0
- package/fonts/inter/Inter-BlackItalic.woff2 +0 -0
- package/fonts/inter/Inter-Bold.woff +0 -0
- package/fonts/inter/Inter-Bold.woff2 +0 -0
- package/fonts/inter/Inter-BoldItalic.woff +0 -0
- package/fonts/inter/Inter-BoldItalic.woff2 +0 -0
- package/fonts/inter/Inter-ExtraBold.woff +0 -0
- package/fonts/inter/Inter-ExtraBold.woff2 +0 -0
- package/fonts/inter/Inter-ExtraBoldItalic.woff +0 -0
- package/fonts/inter/Inter-ExtraBoldItalic.woff2 +0 -0
- package/fonts/inter/Inter-ExtraLight.woff +0 -0
- package/fonts/inter/Inter-ExtraLight.woff2 +0 -0
- package/fonts/inter/Inter-ExtraLightItalic.woff +0 -0
- package/fonts/inter/Inter-ExtraLightItalic.woff2 +0 -0
- package/fonts/inter/Inter-Italic.woff +0 -0
- package/fonts/inter/Inter-Italic.woff2 +0 -0
- package/fonts/inter/Inter-Light.woff +0 -0
- package/fonts/inter/Inter-Light.woff2 +0 -0
- package/fonts/inter/Inter-LightItalic.woff +0 -0
- package/fonts/inter/Inter-LightItalic.woff2 +0 -0
- package/fonts/inter/Inter-Medium.woff +0 -0
- package/fonts/inter/Inter-Medium.woff2 +0 -0
- package/fonts/inter/Inter-MediumItalic.woff +0 -0
- package/fonts/inter/Inter-MediumItalic.woff2 +0 -0
- package/fonts/inter/Inter-Regular.woff +0 -0
- package/fonts/inter/Inter-Regular.woff2 +0 -0
- package/fonts/inter/Inter-SemiBold.woff +0 -0
- package/fonts/inter/Inter-SemiBold.woff2 +0 -0
- package/fonts/inter/Inter-SemiBoldItalic.woff +0 -0
- package/fonts/inter/Inter-SemiBoldItalic.woff2 +0 -0
- package/fonts/inter/Inter-Thin.woff +0 -0
- package/fonts/inter/Inter-Thin.woff2 +0 -0
- package/fonts/inter/Inter-ThinItalic.woff +0 -0
- package/fonts/inter/Inter-ThinItalic.woff2 +0 -0
- package/fonts/inter/Inter-italic.var.woff2 +0 -0
- package/fonts/inter/Inter-roman.var.woff2 +0 -0
- package/images/close.js +63 -0
- package/images/logo.js +22 -0
- package/js/4101.js +19721 -0
- package/js/daily-esm.js +9948 -0
- package/js/date-fns.js +427 -0
- package/js/multimodal_v2.js +1653 -0
- package/js/runtime.js +109 -0
- package/media/Inter-Black.796be8d8bf.woff2 +0 -0
- package/media/Inter-Black.b254104c56.woff +0 -0
- package/media/Inter-BlackItalic.70306b0eae.woff +0 -0
- package/media/Inter-BlackItalic.752f1e0aaa.woff2 +0 -0
- package/media/Inter-Bold.579e0f95ca.woff2 +0 -0
- package/media/Inter-Bold.b1234477a5.woff +0 -0
- package/media/Inter-BoldItalic.3d0d804323.woff +0 -0
- package/media/Inter-BoldItalic.828a494e04.woff2 +0 -0
- package/media/Inter-ExtraBold.208a9e6c99.woff +0 -0
- package/media/Inter-ExtraBold.d65f028165.woff2 +0 -0
- package/media/Inter-ExtraBoldItalic.30429962ec.woff +0 -0
- package/media/Inter-ExtraBoldItalic.8c7eac5ce3.woff2 +0 -0
- package/media/Inter-ExtraLight.15c082a57d.woff +0 -0
- package/media/Inter-ExtraLight.6824177d1e.woff2 +0 -0
- package/media/Inter-ExtraLightItalic.05138dddf3.woff2 +0 -0
- package/media/Inter-ExtraLightItalic.3beee54f59.woff +0 -0
- package/media/Inter-Italic.9beab78452.woff +0 -0
- package/media/Inter-Italic.d593a8df79.woff2 +0 -0
- package/media/Inter-Light.27083fa637.woff2 +0 -0
- package/media/Inter-Light.91dfddd842.woff +0 -0
- package/media/Inter-LightItalic.0a783b89b3.woff2 +0 -0
- package/media/Inter-LightItalic.f8ccf2813f.woff +0 -0
- package/media/Inter-Medium.dc792b508e.woff2 +0 -0
- package/media/Inter-Medium.ec7dd2d9d8.woff +0 -0
- package/media/Inter-MediumItalic.17301e5b40.woff +0 -0
- package/media/Inter-MediumItalic.84d3493a9f.woff2 +0 -0
- package/media/Inter-Regular.f1f0c35b32.woff2 +0 -0
- package/media/Inter-Regular.f356e84aa0.woff +0 -0
- package/media/Inter-SemiBold.55027e4724.woff +0 -0
- package/media/Inter-SemiBold.fcb100c760.woff2 +0 -0
- package/media/Inter-SemiBoldItalic.ab9105ed3b.woff +0 -0
- package/media/Inter-SemiBoldItalic.d90f295d0c.woff2 +0 -0
- package/media/Inter-Thin.16325d9b0f.woff +0 -0
- package/media/Inter-Thin.dafaa44d99.woff2 +0 -0
- package/media/Inter-ThinItalic.4fc662b3cf.woff2 +0 -0
- package/media/Inter-ThinItalic.d3d8994788.woff +0 -0
- package/media/Inter-italic.var.958a0b9742.woff2 +0 -0
- package/media/Inter-roman.var.b2129c009c.woff2 +0 -0
- package/package.json +20 -0
- package/packs/widget/api/docking/docking_host.js +97 -0
- package/packs/widget/api/docking/index.js +294 -0
- package/packs/widget/api/docking/shared.js +164 -0
- package/packs/widget/api/docking/viewport_lock.js +488 -0
- package/packs/widget/api/docking/viewport_resize.js +1203 -0
- package/packs/widget/esm/fonts/Inter-Black.796be8d8bf.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Black.b254104c56.woff +0 -0
- package/packs/widget/esm/fonts/Inter-BlackItalic.70306b0eae.woff +0 -0
- package/packs/widget/esm/fonts/Inter-BlackItalic.752f1e0aaa.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Bold.579e0f95ca.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Bold.b1234477a5.woff +0 -0
- package/packs/widget/esm/fonts/Inter-BoldItalic.3d0d804323.woff +0 -0
- package/packs/widget/esm/fonts/Inter-BoldItalic.828a494e04.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraBold.208a9e6c99.woff +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraBold.d65f028165.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraBoldItalic.30429962ec.woff +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraBoldItalic.8c7eac5ce3.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraLight.15c082a57d.woff +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraLight.6824177d1e.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraLightItalic.05138dddf3.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ExtraLightItalic.3beee54f59.woff +0 -0
- package/packs/widget/esm/fonts/Inter-Italic.9beab78452.woff +0 -0
- package/packs/widget/esm/fonts/Inter-Italic.d593a8df79.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Light.27083fa637.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Light.91dfddd842.woff +0 -0
- package/packs/widget/esm/fonts/Inter-LightItalic.0a783b89b3.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-LightItalic.f8ccf2813f.woff +0 -0
- package/packs/widget/esm/fonts/Inter-Medium.dc792b508e.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Medium.ec7dd2d9d8.woff +0 -0
- package/packs/widget/esm/fonts/Inter-MediumItalic.17301e5b40.woff +0 -0
- package/packs/widget/esm/fonts/Inter-MediumItalic.84d3493a9f.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Regular.f1f0c35b32.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Regular.f356e84aa0.woff +0 -0
- package/packs/widget/esm/fonts/Inter-SemiBold.55027e4724.woff +0 -0
- package/packs/widget/esm/fonts/Inter-SemiBold.fcb100c760.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-SemiBoldItalic.ab9105ed3b.woff +0 -0
- package/packs/widget/esm/fonts/Inter-SemiBoldItalic.d90f295d0c.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-Thin.16325d9b0f.woff +0 -0
- package/packs/widget/esm/fonts/Inter-Thin.dafaa44d99.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ThinItalic.4fc662b3cf.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-ThinItalic.d3d8994788.woff +0 -0
- package/packs/widget/esm/fonts/Inter-italic.var.958a0b9742.woff2 +0 -0
- package/packs/widget/esm/fonts/Inter-roman.var.b2129c009c.woff2 +0 -0
- package/packs/widget/esm/index.js +183 -0
- package/packs/widget/esm/qualified.css +5502 -0
- package/routes/app/offers/scripts/OfferMainScript.js +154 -0
- package/routes/app/offers/scripts/constants.js +71 -0
- package/routes/app/offers/scripts/main/ButtonManager.js +65 -0
- package/routes/app/offers/scripts/main/FormManager.js +325 -0
- package/routes/app/offers/scripts/main/MainContext.js +19 -0
- package/routes/app/offers/scripts/main/OfferManager.js +91 -0
- package/routes/app/offers/scripts/main/TriggerManager.js +125 -0
- package/routes/app/offers/scripts/rendering/ContentManager.js +53 -0
- package/routes/app/offers/scripts/rendering/LocationManager.js +83 -0
- package/routes/app/offers/scripts/rendering/RenderedOffer.js +188 -0
- package/routes/app/offers/scripts/rendering/Renderer.js +69 -0
- package/routes/app/offers/scripts/rendering/RenderingInitializer.js +62 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManager.js +31 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManagerFooter.js +81 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManagerHeader.js +81 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManagerModal.js +117 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationManagerSidebar.js +75 -0
- package/routes/app/offers/scripts/rendering/animations/AnimationResult.js +43 -0
- package/routes/app/offers/scripts/rendering/animations/Animator.js +78 -0
- package/routes/app/offers/scripts/rendering/animations/BaseAnimationManager.js +25 -0
- package/routes/app/offers/scripts/rendering/lib/BaseComponent.js +106 -0
- package/routes/app/offers/scripts/rendering/lib/FormComponent.js +134 -0
- package/routes/app/offers/scripts/rendering/lib/OfferComponent.js +144 -0
- package/routes/app/offers/scripts/rendering/lib/ScrollbarWidth.js +27 -0
- package/routes/app/offers/scripts/rendering/lib/decorators.js +20 -0
- package/routes/app/offers/scripts/rendering/locations/CSSVarsManager.js +66 -0
- package/routes/app/offers/scripts/rendering/locations/ElementResizeObserver.js +49 -0
- package/routes/app/offers/scripts/rendering/locations/footer.js +53 -0
- package/routes/app/offers/scripts/rendering/locations/header/AsyncBatchProcessor.js +70 -0
- package/routes/app/offers/scripts/rendering/locations/header/CSSTransitionObserver.js +182 -0
- package/routes/app/offers/scripts/rendering/locations/header/ElementStyleChangeObserver.js +138 -0
- package/routes/app/offers/scripts/rendering/locations/header/ExternalStyleManager.js +110 -0
- package/routes/app/offers/scripts/rendering/locations/header/Header.js +353 -0
- package/routes/app/offers/scripts/rendering/locations/header/InlineStyleManager.js +105 -0
- package/routes/app/offers/scripts/rendering/locations/header/MatchingElementsObserver.js +107 -0
- package/routes/app/offers/scripts/rendering/locations/header/NewElementsObserver.js +129 -0
- package/routes/app/offers/scripts/rendering/locations/header/RuleWrapper.js +46 -0
- package/routes/app/offers/scripts/rendering/locations/header/SelectorObservable.js +23 -0
- package/routes/app/offers/scripts/rendering/locations/header/SelectorObserver.js +61 -0
- package/routes/app/offers/scripts/rendering/locations/header/ShiftedElementsManager.js +45 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleElementManager.js +37 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleElementWrapper.js +62 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/ObservedSelectorValue.js +45 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/ObservedSelectors.js +62 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/StyleSelectorObserver.js +294 -0
- package/routes/app/offers/scripts/rendering/locations/header/StyleSelectorObserver/constants.js +21 -0
- package/routes/app/offers/scripts/rendering/locations/header/WindowResizeObserver.js +43 -0
- package/routes/app/offers/scripts/rendering/locations/header/utils.js +25 -0
- package/routes/app/offers/scripts/rendering/locations/popup.js +66 -0
- package/routes/app/offers/scripts/rendering/locations/sidebar.js +21 -0
- package/routes/app/offers/scripts/rendering/variations/ButtonBanner.js +105 -0
- package/routes/app/offers/scripts/rendering/variations/ButtonModal.js +114 -0
- package/routes/app/offers/scripts/rendering/variations/FormBanner.js +214 -0
- package/routes/app/offers/scripts/rendering/variations/FormModal.js +325 -0
- package/routes/app/offers/scripts/rendering/variations/LinkBanner.js +105 -0
- package/routes/app/offers/scripts/rendering/variations/components/Body.js +29 -0
- package/routes/app/offers/scripts/rendering/variations/components/Button.js +128 -0
- package/routes/app/offers/scripts/rendering/variations/components/DismissButton.js +39 -0
- package/routes/app/offers/scripts/rendering/variations/components/ForegroundImageBanner.js +110 -0
- package/routes/app/offers/scripts/rendering/variations/components/ForegroundImageModal.js +128 -0
- package/routes/app/offers/scripts/rendering/variations/components/Headline.js +94 -0
- package/routes/app/offers/scripts/rendering/variations/components/MultiFieldForm.js +302 -0
- package/routes/app/offers/scripts/rendering/variations/components/Tooltip.js +74 -0
- package/routes/app/offers/scripts/rendering/variations/icons.js +15 -0
- package/routes/app/offers/scripts/utils.js +115 -0
- package/routes/app/offers/utils/HTMLUtils.js +10 -0
- package/routes/app/offers/utils/createTypeGuard.js +32 -0
- package/routes/app/offers/utils/promise-utils.js +22 -0
- package/routes/app/websiteBuilder/stores/storeHelpers.js +18 -0
- package/sounds/message-initial.mp3 +0 -0
- package/sounds/message-received.mp3 +0 -0
- package/sounds/message-sent.mp3 +0 -0
- package/src/arrays.js +15 -0
- package/src/audio.js +106 -0
- package/src/bounded-set.js +16 -0
- package/src/bounding_box_observer.js +129 -0
- package/src/decorators.js +29 -0
- package/src/dom.js +128 -0
- package/src/dom_roots.js +26 -0
- package/src/embedded_forms/EmbeddedForm.js +638 -0
- package/src/embedded_forms/QualifiedEmbeddedForm.js +51 -0
- package/src/embedded_forms/QualifiedFormField.js +137 -0
- package/src/embedded_forms/utils.js +17 -0
- package/src/graphql-types.js +1686 -0
- package/src/iframes.js +86 -0
- package/src/localstorage.js +43 -0
- package/src/mirror/Shipper.js +133 -0
- package/src/mirror/constants.generated.js +13 -0
- package/src/mirror/constants.js +238 -0
- package/src/mirror/shipper/ChangeQueue.js +155 -0
- package/src/mirror/shipper/DOMSerializer.js +392 -0
- package/src/mirror/shipper/observers.js +441 -0
- package/src/mirror/shipper/utils.js +98 -0
- package/src/mixins/disposable.js +125 -0
- package/src/mixins/injectable.js +37 -0
- package/src/personalizations/personalization-manager.js +110 -0
- package/src/personalizations/strategies/node-freezing-strategy.js +174 -0
- package/src/personalizations/utils.js +187 -0
- package/src/promises.js +107 -0
- package/src/proxy.js +144 -0
- package/src/qualified_root.js +35 -0
- package/src/query_params.js +55 -0
- package/src/shadow-dom-helper.js +63 -0
- package/src/singleton_host.js +39 -0
- package/src/smart_website/trigger.js +49 -0
- package/src/smart_website/utils.js +149 -0
- package/src/string.js +53 -0
- package/src/timezone.js +57 -0
- package/src/timing.js +49 -0
- package/src/type-utils.js +76 -0
- package/src/url-utils.js +102 -0
- package/src/url.js +50 -0
- package/src/utils.js +72 -0
- package/src/validation.js.js +29 -0
- package/src/validation_ts.js +6 -0
- package/vendor/actioncable/adapters.js +6 -0
- package/vendor/actioncable/connection.js +204 -0
- package/vendor/actioncable/connection_monitor.js +129 -0
- package/vendor/actioncable/consumer.js +91 -0
- package/vendor/actioncable/index.js +34 -0
- package/vendor/actioncable/internal.js +22 -0
- package/vendor/actioncable/logger.js +28 -0
- package/vendor/actioncable/subscription.js +93 -0
- package/vendor/actioncable/subscriptions.js +89 -0
- package/vendor/open-telemetry-idgenerator.js +43 -0
- package/widget/analytics/facebook_tracker.js +8 -0
- package/widget/analytics/google_analytics_tracker.js +83 -0
- package/widget/analytics/google_tag_manager_tracker.js +22 -0
- package/widget/analytics.js +58 -0
- package/widget/api_handler/api_handler.js +730 -0
- package/widget/api_handler/base_api_handler.js +249 -0
- package/widget/booker_intent_tracker.js +391 -0
- package/widget/booker_outcome_tracker.js +329 -0
- package/widget/capture_widget_exceptions.js +150 -0
- package/widget/channel.js +282 -0
- package/widget/composite_experience_adapter.js +101 -0
- package/widget/constants.generated.js +350 -0
- package/widget/constants.js +21 -0
- package/widget/container.js +193 -0
- package/widget/content_activity_emitter.js +36 -0
- package/widget/data360_visitor.js +67 -0
- package/widget/date_provider.js +11 -0
- package/widget/debug_mode_state.js +175 -0
- package/widget/dummy_module.js +9 -0
- package/widget/eloqua_visitor.js +17 -0
- package/widget/form_cta_booker_intent.js +246 -0
- package/widget/hubspot_visitor.js +39 -0
- package/widget/inline_meeting_booker_page.js +90 -0
- package/widget/local_state/abstract_local_state.js +38 -0
- package/widget/local_state/debug_state/abstract_debug_flow.js +29 -0
- package/widget/local_state/debug_state/custom_form_flow.js +14 -0
- package/widget/local_state/debug_state/hubspot_form_flow.js +19 -0
- package/widget/local_state/debug_state/hubspot_v4_form_flow.js +19 -0
- package/widget/local_state/debug_state/marketo_form_flow.js +20 -0
- package/widget/local_state/debug_state/pardot_form_flow.js +18 -0
- package/widget/local_state/debug_state.js +362 -0
- package/widget/local_state/trace_state.js +20 -0
- package/widget/location_provider.js +9 -0
- package/widget/marketo_visitor.js +39 -0
- package/widget/meetings/tracing/buttons_forms_triggering_tracer.js +124 -0
- package/widget/meetings/tracing/spans/button_spans.js +18 -0
- package/widget/meetings/tracing/spans/form_spans.js +11 -0
- package/widget/multimodal_v2/assets_preloader.js +97 -0
- package/widget/multimodal_v2/components/AppLayout.js +93 -0
- package/widget/multimodal_v2/components/CursorOverlay.js +93 -0
- package/widget/multimodal_v2/components/PointerRectOverlay.js +74 -0
- package/widget/multimodal_v2/components/app/Artifact.js +109 -0
- package/widget/multimodal_v2/components/app/Background.js +27 -0
- package/widget/multimodal_v2/components/app/CalendarLoadingContent.js +255 -0
- package/widget/multimodal_v2/components/app/Chat.js +39 -0
- package/widget/multimodal_v2/components/app/CookieConsentModal.js +149 -0
- package/widget/multimodal_v2/components/app/Foreground.js +48 -0
- package/widget/multimodal_v2/components/app/HiddenInput.js +41 -0
- package/widget/multimodal_v2/components/app/Input.js +72 -0
- package/widget/multimodal_v2/components/app/LightboxExperience.js +769 -0
- package/widget/multimodal_v2/components/app/LoadingOverlay.js +97 -0
- package/widget/multimodal_v2/components/app/Main.js +985 -0
- package/widget/multimodal_v2/components/app/MessengerButton.js +160 -0
- package/widget/multimodal_v2/components/app/Multimodal.js +17 -0
- package/widget/multimodal_v2/components/app/OverlayControls.js +79 -0
- package/widget/multimodal_v2/components/app/Preview.js +32 -0
- package/widget/multimodal_v2/components/app/PrivacyDisclosure.js +57 -0
- package/widget/multimodal_v2/components/app/RotateDeviceOverlay.js +70 -0
- package/widget/multimodal_v2/components/app/Toolbar.js +156 -0
- package/widget/multimodal_v2/components/chat/ChatComposer.js +129 -0
- package/widget/multimodal_v2/components/chat/ChatInputForm.js +398 -0
- package/widget/multimodal_v2/components/chat/ColdStartQuestions.js +354 -0
- package/widget/multimodal_v2/components/chat/ComposerErrorBanner.js +62 -0
- package/widget/multimodal_v2/components/chat/PostCallSurvey.js +359 -0
- package/widget/multimodal_v2/components/chat/preview/FieldRequestRenderer.js +41 -0
- package/widget/multimodal_v2/components/chat/preview/PreviewMessageRenderer.js +60 -0
- package/widget/multimodal_v2/components/chat/preview/SharedOfferRenderer.js +143 -0
- package/widget/multimodal_v2/components/chat/preview/TextRenderer.js +27 -0
- package/widget/multimodal_v2/components/chat/preview/TimelinePreview.js +254 -0
- package/widget/multimodal_v2/components/chat/timeline/CalendarEventOfferRenderer.js +103 -0
- package/widget/multimodal_v2/components/chat/timeline/CalendarEventPickRenderer.js +148 -0
- package/widget/multimodal_v2/components/chat/timeline/FieldEntryRenderer.js +84 -0
- package/widget/multimodal_v2/components/chat/timeline/FieldRequestRenderer.js +56 -0
- package/widget/multimodal_v2/components/chat/timeline/InlinePrivacyDisclosure.js +66 -0
- package/widget/multimodal_v2/components/chat/timeline/LinkPreviewCard.js +70 -0
- package/widget/multimodal_v2/components/chat/timeline/MessageEntry.js +88 -0
- package/widget/multimodal_v2/components/chat/timeline/PresentContentRenderer.js +30 -0
- package/widget/multimodal_v2/components/chat/timeline/PresentDeckRenderer.js +279 -0
- package/widget/multimodal_v2/components/chat/timeline/PresentVideoRenderer.js +131 -0
- package/widget/multimodal_v2/components/chat/timeline/ShareContentRenderer.js +59 -0
- package/widget/multimodal_v2/components/chat/timeline/SharedOfferRenderer.js +131 -0
- package/widget/multimodal_v2/components/chat/timeline/SystemRenderer.js +82 -0
- package/widget/multimodal_v2/components/chat/timeline/TextRenderer.js +66 -0
- package/widget/multimodal_v2/components/chat/timeline/Timeline.js +158 -0
- package/widget/multimodal_v2/components/debug/DebugMultimodalPanel.js +327 -0
- package/widget/multimodal_v2/components/decks/index.js +160 -0
- package/widget/multimodal_v2/components/field_request/BooleanField.js +77 -0
- package/widget/multimodal_v2/components/field_request/FieldComponents.js +69 -0
- package/widget/multimodal_v2/components/field_request/Form.js +87 -0
- package/widget/multimodal_v2/components/field_request/MultiPicklistField.js +240 -0
- package/widget/multimodal_v2/components/field_request/PicklistField.js +166 -0
- package/widget/multimodal_v2/components/field_request/SingleLineInputField.js +69 -0
- package/widget/multimodal_v2/components/field_request/TextField.js +37 -0
- package/widget/multimodal_v2/components/field_request/index.js +170 -0
- package/widget/multimodal_v2/components/helpers/AutoScroll.js +37 -0
- package/widget/multimodal_v2/components/helpers/ErrorBoundary.js +53 -0
- package/widget/multimodal_v2/components/helpers/FocusTrapDialog.js +26 -0
- package/widget/multimodal_v2/components/helpers/ImpressionTracker.js +94 -0
- package/widget/multimodal_v2/components/helpers/ListRenderer.js +37 -0
- package/widget/multimodal_v2/components/helpers/Localization.js +76 -0
- package/widget/multimodal_v2/components/helpers/Persisted.js +166 -0
- package/widget/multimodal_v2/components/helpers/RichText.js +358 -0
- package/widget/multimodal_v2/components/helpers/ScreenReaderHeading.js +17 -0
- package/widget/multimodal_v2/components/helpers/Thumbnail.js +190 -0
- package/widget/multimodal_v2/components/helpers/VisuallyHidden.js +41 -0
- package/widget/multimodal_v2/components/helpers/content_click_payloads.js +58 -0
- package/widget/multimodal_v2/components/helpers/useDraggable.js +103 -0
- package/widget/multimodal_v2/components/helpers/useTextOverflow.js +44 -0
- package/widget/multimodal_v2/components/lightbox_gather/index.js +741 -0
- package/widget/multimodal_v2/components/meetings/ArtifactEntryPoint.js +252 -0
- package/widget/multimodal_v2/components/meetings/MeetingAdditionalAttendees.js +325 -0
- package/widget/multimodal_v2/components/meetings/MeetingBookerEntry.js +100 -0
- package/widget/multimodal_v2/components/meetings/MeetingDetailsCard.js +99 -0
- package/widget/multimodal_v2/components/meetings/MeetingErrorBanner.js +62 -0
- package/widget/multimodal_v2/components/meetings/MeetingOfferEmailStep.js +239 -0
- package/widget/multimodal_v2/components/meetings/MeetingOfferFooter.js +104 -0
- package/widget/multimodal_v2/components/meetings/MeetingOfferSelectionStep.js +60 -0
- package/widget/multimodal_v2/components/meetings/MeetingRepHeader.js +222 -0
- package/widget/multimodal_v2/components/meetings/MeetingStepShell.js +92 -0
- package/widget/multimodal_v2/components/meetings/MeetingSummaryRail.js +515 -0
- package/widget/multimodal_v2/components/meetings/MeetingTimeSelector.js +603 -0
- package/widget/multimodal_v2/components/meetings/MonthDatePicker.js +422 -0
- package/widget/multimodal_v2/components/meetings/NavigationButtons.js +76 -0
- package/widget/multimodal_v2/components/meetings/TimeSlotHeader.js +357 -0
- package/widget/multimodal_v2/components/meetings/WeekViewHeader.js +20 -0
- package/widget/multimodal_v2/components/meetings/constants.js +7 -0
- package/widget/multimodal_v2/components/meetings/index.js +47 -0
- package/widget/multimodal_v2/components/meetings/utils.js +328 -0
- package/widget/multimodal_v2/components/multimodal/Audio.js +28 -0
- package/widget/multimodal_v2/components/multimodal/Controls.js +188 -0
- package/widget/multimodal_v2/components/multimodal/LiveVideo.js +63 -0
- package/widget/multimodal_v2/components/multimodal/MultiModalComponent.js +424 -0
- package/widget/multimodal_v2/components/multimodal/MultimodalAvatar.js +36 -0
- package/widget/multimodal_v2/components/multimodal/OrbAvatar.js +326 -0
- package/widget/multimodal_v2/components/multimodal/Status.js +220 -0
- package/widget/multimodal_v2/components/multimodal/VideoAvatar.js +24 -0
- package/widget/multimodal_v2/components/multimodal/VideoPreview.js +114 -0
- package/widget/multimodal_v2/components/multimodal/useAudioLevelMonitoring.js +96 -0
- package/widget/multimodal_v2/components/multimodal/useMultimodal.js +434 -0
- package/widget/multimodal_v2/components/presentations/index.js +372 -0
- package/widget/multimodal_v2/components/shared/Avatar.js +92 -0
- package/widget/multimodal_v2/components/shared/AvatarGroup.js +135 -0
- package/widget/multimodal_v2/components/shared/Button.js +245 -0
- package/widget/multimodal_v2/components/shared/ButtonGroup.js +133 -0
- package/widget/multimodal_v2/components/shared/ComposerForm.js +98 -0
- package/widget/multimodal_v2/components/shared/SpeakingIndicator.js +239 -0
- package/widget/multimodal_v2/components/shared/ThinkingAnimation.js +165 -0
- package/widget/multimodal_v2/components/shared/Tooltip.js +266 -0
- package/widget/multimodal_v2/components/shared/controls/Dropdown.js +79 -0
- package/widget/multimodal_v2/components/shared/controls/PillToggle.js +142 -0
- package/widget/multimodal_v2/components/shared/controls/TextArea.js +114 -0
- package/widget/multimodal_v2/components/shared/toolCallLabels.js +12 -0
- package/widget/multimodal_v2/components/slides/SlidesThumbnail.js +47 -0
- package/widget/multimodal_v2/components/slides/index.js +61 -0
- package/widget/multimodal_v2/constants.js +88 -0
- package/widget/multimodal_v2/host.split-css.js +2 -0
- package/widget/multimodal_v2/host.string.js +96 -0
- package/widget/multimodal_v2/images/icons.js +582 -0
- package/widget/multimodal_v2/images/posters/piper_low_res.jpg +0 -0
- package/widget/multimodal_v2/index.js +23 -0
- package/widget/multimodal_v2/index.panda.js +28 -0
- package/widget/multimodal_v2/index.split-css.panda.js +2 -0
- package/widget/multimodal_v2/inline_meeting_booker.js +182 -0
- package/widget/multimodal_v2/locales/cs.js +196 -0
- package/widget/multimodal_v2/locales/da.js +196 -0
- package/widget/multimodal_v2/locales/de.js +196 -0
- package/widget/multimodal_v2/locales/en.js +196 -0
- package/widget/multimodal_v2/locales/en_AU.js +197 -0
- package/widget/multimodal_v2/locales/en_GB.js +197 -0
- package/widget/multimodal_v2/locales/es.js +197 -0
- package/widget/multimodal_v2/locales/es_LA.js +196 -0
- package/widget/multimodal_v2/locales/fi.js +196 -0
- package/widget/multimodal_v2/locales/fr.js +197 -0
- package/widget/multimodal_v2/locales/fr_CA.js +196 -0
- package/widget/multimodal_v2/locales/id.js +196 -0
- package/widget/multimodal_v2/locales/index.js +48 -0
- package/widget/multimodal_v2/locales/it.js +196 -0
- package/widget/multimodal_v2/locales/ja.js +196 -0
- package/widget/multimodal_v2/locales/ko.js +196 -0
- package/widget/multimodal_v2/locales/nb.js +196 -0
- package/widget/multimodal_v2/locales/nl.js +196 -0
- package/widget/multimodal_v2/locales/pl.js +196 -0
- package/widget/multimodal_v2/locales/pt_BR.js +196 -0
- package/widget/multimodal_v2/locales/ru.js +196 -0
- package/widget/multimodal_v2/locales/sv.js +196 -0
- package/widget/multimodal_v2/locales/th.js +196 -0
- package/widget/multimodal_v2/locales/tr.js +196 -0
- package/widget/multimodal_v2/locales/vi.js +196 -0
- package/widget/multimodal_v2/locales/zh_CN.js +196 -0
- package/widget/multimodal_v2/locales/zh_TW.js +196 -0
- package/widget/multimodal_v2/multimodal.js +633 -0
- package/widget/multimodal_v2/multimodal_channel.js +195 -0
- package/widget/multimodal_v2/signals/active_conversation_signal.js +33 -0
- package/widget/multimodal_v2/signals/allowed_conversation_mode_signal.js +38 -0
- package/widget/multimodal_v2/signals/artifact_signal.js +22 -0
- package/widget/multimodal_v2/signals/layout_signal.js +98 -0
- package/widget/multimodal_v2/signals/messages_signal.js +207 -0
- package/widget/multimodal_v2/signals/ui_state_signal.js +128 -0
- package/widget/multimodal_v2/stable_bundle_src.js +44 -0
- package/widget/multimodal_v2/stores/ai_conversation_store.js +221 -0
- package/widget/multimodal_v2/stores/artifact_store.js +205 -0
- package/widget/multimodal_v2/stores/base_store.js +16 -0
- package/widget/multimodal_v2/stores/call_store.js +770 -0
- package/widget/multimodal_v2/stores/call_ui_adapter.js +225 -0
- package/widget/multimodal_v2/stores/debug_multimodal_scenario_store.js +471 -0
- package/widget/multimodal_v2/stores/decks_store.js +285 -0
- package/widget/multimodal_v2/stores/device_store.js +63 -0
- package/widget/multimodal_v2/stores/docking_store.js +62 -0
- package/widget/multimodal_v2/stores/field_request_store.js +326 -0
- package/widget/multimodal_v2/stores/meeting_store.js +477 -0
- package/widget/multimodal_v2/stores/participant_store.js +73 -0
- package/widget/multimodal_v2/stores/post_call_survey_store.js +160 -0
- package/widget/multimodal_v2/stores/pounce_tracking_store.js +163 -0
- package/widget/multimodal_v2/stores/pounce_tracking_store_v2.js +511 -0
- package/widget/multimodal_v2/stores/presentations_store.js +111 -0
- package/widget/multimodal_v2/stores/root_store.js +1919 -0
- package/widget/multimodal_v2/stores/screen_share_store.js +217 -0
- package/widget/multimodal_v2/stores/slides_store.js +21 -0
- package/widget/multimodal_v2/stores/translation_store.js +185 -0
- package/widget/multimodal_v2/stores/ui_store.js +496 -0
- package/widget/multimodal_v2/stores/waiting_store.js +159 -0
- package/widget/multimodal_v2/stores/website_navigation_store.js +767 -0
- package/widget/multimodal_v2/styled-system/css/conditions.js +34 -0
- package/widget/multimodal_v2/styled-system/css/css.js +48 -0
- package/widget/multimodal_v2/styled-system/css/cva.js +96 -0
- package/widget/multimodal_v2/styled-system/css/cx.js +13 -0
- package/widget/multimodal_v2/styled-system/css/index.js +15 -0
- package/widget/multimodal_v2/styled-system/css/sva.js +69 -0
- package/widget/multimodal_v2/styled-system/helpers.js +384 -0
- package/widget/multimodal_v2/styled-system/jsx/create-style-context.js +96 -0
- package/widget/multimodal_v2/styled-system/jsx/factory-helper.js +19 -0
- package/widget/multimodal_v2/styled-system/jsx/factory.js +111 -0
- package/widget/multimodal_v2/styled-system/jsx/index.js +12 -0
- package/widget/multimodal_v2/styled-system/jsx/is-valid-prop.js +22 -0
- package/widget/multimodal_v2/types.js +105 -0
- package/widget/multimodal_v2/utils/auto_scroller.js +157 -0
- package/widget/multimodal_v2/utils/flip_animation.js +124 -0
- package/widget/multimodal_v2/utils/focus_gate.js +237 -0
- package/widget/multimodal_v2/utils/locale.js +16 -0
- package/widget/multimodal_v2/utils/media_queries.js +30 -0
- package/widget/multimodal_v2/utils/multimodal_cache.js +19 -0
- package/widget/multimodal_v2/utils/mutation_effect.js +14 -0
- package/widget/multimodal_v2/utils/navigation_interceptor.js +205 -0
- package/widget/multimodal_v2/utils/navigation_strategies/dom_swap.js +393 -0
- package/widget/multimodal_v2/utils/navigation_strategies/index.js +12 -0
- package/widget/multimodal_v2/utils/navigation_strategies/lwr.js +61 -0
- package/widget/multimodal_v2/utils/navigation_strategies/navigation_utils.js +46 -0
- package/widget/multimodal_v2/utils/navigation_strategies/next_js.js +24 -0
- package/widget/multimodal_v2/utils/navigation_strategies/wouter_v3.js +15 -0
- package/widget/multimodal_v2/utils/objects_map.js +38 -0
- package/widget/multimodal_v2/utils/perceived_voice_turn_tracker.js +345 -0
- package/widget/multimodal_v2/utils/sanitize_html.js +132 -0
- package/widget/multimodal_v2/utils/signals.js +97 -0
- package/widget/multimodal_v2/utils/slide_zoom.js +114 -0
- package/widget/multimodal_v2/utils/theme_styles.js +137 -0
- package/widget/multimodal_v2/utils/url_observer.js +52 -0
- package/widget/multimodal_v2/utils/voice_onset_detector.js +127 -0
- package/widget/page_mirror.js +89 -0
- package/widget/page_view_activity_emitter.js +71 -0
- package/widget/pardot_visitor.js +137 -0
- package/widget/personalization_observer.js +96 -0
- package/widget/personalizations_config.js +160 -0
- package/widget/qualified_form/constants.js +23 -0
- package/widget/qualified_form/phone_utils.js +38 -0
- package/widget/qualified_form/qualified_form_action.js +91 -0
- package/widget/qualified_form/qualified_form_action_orchestrator.js +21 -0
- package/widget/qualified_form/qualified_form_api.js +471 -0
- package/widget/scroll_disabler.js +109 -0
- package/widget/server-logger.js +156 -0
- package/widget/smart_website_config.js +112 -0
- package/widget/telemetry/context.js +75 -0
- package/widget/telemetry/index.js +16 -0
- package/widget/telemetry/messenger_uptime.js +80 -0
- package/widget/telemetry/metrics.js +120 -0
- package/widget/telemetry/span.js +82 -0
- package/widget/telemetry/telemetry.js +180 -0
- package/widget/telemetry/tracer.js +41 -0
- package/widget/telemetry/tracing_store.js +310 -0
- package/widget/tracker.js +916 -0
- package/widget/utils/native_globals.js +129 -0
- package/widget/v1_adapter.js +50 -0
- package/widget/v2_adapter.js +368 -0
- package/widget/visitor/base_visitor_state.js +11 -0
- package/widget/visitor/cookie_visitor_state.js +128 -0
- package/widget/visitor/in_memory_visitor_state.js +29 -0
- package/widget/visitor/visitor_state.js +384 -0
- package/widget/visitor.js +356 -0
- package/widget/widget/linked_widget_v2.js +227 -0
- package/widget/widget/page_mirror_factory.js +22 -0
- package/widget/widget/sentry.js +130 -0
- package/widget/widget/widget.js +1698 -0
- package/widget/widget.split-css.js +2 -0
- package/widget/widget_bootstrap.js +97 -0
- package/widget/widget_object.js +73 -0
|
@@ -0,0 +1,1203 @@
|
|
|
1
|
+
import { BoundingBoxObserver } from "../../../../src/bounding_box_observer.js";
|
|
2
|
+
import { getProbeIframe, getDockingShadowRoot } from "./docking_host.js";
|
|
3
|
+
import { DOCKED_TOP_OFFSET_CSS_VARIABLE, isQualifiedOwnedShadowRoot, tryGet, measureScrollbarWidth, dispatchResizeEvent, MOBILE_BREAKPOINT, whenBodyAvailable, DOCKING_PROXY_MARKER, DOCKED_TARGET_ATTRIBUTE, applyOnce, DOCKED_DOCUMENT_ATTRIBUTE } from "./shared.js";
|
|
4
|
+
import { _tagged_template_literal_loose } from "../../../../js/4101.js";
|
|
5
|
+
import { queryAllAcrossRoots } from "../../../../src/dom_roots.js";
|
|
6
|
+
import { applyProxy, originalOf } from "../../../../src/proxy.js";
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
function viewport_resize_templateObject() {
|
|
10
|
+
const data = _tagged_template_literal_loose([
|
|
11
|
+
"(?:^|[^a-z-])(?:",
|
|
12
|
+
")s*(?::|<=|>=|<|>)"
|
|
13
|
+
], [
|
|
14
|
+
"(?:^|[^a-z-])(?:",
|
|
15
|
+
")\\s*(?::|<=|>=|<|>)"
|
|
16
|
+
]);
|
|
17
|
+
viewport_resize_templateObject = function _templateObject() {
|
|
18
|
+
return data;
|
|
19
|
+
};
|
|
20
|
+
return data;
|
|
21
|
+
}
|
|
22
|
+
function _templateObject1() {
|
|
23
|
+
const data = _tagged_template_literal_loose([
|
|
24
|
+
"|"
|
|
25
|
+
]);
|
|
26
|
+
_templateObject1 = function _templateObject() {
|
|
27
|
+
return data;
|
|
28
|
+
};
|
|
29
|
+
return data;
|
|
30
|
+
}
|
|
31
|
+
function _templateObject2() {
|
|
32
|
+
const data = _tagged_template_literal_loose([
|
|
33
|
+
"(?:<=|>=|<|>)s*(?:",
|
|
34
|
+
")(?:[^a-z-]|$)"
|
|
35
|
+
], [
|
|
36
|
+
"(?:<=|>=|<|>)\\s*(?:",
|
|
37
|
+
")(?:[^a-z-]|$)"
|
|
38
|
+
]);
|
|
39
|
+
_templateObject2 = function _templateObject() {
|
|
40
|
+
return data;
|
|
41
|
+
};
|
|
42
|
+
return data;
|
|
43
|
+
}
|
|
44
|
+
/* eslint-disable rulesdir/css-units */
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Constants
|
|
51
|
+
// ============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Selector used to locate the host page's header: the semantic `<header>`
|
|
54
|
+
* element or the `banner` landmark role.
|
|
55
|
+
*/ const PINNED_HEADER_SELECTOR = ":is(header, [role='banner']):not(main *)";
|
|
56
|
+
/**
|
|
57
|
+
* Width of the docked panel in pixels. The value is exposed via the
|
|
58
|
+
* `--q-docked-width` custom property and animates between this and 0 when
|
|
59
|
+
* docking is toggled.
|
|
60
|
+
*/ const DOCKED_WIDTH_PX = 400;
|
|
61
|
+
/**
|
|
62
|
+
* Custom property that holds the active docked panel width. Set to 0 by default
|
|
63
|
+
* and to {@link DOCKED_WIDTH_PX} when `html[q-docked]` is present.
|
|
64
|
+
*/ const DOCKED_WIDTH_CSS_VARIABLE = "--q-docked-width";
|
|
65
|
+
/**
|
|
66
|
+
* Horizontal offset eaten by the docked panel plus the host page's scrollbar.
|
|
67
|
+
* Internal: shrinks `<html>` and feeds
|
|
68
|
+
* {@link DOCKED_RIGHT_OFFSET_CSS_VARIABLE}.
|
|
69
|
+
*/ const DOCKED_VIEWPORT_OFFSET_CSS_VARIABLE = "--q-docked-viewport-offset";
|
|
70
|
+
/**
|
|
71
|
+
* How far right of its containing block's edge the real viewport edge sits, for
|
|
72
|
+
* anything overlaying the page. Consume as `right: var(..., 0px)`, the fallback
|
|
73
|
+
* covering docking not being loaded.
|
|
74
|
+
*
|
|
75
|
+
* Always declared, so no consumer rebuilds it from parts. Non-zero only where
|
|
76
|
+
* docking shrank `<html>` and a fixed child's containing block stops at the
|
|
77
|
+
* gutter's inner edge.
|
|
78
|
+
*/ const DOCKED_RIGHT_OFFSET_CSS_VARIABLE = "--q-docked-right-offset";
|
|
79
|
+
/**
|
|
80
|
+
* Container name applied to `<html>` so the responsive @container rules
|
|
81
|
+
* generated from the host's @media rules target the correct container.
|
|
82
|
+
*/ const DOCKED_DOCUMENT_CONTAINER_NAME = "q-docked-container";
|
|
83
|
+
// Host page's main/footer regions that shrink to form the gutter in
|
|
84
|
+
// `dockUnderHeader` mode (semantic elements + their ARIA landmarks).
|
|
85
|
+
const DOCKED_UNDER_HEADER_TARGET_SELECTOR = "main, [role='main'], footer, [role='contentinfo']";
|
|
86
|
+
function createViewportResize(options) {
|
|
87
|
+
if (options === void 0) options = {};
|
|
88
|
+
var _options_dockUnderHeader, _options_skipCrossOriginStylesheets;
|
|
89
|
+
const dockUnderHeader = (_options_dockUnderHeader = options.dockUnderHeader) != null ? _options_dockUnderHeader : false;
|
|
90
|
+
const state = {
|
|
91
|
+
processedSheets: new WeakSet(),
|
|
92
|
+
scrollbarWidth: 0,
|
|
93
|
+
rootObserver: null,
|
|
94
|
+
linkRelObserver: null,
|
|
95
|
+
mqlByMedia: new Map(),
|
|
96
|
+
linksByMql: new WeakMap(),
|
|
97
|
+
attrsByMql: new WeakMap(),
|
|
98
|
+
linkOriginalMedia: new WeakMap(),
|
|
99
|
+
headerObserver: null
|
|
100
|
+
};
|
|
101
|
+
const transform = (sheet)=>{
|
|
102
|
+
transformStylesheet(sheet, transformContext);
|
|
103
|
+
};
|
|
104
|
+
const transformLinkMedia = (link)=>{
|
|
105
|
+
// WeakMap miss = first time we've touched this element. A reconnected
|
|
106
|
+
// link hits the WeakMap and skips the dimension gate (its current
|
|
107
|
+
// `link.media` has already been rewritten and no longer parses as one).
|
|
108
|
+
let originalMedia = state.linkOriginalMedia.get(link);
|
|
109
|
+
if (!originalMedia) {
|
|
110
|
+
if (!link.media) return;
|
|
111
|
+
if (!extractDimensionConditions(link.media)) return;
|
|
112
|
+
originalMedia = link.media;
|
|
113
|
+
state.linkOriginalMedia.set(link, originalMedia);
|
|
114
|
+
}
|
|
115
|
+
registerMqlConsumer(state, state.linksByMql, originalMedia, link, (live, matches)=>{
|
|
116
|
+
var _state_linkOriginalMedia_get;
|
|
117
|
+
if (!live.isConnected) {
|
|
118
|
+
// Lazily prune detached links; the WeakMap entry survives so a
|
|
119
|
+
// future re-attach can re-register against the original query.
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
const recoveredOriginal = (_state_linkOriginalMedia_get = state.linkOriginalMedia.get(live)) != null ? _state_linkOriginalMedia_get : originalMedia;
|
|
123
|
+
live.media = computeMediaForLink(recoveredOriginal, matches);
|
|
124
|
+
return true;
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
const registerHtmlAttrForMedia = (mediaCondition, attr)=>{
|
|
128
|
+
registerMqlConsumer(state, state.attrsByMql, mediaCondition, attr, (name, matches)=>{
|
|
129
|
+
document.documentElement.toggleAttribute(name, matches);
|
|
130
|
+
return true;
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
// Bundle the per-instance dependencies that the file-scope transform
|
|
134
|
+
// helpers need. Avoids growing parameter lists every time we add a new
|
|
135
|
+
// hook (e.g. registerHtmlAttrForMedia for the html-self side channel).
|
|
136
|
+
const transformContext = {
|
|
137
|
+
processedSheets: state.processedSheets,
|
|
138
|
+
registerHtmlAttrForMedia,
|
|
139
|
+
skipCrossOriginStylesheets: (_options_skipCrossOriginStylesheets = options.skipCrossOriginStylesheets) != null ? _options_skipCrossOriginStylesheets : false
|
|
140
|
+
};
|
|
141
|
+
// Unified node handler used by every entry point (initial scan, mutation
|
|
142
|
+
// observer, link rel observer). Closure capture lets it pull from the
|
|
143
|
+
// shared `state` without file-scope helpers needing to know about it.
|
|
144
|
+
const handleNewStyleNode = (node)=>{
|
|
145
|
+
if (node instanceof HTMLStyleElement && node.sheet) {
|
|
146
|
+
transform(node.sheet);
|
|
147
|
+
} else if (node instanceof HTMLLinkElement && linkAppliesStylesheet(node)) {
|
|
148
|
+
transformLinkMedia(node);
|
|
149
|
+
if (node.sheet) {
|
|
150
|
+
transform(node.sheet);
|
|
151
|
+
} else {
|
|
152
|
+
node.addEventListener("load", ()=>{
|
|
153
|
+
if (node.sheet) {
|
|
154
|
+
transform(node.sheet);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
} else if (node instanceof HTMLLinkElement && linkIsPreloadStyle(node)) {
|
|
159
|
+
var // Async CSS pattern (HubSpot hs-async-css, loadCSS, ...): the link is
|
|
160
|
+
// injected as rel="preload" and the inline onload flips it to include
|
|
161
|
+
// "stylesheet" once the resource fetches. Watch the rel attribute so we
|
|
162
|
+
// re-enter the stylesheet branch above the moment that happens. Ordered
|
|
163
|
+
// after the stylesheet branch so a link that is already applied
|
|
164
|
+
// (rel="preload stylesheet") is transformed now rather than merely
|
|
165
|
+
// observed.
|
|
166
|
+
_state_linkRelObserver;
|
|
167
|
+
(_state_linkRelObserver = state.linkRelObserver) == null ? void 0 : _state_linkRelObserver.observe(node, {
|
|
168
|
+
attributes: true,
|
|
169
|
+
attributeFilter: [
|
|
170
|
+
"rel"
|
|
171
|
+
]
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const handleNewRootNode = (root)=>{
|
|
176
|
+
var _root_adoptedStyleSheets;
|
|
177
|
+
if (isQualifiedOwnedShadowRoot(root)) return;
|
|
178
|
+
if (root === document) {
|
|
179
|
+
var _state_rootObserver;
|
|
180
|
+
(_state_rootObserver = state.rootObserver) == null ? void 0 : _state_rootObserver.observe(root.head, {
|
|
181
|
+
childList: true,
|
|
182
|
+
subtree: true
|
|
183
|
+
});
|
|
184
|
+
whenBodyAvailable((body)=>{
|
|
185
|
+
var _state_rootObserver;
|
|
186
|
+
(_state_rootObserver = state.rootObserver) == null ? void 0 : _state_rootObserver.observe(body, {
|
|
187
|
+
childList: true,
|
|
188
|
+
subtree: true
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
} else {
|
|
192
|
+
var _state_rootObserver1;
|
|
193
|
+
(_state_rootObserver1 = state.rootObserver) == null ? void 0 : _state_rootObserver1.observe(root, {
|
|
194
|
+
childList: true,
|
|
195
|
+
subtree: true
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
for (const sheet of tryGet(()=>root.styleSheets, [])){
|
|
199
|
+
transform(sheet);
|
|
200
|
+
}
|
|
201
|
+
for (const sheet of (_root_adoptedStyleSheets = root.adoptedStyleSheets) != null ? _root_adoptedStyleSheets : []){
|
|
202
|
+
transform(sheet);
|
|
203
|
+
}
|
|
204
|
+
handlePendingLinkStylesheets(root, handleNewStyleNode);
|
|
205
|
+
};
|
|
206
|
+
const handleNewElements = ()=>{
|
|
207
|
+
var _state_headerObserver;
|
|
208
|
+
if (!dockUnderHeader) {
|
|
209
|
+
document.documentElement.setAttribute(DOCKED_TARGET_ATTRIBUTE, "true");
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
for (const el of queryAllAcrossRoots(DOCKED_UNDER_HEADER_TARGET_SELECTOR, isQualifiedOwnedShadowRoot)){
|
|
213
|
+
el.setAttribute(DOCKED_TARGET_ATTRIBUTE, "true");
|
|
214
|
+
// The light-DOM `[q-docked-target]` rule can't reach into shadow roots, so
|
|
215
|
+
// mirror the shrink as inline styles there (inherited vars cross the boundary).
|
|
216
|
+
if (el.getRootNode() instanceof ShadowRoot) applyInlineShrink(el);
|
|
217
|
+
}
|
|
218
|
+
(_state_headerObserver = state.headerObserver) == null ? void 0 : _state_headerObserver.start();
|
|
219
|
+
};
|
|
220
|
+
return {
|
|
221
|
+
init () {
|
|
222
|
+
state.scrollbarWidth = measureScrollbarWidth();
|
|
223
|
+
if (dockUnderHeader) {
|
|
224
|
+
state.headerObserver = createHeaderObserver();
|
|
225
|
+
}
|
|
226
|
+
registerCssAnimationProperty();
|
|
227
|
+
installResizeProxy();
|
|
228
|
+
installIframeProxies();
|
|
229
|
+
installAdoptedStyleSheetProxy(transform);
|
|
230
|
+
installAttachShadowProxy(handleNewRootNode);
|
|
231
|
+
},
|
|
232
|
+
reEvaluate () {
|
|
233
|
+
var _state_rootObserver, _state_linkRelObserver;
|
|
234
|
+
(_state_rootObserver = state.rootObserver) == null ? void 0 : _state_rootObserver.disconnect();
|
|
235
|
+
(_state_linkRelObserver = state.linkRelObserver) == null ? void 0 : _state_linkRelObserver.disconnect();
|
|
236
|
+
state.rootObserver = createRootObserver(handleNewStyleNode, handleNewRootNode, handleNewElements);
|
|
237
|
+
state.linkRelObserver = createLinkRelObserver(handleNewStyleNode);
|
|
238
|
+
handleNewRootNode(document);
|
|
239
|
+
for (const root of findShadowRoots()){
|
|
240
|
+
handleNewRootNode(root);
|
|
241
|
+
}
|
|
242
|
+
handleNewElements();
|
|
243
|
+
},
|
|
244
|
+
getStyles () {
|
|
245
|
+
// Keys off which element is the docked target, so one stylesheet serves both
|
|
246
|
+
// modes: <html> absorbs widget width + scrollbar; non-<html> targets shrink
|
|
247
|
+
// by widget width only while <html> clips just the scrollbar.
|
|
248
|
+
return /* css */ "\n html {\n " + DOCKED_WIDTH_CSS_VARIABLE + ": 0px;\n " + DOCKED_VIEWPORT_OFFSET_CSS_VARIABLE + ": var(" + DOCKED_WIDTH_CSS_VARIABLE + ");\n " + (/* inlined export .DOCKED_VIEWPORT_WIDTH_CSS_VARIABLE */"--qdvw") + ": calc(100dvw - var(" + DOCKED_VIEWPORT_OFFSET_CSS_VARIABLE + "));\n " + DOCKED_RIGHT_OFFSET_CSS_VARIABLE + ": 0px;\n transition: " + DOCKED_WIDTH_CSS_VARIABLE + " 300ms ease-out;\n container-type: inline-size !important;\n container-name: " + DOCKED_DOCUMENT_CONTAINER_NAME + " !important;\n }\n html[" + DOCKED_TARGET_ATTRIBUTE + "] {\n " + DOCKED_VIEWPORT_OFFSET_CSS_VARIABLE + ": calc(var(" + DOCKED_WIDTH_CSS_VARIABLE + ") + " + state.scrollbarWidth + "px);\n " + DOCKED_RIGHT_OFFSET_CSS_VARIABLE + ": calc(-1 * var(" + DOCKED_VIEWPORT_OFFSET_CSS_VARIABLE + "));\n min-width: var(" + (/* inlined export .DOCKED_VIEWPORT_WIDTH_CSS_VARIABLE */"--qdvw") + ") !important;\n max-width: var(" + (/* inlined export .DOCKED_VIEWPORT_WIDTH_CSS_VARIABLE */"--qdvw") + ") !important;\n width: var(" + (/* inlined export .DOCKED_VIEWPORT_WIDTH_CSS_VARIABLE */"--qdvw") + ") !important;\n margin-right: var(" + DOCKED_VIEWPORT_OFFSET_CSS_VARIABLE + ") !important;\n }\n html[" + DOCKED_DOCUMENT_ATTRIBUTE + "] {\n " + DOCKED_WIDTH_CSS_VARIABLE + ": " + DOCKED_WIDTH_PX + "px;\n }\n [" + DOCKED_TARGET_ATTRIBUTE + "]:not(html) {\n min-width: calc(100% - var(" + DOCKED_WIDTH_CSS_VARIABLE + ")) !important;\n max-width: calc(100% - var(" + DOCKED_WIDTH_CSS_VARIABLE + ")) !important;\n width: calc(100% - var(" + DOCKED_WIDTH_CSS_VARIABLE + ")) !important;\n margin-right: var(" + DOCKED_WIDTH_CSS_VARIABLE + ") !important;\n container-type: inline-size !important;\n container-name: " + DOCKED_DOCUMENT_CONTAINER_NAME + " !important;\n }\n @media (" + MOBILE_BREAKPOINT + ") {\n html[" + DOCKED_DOCUMENT_ATTRIBUTE + "] {\n " + DOCKED_WIDTH_CSS_VARIABLE + ": 0px;\n " + DOCKED_VIEWPORT_OFFSET_CSS_VARIABLE + ": 0px;\n }\n }\n ";
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Applies the docked-gutter shrink as inline styles for under-header targets
|
|
254
|
+
* inside shadow roots, where the light-DOM `[q-docked-target]` rule can't reach.
|
|
255
|
+
*/ function applyInlineShrink(el) {
|
|
256
|
+
const w = "calc(100% - var(" + DOCKED_WIDTH_CSS_VARIABLE + "))";
|
|
257
|
+
el.style.setProperty("min-width", w, "important");
|
|
258
|
+
el.style.setProperty("max-width", w, "important");
|
|
259
|
+
el.style.setProperty("width", w, "important");
|
|
260
|
+
el.style.setProperty("margin-right", "var(" + DOCKED_WIDTH_CSS_VARIABLE + ")", "important");
|
|
261
|
+
el.style.setProperty("container-type", "inline-size", "important");
|
|
262
|
+
el.style.setProperty("container-name", DOCKED_DOCUMENT_CONTAINER_NAME, "important");
|
|
263
|
+
}
|
|
264
|
+
// ============================================================================
|
|
265
|
+
// Init Helpers
|
|
266
|
+
// ============================================================================
|
|
267
|
+
/**
|
|
268
|
+
* Registers `--q-docked-width` as a typed `<length>` so the value is
|
|
269
|
+
* interpolatable, which is what makes the docked panel slide smoothly between
|
|
270
|
+
* 0 and {@link DOCKED_WIDTH_PX} instead of snapping.
|
|
271
|
+
*/ function registerCssAnimationProperty() {
|
|
272
|
+
try {
|
|
273
|
+
if ("registerProperty" in window.CSS) {
|
|
274
|
+
window.CSS.registerProperty({
|
|
275
|
+
name: DOCKED_WIDTH_CSS_VARIABLE,
|
|
276
|
+
syntax: "<length>",
|
|
277
|
+
inherits: true,
|
|
278
|
+
initialValue: "0px"
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
} catch (unused) {
|
|
282
|
+
// Already registered, ignore
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Uses a ResizeObserver on `<html>` to forward size changes as window
|
|
287
|
+
* resize events. The effective viewport width changes when the docked
|
|
288
|
+
* panel opens/closes (via the CSS variable transition), and customer
|
|
289
|
+
* code listening for `window.resize` needs to be notified.
|
|
290
|
+
*/ function installResizeProxy() {
|
|
291
|
+
applyOnce(document.documentElement, "" + DOCKING_PROXY_MARKER + "_resize", (el)=>{
|
|
292
|
+
new ResizeObserver(()=>dispatchResizeEvent()).observe(el);
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Points every viewport reading the host page can take — `window.innerWidth`
|
|
297
|
+
* / `innerHeight`, `document.documentElement.clientWidth` / `clientHeight`
|
|
298
|
+
* and `window.matchMedia` — at the hidden probe iframe, whose own viewport is
|
|
299
|
+
* sized to the constrained content area by CSS.
|
|
300
|
+
*
|
|
301
|
+
* When docking is active, `<html>` is shrunk to `100dvw - 400px`. Customer code
|
|
302
|
+
* that measures the viewport directly would otherwise see the full width and
|
|
303
|
+
* make wrong layout decisions (e.g. showing a desktop nav when the content area
|
|
304
|
+
* is at a mobile breakpoint). `clientWidth/Height` need proxying too because
|
|
305
|
+
* the browser reports the initial containing block for those regardless of any
|
|
306
|
+
* CSS applied to `<html>`.
|
|
307
|
+
*
|
|
308
|
+
* Sourcing all of them from one iframe keeps the numbers mutually consistent —
|
|
309
|
+
* a `(max-width: 767px)` query flips at exactly the width `innerWidth` reports
|
|
310
|
+
* — and media queries get native behavior (`change` events included) with no
|
|
311
|
+
* manual parsing or evaluation.
|
|
312
|
+
*
|
|
313
|
+
* The iframe is resolved per read rather than captured once, so a host page
|
|
314
|
+
* that replaces `<html>`'s children (detaching ours) recovers on the next read
|
|
315
|
+
* via the rebuilt `<q-docking>` singleton. Until a fresh iframe has laid out,
|
|
316
|
+
* each proxy falls back to the closest same-axis measurement.
|
|
317
|
+
*
|
|
318
|
+
* Every patch goes through {@link applyProxy}, so our own code can still reach
|
|
319
|
+
* the browser's real values with `originalOf(window)` — which the liveview
|
|
320
|
+
* shipper needs, since its receiver applies the docked shrink itself.
|
|
321
|
+
*/ function installIframeProxies() {
|
|
322
|
+
// Touch the iframe now rather than on the first read, so the browser has laid
|
|
323
|
+
// it out (and `--qdvw` has landed) before anything measures it.
|
|
324
|
+
probeIframeWindow();
|
|
325
|
+
applyOnce(window, "" + DOCKING_PROXY_MARKER + "_innerSize", (win)=>{
|
|
326
|
+
const { documentElement } = document;
|
|
327
|
+
applyProxy(win, "innerWidth", {
|
|
328
|
+
get () {
|
|
329
|
+
return measureInProbeIframe((probe)=>probe.innerWidth, ()=>documentElement.offsetWidth);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
applyProxy(win, "innerHeight", {
|
|
333
|
+
get () {
|
|
334
|
+
return measureInProbeIframe((probe)=>probe.innerHeight, ()=>documentElement.offsetHeight);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
applyOnce(document.documentElement, "" + DOCKING_PROXY_MARKER + "_clientSize", (el)=>{
|
|
339
|
+
applyProxy(el, "clientWidth", {
|
|
340
|
+
get () {
|
|
341
|
+
return measureInProbeIframe((probe)=>probe.document.documentElement.clientWidth, ()=>el.offsetWidth);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
applyProxy(el, "clientHeight", {
|
|
345
|
+
get () {
|
|
346
|
+
return measureInProbeIframe((probe)=>probe.document.documentElement.clientHeight, ()=>el.offsetHeight);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
applyOnce(window, "" + DOCKING_PROXY_MARKER + "_matchMedia", (win)=>{
|
|
351
|
+
// Captured through the raw view so a re-entrant install can't wrap our own
|
|
352
|
+
// proxy; consumers that need the host viewport read it the same way.
|
|
353
|
+
const { matchMedia } = originalOf(win);
|
|
354
|
+
applyProxy(win, "matchMedia", {
|
|
355
|
+
enumerable: true,
|
|
356
|
+
writable: true,
|
|
357
|
+
value: (query)=>{
|
|
358
|
+
const probe = probeIframeWindow();
|
|
359
|
+
// Feature-detected rather than assumed: not every browsing context
|
|
360
|
+
// exposes matchMedia (jsdom's iframes don't).
|
|
361
|
+
return typeof (probe == null ? void 0 : probe.matchMedia) === "function" ? probe.matchMedia(query) : matchMedia.call(win, query);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
/** The probe iframe's window, or null while it has no browsing context. */ function probeIframeWindow() {
|
|
367
|
+
return tryGet(()=>getProbeIframe().contentWindow, null);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Reads a dimension from the probe iframe, falling back to `fallback()` when
|
|
371
|
+
* the iframe has no browsing context or reports a non-positive size (detached,
|
|
372
|
+
* still initialising, or hidden by the host page). A zero reading is never
|
|
373
|
+
* useful — it would tell customer code the content area has collapsed — and the
|
|
374
|
+
* fallback is a thunk so the healthy path never forces an extra layout.
|
|
375
|
+
*/ function measureInProbeIframe(read, fallback) {
|
|
376
|
+
const probe = probeIframeWindow();
|
|
377
|
+
const measured = probe ? tryGet(()=>read(probe)) : undefined;
|
|
378
|
+
return typeof measured === "number" && measured > 0 ? measured : fallback();
|
|
379
|
+
}
|
|
380
|
+
// ============================================================================
|
|
381
|
+
// MQL Consumer Registry
|
|
382
|
+
// ============================================================================
|
|
383
|
+
/**
|
|
384
|
+
* Subscribes a consumer to a media query against the iframe-backed
|
|
385
|
+
* `window.matchMedia` (so the query evaluates the docked container, not the
|
|
386
|
+
* host viewport). MQLs are deduplicated by media string in `state.mqlByMedia`,
|
|
387
|
+
* shared across consumer types — link rewriting and html-attribute toggling
|
|
388
|
+
* both subscribe through here, and they share the same MQL instance when the
|
|
389
|
+
* conditions match. The first registration for a given (mql, consumersByMql)
|
|
390
|
+
* pair installs the change listener that fans out to every consumer.
|
|
391
|
+
*
|
|
392
|
+
* `apply` is invoked once at registration with the current matches state and
|
|
393
|
+
* again on every subsequent change. Returning `false` removes the consumer
|
|
394
|
+
* from the set, which the link path uses to lazily prune detached elements
|
|
395
|
+
* (the closure would otherwise keep them alive).
|
|
396
|
+
*/ function registerMqlConsumer(state, consumersByMql, media, consumer, apply) {
|
|
397
|
+
let mql = state.mqlByMedia.get(media);
|
|
398
|
+
if (!mql) {
|
|
399
|
+
mql = window.matchMedia(media);
|
|
400
|
+
state.mqlByMedia.set(media, mql);
|
|
401
|
+
}
|
|
402
|
+
let consumers = consumersByMql.get(mql);
|
|
403
|
+
if (!consumers) {
|
|
404
|
+
consumers = new Set();
|
|
405
|
+
consumersByMql.set(mql, consumers);
|
|
406
|
+
// Capture locals so the listener doesn't depend on the outer let-bindings.
|
|
407
|
+
const targetMql = mql;
|
|
408
|
+
const targetConsumers = consumers;
|
|
409
|
+
targetMql.addEventListener("change", ()=>{
|
|
410
|
+
for (const c of targetConsumers){
|
|
411
|
+
if (!apply(c, targetMql.matches)) {
|
|
412
|
+
targetConsumers.delete(c);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
consumers.add(consumer);
|
|
418
|
+
apply(consumer, mql.matches);
|
|
419
|
+
return mql;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Patches `Document.prototype` and `ShadowRoot.prototype` so that any
|
|
423
|
+
* future assignment or in-place mutation of `adoptedStyleSheets`
|
|
424
|
+
* automatically transforms newly added stylesheets.
|
|
425
|
+
*
|
|
426
|
+
* Per-instance proxy caching is handled via a WeakMap so each root
|
|
427
|
+
* (document or shadow root) gets its own cached proxy.
|
|
428
|
+
*/ function installAdoptedStyleSheetProxy(transform) {
|
|
429
|
+
const proxyFor = new WeakMap();
|
|
430
|
+
for (const proto of [
|
|
431
|
+
Document.prototype,
|
|
432
|
+
ShadowRoot.prototype
|
|
433
|
+
]){
|
|
434
|
+
applyOnce(proto, "" + DOCKING_PROXY_MARKER + "_adopted", ()=>{
|
|
435
|
+
const desc = Object.getOwnPropertyDescriptor(proto, "adoptedStyleSheets");
|
|
436
|
+
if (!(desc == null ? void 0 : desc.get) || !(desc == null ? void 0 : desc.set)) return;
|
|
437
|
+
const originalGet = desc.get;
|
|
438
|
+
const originalSet = desc.set;
|
|
439
|
+
Object.defineProperty(proto, "adoptedStyleSheets", {
|
|
440
|
+
get () {
|
|
441
|
+
const sheets = originalGet.call(this);
|
|
442
|
+
const cached = proxyFor.get(sheets);
|
|
443
|
+
if (cached) return cached;
|
|
444
|
+
const proxy = createAdoptedSheetsProxy(this, sheets, transform);
|
|
445
|
+
proxyFor.set(sheets, proxy);
|
|
446
|
+
return proxy;
|
|
447
|
+
},
|
|
448
|
+
set (sheets) {
|
|
449
|
+
originalSet.call(this, sheets);
|
|
450
|
+
if (isQualifiedOwnedShadowRoot(this)) return;
|
|
451
|
+
for (const sheet of sheets){
|
|
452
|
+
transform(sheet);
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
configurable: true
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Wraps an adopted stylesheet array in a Proxy whose `set` trap
|
|
462
|
+
* intercepts element additions (index assignment, push, splice, etc.)
|
|
463
|
+
* and transforms any newly added CSSStyleSheet.
|
|
464
|
+
*/ function createAdoptedSheetsProxy(root, sheets, transform) {
|
|
465
|
+
if (isQualifiedOwnedShadowRoot(root)) return sheets;
|
|
466
|
+
return new Proxy(sheets, {
|
|
467
|
+
set (target, prop, value) {
|
|
468
|
+
const result = Reflect.set(target, prop, value);
|
|
469
|
+
if (value instanceof CSSStyleSheet) {
|
|
470
|
+
transform(value);
|
|
471
|
+
}
|
|
472
|
+
return result;
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Patches `Element.prototype.attachShadow` so that every newly created
|
|
478
|
+
* shadow root is automatically processed (stylesheets transformed and
|
|
479
|
+
* mutation observer attached). This catches shadow roots created by
|
|
480
|
+
* customer code or third-party libraries after the initial DOM scan.
|
|
481
|
+
*/ function installAttachShadowProxy(observe) {
|
|
482
|
+
applyOnce(Element.prototype, "" + DOCKING_PROXY_MARKER + "_shadow", (proto)=>{
|
|
483
|
+
const original = proto.attachShadow;
|
|
484
|
+
proto.attachShadow = function() {
|
|
485
|
+
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
|
|
486
|
+
args[_key] = arguments[_key];
|
|
487
|
+
}
|
|
488
|
+
const root = original.call(this, ...args);
|
|
489
|
+
observe(root);
|
|
490
|
+
return root;
|
|
491
|
+
};
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
// ============================================================================
|
|
495
|
+
// Document Observer
|
|
496
|
+
// ============================================================================
|
|
497
|
+
/**
|
|
498
|
+
* Creates a single MutationObserver that handles stylesheet additions and
|
|
499
|
+
* shadow root discovery. Initially observes the document; shadow roots are
|
|
500
|
+
* added via additional `.observe()` calls (a single observer can watch
|
|
501
|
+
* multiple roots — `.disconnect()` detaches them all at once).
|
|
502
|
+
*
|
|
503
|
+
* The selector includes `link[rel~='preload'][as='style']` so we also catch
|
|
504
|
+
* async CSS patterns (HubSpot, loadCSS, ...) where the link starts as a
|
|
505
|
+
* preload and only becomes a real stylesheet once `rel` flips. `~=` matches
|
|
506
|
+
* a single whitespace-separated token, so multi-token values like
|
|
507
|
+
* `rel="preload stylesheet"` are recognised too. The link rel observer is
|
|
508
|
+
* what actually drives the rel-flip transition; this selector just makes
|
|
509
|
+
* sure we register those links in the first place.
|
|
510
|
+
*/ function createRootObserver(handleNewStyleNode, handleNewRootNode, handleNewElements) {
|
|
511
|
+
const observer = new MutationObserver((mutations)=>{
|
|
512
|
+
let elementAdded = false;
|
|
513
|
+
for (const mutation of mutations){
|
|
514
|
+
for (const node of mutation.addedNodes){
|
|
515
|
+
if (node instanceof HTMLStyleElement || node instanceof HTMLLinkElement) {
|
|
516
|
+
handleNewStyleNode(node);
|
|
517
|
+
} else if (node instanceof Element) {
|
|
518
|
+
elementAdded = true;
|
|
519
|
+
handleDeclarativeShadowRoots(node, handleNewRootNode);
|
|
520
|
+
for (const child of node.querySelectorAll("style, " + STYLESHEET_LINK_SELECTOR)){
|
|
521
|
+
handleNewStyleNode(child);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
if (elementAdded) handleNewElements();
|
|
527
|
+
});
|
|
528
|
+
return observer;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Creates a single MutationObserver that detects when a `<link>` element's
|
|
532
|
+
* `rel` attribute changes. The async CSS pattern (HubSpot's `hs-async-css`,
|
|
533
|
+
* filamentgroup's `loadCSS`, etc.) injects links as `rel="preload"` and an
|
|
534
|
+
* inline `onload="this.rel='stylesheet'"` flips them once the resource has
|
|
535
|
+
* been fetched.
|
|
536
|
+
*
|
|
537
|
+
* The observer is shared across every candidate link; we call `.observe()`
|
|
538
|
+
* on each link individually with `attributeFilter: ["rel"]` so we never
|
|
539
|
+
* watch head/body subtrees. On a rel mutation we just re-run the unified
|
|
540
|
+
* node handler, which dispatches to the regular `rel="stylesheet"` branch
|
|
541
|
+
* (the WeakSet of processed sheets prevents double-transformation).
|
|
542
|
+
*/ function createLinkRelObserver(processStyleNode) {
|
|
543
|
+
return new MutationObserver((mutations)=>{
|
|
544
|
+
for (const mutation of mutations){
|
|
545
|
+
if (mutation.target instanceof HTMLLinkElement) {
|
|
546
|
+
processStyleNode(mutation.target);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Handles declarative shadow DOM (`<template shadowrootmode="open">`).
|
|
553
|
+
* The browser creates these shadow roots during HTML parsing without
|
|
554
|
+
* calling `attachShadow`, so the prototype proxy cannot intercept them.
|
|
555
|
+
* This function checks a newly added element — and its subtree — for
|
|
556
|
+
* any `.shadowRoot` that needs stylesheet transformation.
|
|
557
|
+
*/ function handleDeclarativeShadowRoots(el, observe) {
|
|
558
|
+
if (el.shadowRoot) {
|
|
559
|
+
observe(el.shadowRoot);
|
|
560
|
+
for (const root of findShadowRoots(el.shadowRoot)){
|
|
561
|
+
observe(root);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
for (const root of findShadowRoots(el)){
|
|
565
|
+
observe(root);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Finds `<link>` elements that are in the DOM but haven't been processed
|
|
570
|
+
* yet — either still loading (`.sheet` is null) or staged as
|
|
571
|
+
* `rel="preload"` waiting to flip to `rel="stylesheet"` (HubSpot async CSS).
|
|
572
|
+
* These are missed by both the `styleSheets` iteration (not yet loaded)
|
|
573
|
+
* and the MutationObserver (already in the DOM before the observer
|
|
574
|
+
* started). Routes them through `processStyleNode`, which attaches load
|
|
575
|
+
* listeners for pending stylesheet links and a rel-flip observer for
|
|
576
|
+
* preload links.
|
|
577
|
+
*
|
|
578
|
+
* Two passes are needed to cover all timing scenarios:
|
|
579
|
+
*
|
|
580
|
+
* 1. Immediate pass — handles the late-init case (docking initialised after
|
|
581
|
+
* the page is fully parsed). Queries the full document so body links
|
|
582
|
+
* (e.g. AEM clientlibs injected via `<span class="header-injector">`) are
|
|
583
|
+
* also found, not just `<head>` links.
|
|
584
|
+
*
|
|
585
|
+
* 2. Deferred body pass — handles the early-init case (snippet running in
|
|
586
|
+
* `<head>` before `<body>` is parsed). At that point `document.body` does
|
|
587
|
+
* not yet exist so the immediate `querySelectorAll` finds nothing in the
|
|
588
|
+
* body. Once the body is available we rescan it to pick up any server-
|
|
589
|
+
* rendered `<link>` elements that the MutationObserver never saw.
|
|
590
|
+
*/ function handlePendingLinkStylesheets(root, processStyleNode) {
|
|
591
|
+
const scanLinks = (container)=>{
|
|
592
|
+
for (const link of container.querySelectorAll(STYLESHEET_LINK_SELECTOR)){
|
|
593
|
+
processStyleNode(link);
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
scanLinks(root);
|
|
597
|
+
// When the snippet runs in <head>, document.body doesn't exist yet so the
|
|
598
|
+
// scan above finds no body links. Re-scan once the body is available to
|
|
599
|
+
// catch server-rendered <link> elements (e.g. AEM clientlibs) that the
|
|
600
|
+
// MutationObserver never saw. whenBodyAvailable fires synchronously if the
|
|
601
|
+
// body already exists, so there is no double-processing risk.
|
|
602
|
+
if (root === document) whenBodyAvailable(scanLinks);
|
|
603
|
+
}
|
|
604
|
+
function findShadowRoots(root) {
|
|
605
|
+
if (root === void 0) root = document.body;
|
|
606
|
+
if (!root) return [];
|
|
607
|
+
const roots = [];
|
|
608
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
|
|
609
|
+
let node;
|
|
610
|
+
while(node = walker.nextNode()){
|
|
611
|
+
if (node instanceof Element && node.shadowRoot) {
|
|
612
|
+
roots.push(node.shadowRoot, ...findShadowRoots(node.shadowRoot));
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
return roots;
|
|
616
|
+
}
|
|
617
|
+
// ============================================================================
|
|
618
|
+
// Stylesheet Transformation
|
|
619
|
+
// ============================================================================
|
|
620
|
+
/**
|
|
621
|
+
* Transforms a single stylesheet in place.
|
|
622
|
+
*/ function transformStylesheet(sheet, ctx) {
|
|
623
|
+
if (!canProcessStylesheet(sheet, ctx)) return;
|
|
624
|
+
ctx.processedSheets.add(sheet);
|
|
625
|
+
try {
|
|
626
|
+
transformRules(sheet, sheet.cssRules, ctx);
|
|
627
|
+
} catch (unused) {
|
|
628
|
+
// Cross-origin stylesheets throw SecurityError; retry via crossorigin
|
|
629
|
+
// clone unless the caller has opted out.
|
|
630
|
+
if (!ctx.skipCrossOriginStylesheets) {
|
|
631
|
+
handleCrossOriginStylesheet(sheet);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Detects whether a stylesheet was loaded from a different origin. Inline
|
|
637
|
+
* `<style>` and `adoptedStyleSheets` have null href and are always
|
|
638
|
+
* same-origin; unparseable hrefs are treated as same-origin so we still
|
|
639
|
+
* attempt to read them.
|
|
640
|
+
*/ function isCrossOriginStylesheet(sheet) {
|
|
641
|
+
if (!sheet.href) return false;
|
|
642
|
+
try {
|
|
643
|
+
return new URL(sheet.href, document.baseURI).origin !== window.location.origin;
|
|
644
|
+
} catch (unused) {
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Loads a `crossorigin="anonymous"` clone of `<link>` inside the singleton
|
|
650
|
+
* `<q-docking>` shadow root, then atomically `replaceChild`s it into the
|
|
651
|
+
* main DOM once it has CORS-loaded. The regular pipeline then picks it up
|
|
652
|
+
* and rewrites its rules with full `cssRules` access.
|
|
653
|
+
*
|
|
654
|
+
* Loading inside the shadow root isolates the clone from the host page's
|
|
655
|
+
* named-access lookups (`window[id]` / bare-identifier resolution): a
|
|
656
|
+
* matching `id` or `name` would otherwise resolve to an `HTMLCollection`
|
|
657
|
+
* of two elements during the in-flight load, breaking host code that
|
|
658
|
+
* tests `... .indexOf(stylesheet.ownerNode) !== -1`. The swap preserves
|
|
659
|
+
* every cloned attribute on the main-DOM element so host code keeps
|
|
660
|
+
* resolving correctly afterwards.
|
|
661
|
+
*
|
|
662
|
+
* If the retry fails we remove the failed clone — the original `<link>`
|
|
663
|
+
* is never touched. The `crossorigin` attribute check prevents infinite
|
|
664
|
+
* retry loops once the swap has happened.
|
|
665
|
+
*/ function handleCrossOriginStylesheet(sheet) {
|
|
666
|
+
const { ownerNode } = sheet;
|
|
667
|
+
if (!(ownerNode instanceof HTMLLinkElement)) return;
|
|
668
|
+
if (ownerNode.hasAttribute("crossorigin")) return;
|
|
669
|
+
const newLink = ownerNode.cloneNode();
|
|
670
|
+
let url;
|
|
671
|
+
try {
|
|
672
|
+
url = new URL(newLink.href);
|
|
673
|
+
} catch (unused) {
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
// Append a query param to ensure the browser doesn't return a cached response of the original link
|
|
677
|
+
url.searchParams.append("q_docked", "true");
|
|
678
|
+
newLink.href = url.toString();
|
|
679
|
+
newLink.crossOrigin = "anonymous";
|
|
680
|
+
getDockingShadowRoot().appendChild(newLink);
|
|
681
|
+
let swapped = false;
|
|
682
|
+
newLink.addEventListener("load", ()=>{
|
|
683
|
+
if (swapped) return;
|
|
684
|
+
swapped = true;
|
|
685
|
+
const parent = ownerNode.parentNode;
|
|
686
|
+
if (!parent) {
|
|
687
|
+
newLink.remove();
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
parent.replaceChild(newLink, ownerNode);
|
|
691
|
+
// Mirror `disabled` onto the replacement. `cloneNode` doesn't copy it
|
|
692
|
+
// (IDL property delegating to `sheet.disabled`, not a reflected
|
|
693
|
+
// attribute), so host code that flipped it during the load would
|
|
694
|
+
// otherwise be silently dropped.
|
|
695
|
+
if (ownerNode.disabled) newLink.disabled = true;
|
|
696
|
+
});
|
|
697
|
+
newLink.addEventListener("error", ()=>{
|
|
698
|
+
if (swapped) return;
|
|
699
|
+
newLink.remove();
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Transforms rules within a stylesheet or grouping rule.
|
|
704
|
+
* Iterates backwards to handle index shifts when replacing rules.
|
|
705
|
+
*/ function transformRules(sheet, rules, ctx, parentRule) {
|
|
706
|
+
for(let i = rules.length - 1; i >= 0; i--){
|
|
707
|
+
const rule = rules[i];
|
|
708
|
+
try {
|
|
709
|
+
// Recursively transform inner rules first (covers CSSGroupingRule and CSS Nesting in CSSStyleRule)
|
|
710
|
+
if (isCSSRuleParent(rule)) {
|
|
711
|
+
transformRules(sheet, rule.cssRules, ctx, rule);
|
|
712
|
+
}
|
|
713
|
+
// Handle case by case rules here
|
|
714
|
+
if (rule instanceof CSSMediaRule) {
|
|
715
|
+
transformMediaRule(rule, i, parentRule != null ? parentRule : sheet, ctx);
|
|
716
|
+
} else if (rule instanceof CSSStyleRule) {
|
|
717
|
+
transformStyleRule(rule, i, parentRule != null ? parentRule : sheet);
|
|
718
|
+
}
|
|
719
|
+
} catch (unused) {
|
|
720
|
+
// Transforming a rule should not break the entire stylesheet processing.
|
|
721
|
+
// Cross-origin or malformed rules may throw - we skip them gracefully.
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Transforms a media rule - converts dimension conditions to container queries.
|
|
727
|
+
*
|
|
728
|
+
* Comma-separated query lists are split into segments, each emitted as its own
|
|
729
|
+
* @container rule. The CSSOM's insertRule() does not support comma-separated
|
|
730
|
+
* @container queries, so one rule per segment is the only viable approach.
|
|
731
|
+
* Segments without dimension conditions are skipped (no container equivalent).
|
|
732
|
+
*
|
|
733
|
+
* Multiple rules are inserted at consecutive indices — safe because transformRules
|
|
734
|
+
* iterates backwards, so already-processed indices are not revisited.
|
|
735
|
+
*
|
|
736
|
+
* Examples:
|
|
737
|
+
* @media (max-width: 599px), (min-width: 600px) and (max-width: 999px) { }
|
|
738
|
+
* → @container name (max-width: 599px) { }
|
|
739
|
+
* @container name (min-width: 600px) and (max-width: 999px) { }
|
|
740
|
+
*
|
|
741
|
+
* @media screen and (max-width: 768px) { }
|
|
742
|
+
* → @media screen { @container name (max-width: 768px) { } }
|
|
743
|
+
*
|
|
744
|
+
* @media not (min-width: 80rem) { } (CSS MQ Level 4 form)
|
|
745
|
+
* @media not all and (min-width: 80rem) { } (CSS MQ Level 3 form)
|
|
746
|
+
* → @container name not (min-width: 80rem) { }
|
|
747
|
+
*/ function transformMediaRule(rule, index, parent, ctx) {
|
|
748
|
+
const segments = splitTopLevelCommas(rule.conditionText);
|
|
749
|
+
const innerCSS = collectRulesCssText(rule.cssRules);
|
|
750
|
+
const containerRules = [];
|
|
751
|
+
const passthroughRules = [];
|
|
752
|
+
// Side-channel registrations are deferred until after the rule swap
|
|
753
|
+
// succeeds so a rolled-back transform doesn't leak MQL listeners for
|
|
754
|
+
// styles we never actually emitted.
|
|
755
|
+
const attrRegistrations = [];
|
|
756
|
+
for (const seg of segments){
|
|
757
|
+
const dimensions = extractDimensionConditions(seg);
|
|
758
|
+
if (dimensions !== null) {
|
|
759
|
+
const remaining = removeDimensionConditions(seg);
|
|
760
|
+
// `@media not (X)` / `@media not all and (X)` both negate the whole
|
|
761
|
+
// query. After dimension extraction the negation is all that's left,
|
|
762
|
+
// and wrapping the @container in `@media not { ... }` would serialize
|
|
763
|
+
// as `@media not all` (CSS-false). Fold the negation into the
|
|
764
|
+
// @container itself instead via `not <container-in-parens>`.
|
|
765
|
+
const negated = isNegationOnlyRemainder(remaining);
|
|
766
|
+
// Single dim is already paren-wrapped; multi-dim is "(A) and (B)" so
|
|
767
|
+
// re-wrap to keep `not` binding over the full conjunction.
|
|
768
|
+
const containerCondition = negated ? dimensions.includes(" and ") ? "not (" + dimensions + ")" : "not " + dimensions : dimensions;
|
|
769
|
+
const mediaWrapper = negated ? null : remaining;
|
|
770
|
+
const containerQuery = "@container " + DOCKED_DOCUMENT_CONTAINER_NAME + " " + containerCondition + " { " + innerCSS + " }";
|
|
771
|
+
containerRules.push(mediaWrapper ? "@media " + mediaWrapper + " { " + containerQuery + " }" : containerQuery);
|
|
772
|
+
// Container queries never match the container as a subject, so any
|
|
773
|
+
// rule whose subject is `<html>` (e.g. `html { ... }`, `:root.dark { ... }`)
|
|
774
|
+
// silently no-ops inside the @container block above. Mirror those rules
|
|
775
|
+
// at top level via a synthetic data-attribute we toggle on `<html>` from
|
|
776
|
+
// the same MQL. `:where()` keeps the original specificity, and inserting
|
|
777
|
+
// at the same index preserves cascade order with anything below.
|
|
778
|
+
const attr = attrNameForCondition(seg);
|
|
779
|
+
const htmlSubjectRules = collectHtmlSubjectInnerCss(rule.cssRules, attr);
|
|
780
|
+
if (htmlSubjectRules.length > 0) {
|
|
781
|
+
if (mediaWrapper) {
|
|
782
|
+
// Multiple rules inside one @media wrapper parse as a single
|
|
783
|
+
// CSSMediaRule, so we can hand the whole thing to insertRule.
|
|
784
|
+
containerRules.push("@media " + mediaWrapper + " { " + htmlSubjectRules.join(" ") + " }");
|
|
785
|
+
} else {
|
|
786
|
+
// No wrapper — insertRule() only accepts one top-level rule per
|
|
787
|
+
// call, so emit each html-subject rule as its own entry.
|
|
788
|
+
for (const r of htmlSubjectRules)containerRules.push(r);
|
|
789
|
+
}
|
|
790
|
+
attrRegistrations.push({
|
|
791
|
+
media: seg,
|
|
792
|
+
attr
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
} else {
|
|
796
|
+
// No dimension conditions — re-emit as a plain @media rule so the styles are not lost.
|
|
797
|
+
// This only runs when at least one sibling segment does have dimensions (checked below),
|
|
798
|
+
// preventing a no-op delete+reinsert for fully non-dimension rules like @media print { }.
|
|
799
|
+
passthroughRules.push("@media " + seg + " { " + innerCSS + " }");
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
// Only transform when at least one segment has dimension conditions.
|
|
803
|
+
// Fully non-dimension queries (e.g. @media print { }) are left untouched.
|
|
804
|
+
if (containerRules.length === 0) return;
|
|
805
|
+
const newRules = [
|
|
806
|
+
...containerRules,
|
|
807
|
+
...passthroughRules
|
|
808
|
+
];
|
|
809
|
+
// Atomic swap: insert the rewrites *after* the original (index + 1, +2, …)
|
|
810
|
+
// so the original is still at `index` if any insert throws, then delete it
|
|
811
|
+
// once every insert has succeeded. Earlier code deleted first and inserted
|
|
812
|
+
// after, which meant a single malformed rewrite (e.g. an unbalanced
|
|
813
|
+
// dimension extraction) would leave the cascade short a rule because
|
|
814
|
+
// transformRules() swallows the throw. On failure we roll the inserts back
|
|
815
|
+
// in reverse order so the original cascade is preserved exactly.
|
|
816
|
+
let inserted = 0;
|
|
817
|
+
try {
|
|
818
|
+
for(; inserted < newRules.length; inserted++){
|
|
819
|
+
parent.insertRule(newRules[inserted], index + inserted + 1);
|
|
820
|
+
}
|
|
821
|
+
} catch (err) {
|
|
822
|
+
for(let j = inserted; j > 0; j--){
|
|
823
|
+
try {
|
|
824
|
+
parent.deleteRule(index + j);
|
|
825
|
+
} catch (unused) {
|
|
826
|
+
// Best-effort rollback — if the cascade is already in a bad state
|
|
827
|
+
// there's nothing more we can do, but bailing here would leave the
|
|
828
|
+
// remaining successful inserts orphaned in the sheet.
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
throw err;
|
|
832
|
+
}
|
|
833
|
+
parent.deleteRule(index);
|
|
834
|
+
for (const { media, attr } of attrRegistrations){
|
|
835
|
+
ctx.registerHtmlAttrForMedia(media, attr);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* Transforms a style rule - converts vw units to calc expressions.
|
|
840
|
+
*
|
|
841
|
+
* Modifies individual property values in-place rather than re-serializing
|
|
842
|
+
* the entire rule, which avoids losing CSS shorthand properties that use
|
|
843
|
+
* variables (e.g. `inset: var(--spacing)`) due to CSSOM pending-substitution
|
|
844
|
+
* semantics.
|
|
845
|
+
*/ function transformStyleRule(rule, _index, _parent) {
|
|
846
|
+
const { style } = rule;
|
|
847
|
+
if (!containsVwUnit(style.cssText)) return;
|
|
848
|
+
for(let i = 0; i < style.length; i++){
|
|
849
|
+
const property = style[i];
|
|
850
|
+
if (property) {
|
|
851
|
+
const value = style.getPropertyValue(property);
|
|
852
|
+
if (containsVwUnit(value)) {
|
|
853
|
+
style.setProperty(property, convertVwUnitsIfPresent(value), style.getPropertyPriority(property));
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Checks if a stylesheet should be processed.
|
|
860
|
+
*/ function canProcessStylesheet(sheet, ctx) {
|
|
861
|
+
if (ctx.processedSheets.has(sheet)) return false;
|
|
862
|
+
// Bail before touching `sheet.cssRules` for cross-origin sheets when opted
|
|
863
|
+
// out, so we don't trigger the SecurityError throw path at all.
|
|
864
|
+
if (ctx.skipCrossOriginStylesheets && isCrossOriginStylesheet(sheet)) {
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
867
|
+
const { ownerNode } = sheet;
|
|
868
|
+
if (!(ownerNode instanceof HTMLStyleElement)) return true;
|
|
869
|
+
// Skip our own base styles and qualified offer styles
|
|
870
|
+
return ownerNode.id !== "q-docked-base-styles" && ownerNode.id !== "qualified-offer-style-element";
|
|
871
|
+
}
|
|
872
|
+
// ============================================================================
|
|
873
|
+
// Helpers
|
|
874
|
+
// ============================================================================
|
|
875
|
+
/**
|
|
876
|
+
* Selector for `<link>` elements that carry — or will apply — a stylesheet.
|
|
877
|
+
*
|
|
878
|
+
* `rel` is a space-separated token list, so we match with the `~=`
|
|
879
|
+
* (whitespace-token) attribute operator rather than `=` (exact string). This
|
|
880
|
+
* recognises multi-token values like `rel="preload stylesheet"` (AEM
|
|
881
|
+
* clientlibs' self-applying async pattern) that exact-match selectors miss,
|
|
882
|
+
* alongside plain `rel="stylesheet"` and the `rel="preload" as="style"`
|
|
883
|
+
* async-CSS staging form.
|
|
884
|
+
*/ const STYLESHEET_LINK_SELECTOR = "link[rel~='stylesheet'], link[rel~='preload'][as='style']";
|
|
885
|
+
/**
|
|
886
|
+
* True when a `<link>`'s `rel` token list includes `stylesheet` — i.e. it is
|
|
887
|
+
* (or will apply as) a real stylesheet. Token-aware so `rel="preload stylesheet"`
|
|
888
|
+
* counts, which `rel === "stylesheet"` would not.
|
|
889
|
+
*/ function linkAppliesStylesheet(node) {
|
|
890
|
+
return node.relList.contains("stylesheet");
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* True for an async-CSS staging link (`rel="preload" as="style"`) that has not
|
|
894
|
+
* yet flipped to a stylesheet. Token-aware on `rel` so multi-token preload
|
|
895
|
+
* values are still recognised, but excludes links whose `rel` already contains
|
|
896
|
+
* `stylesheet` (e.g. `rel="preload stylesheet"`): those apply now and belong to
|
|
897
|
+
* {@link linkAppliesStylesheet}, not the observe-and-wait path. Keeping the
|
|
898
|
+
* exclusion here — rather than relying on callers testing
|
|
899
|
+
* {@link linkAppliesStylesheet} first — makes the helper self-consistent for
|
|
900
|
+
* independent use.
|
|
901
|
+
*/ function linkIsPreloadStyle(node) {
|
|
902
|
+
// Read the `as` content attribute (rather than the `.as` IDL property) so
|
|
903
|
+
// the check agrees with the `[as="style"]` attribute selector used to find
|
|
904
|
+
// these links, and stays deterministic across DOM implementations.
|
|
905
|
+
return node.relList.contains("preload") && node.getAttribute("as") === "style" && !node.relList.contains("stylesheet");
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Collects CSS text from all rules in a rule list.
|
|
909
|
+
*/ function collectRulesCssText(rules) {
|
|
910
|
+
const parts = [];
|
|
911
|
+
for (const rule of rules){
|
|
912
|
+
parts.push(rule.cssText);
|
|
913
|
+
}
|
|
914
|
+
return parts.join(" ");
|
|
915
|
+
}
|
|
916
|
+
// ============================================================================
|
|
917
|
+
// Media Query Utilities
|
|
918
|
+
// ============================================================================
|
|
919
|
+
/**
|
|
920
|
+
* Splits a comma-separated CSS list at the top level, tracking parenthesis
|
|
921
|
+
* and bracket depth so we don't split inside condition expressions
|
|
922
|
+
* (`(min-width: 600px)`), functional pseudo-classes (`:is(a, b)`), or
|
|
923
|
+
* attribute selectors (`[data-x="a,b"]`).
|
|
924
|
+
*
|
|
925
|
+
* "(max-width: 599px), (min-width: 600px) and (max-width: 999px)"
|
|
926
|
+
* → ["(max-width: 599px)", "(min-width: 600px) and (max-width: 999px)"]
|
|
927
|
+
*
|
|
928
|
+
* "html, :is(.a, .b) > .c"
|
|
929
|
+
* → ["html", ":is(.a, .b) > .c"]
|
|
930
|
+
*/ function splitTopLevelCommas(text) {
|
|
931
|
+
const segments = [];
|
|
932
|
+
let depth = 0;
|
|
933
|
+
let start = 0;
|
|
934
|
+
for(let i = 0; i < text.length; i++){
|
|
935
|
+
const c = text[i];
|
|
936
|
+
if (c === "(" || c === "[") depth++;
|
|
937
|
+
else if (c === ")" || c === "]") depth--;
|
|
938
|
+
else if (c === "," && depth === 0) {
|
|
939
|
+
segments.push(text.slice(start, i).trim());
|
|
940
|
+
start = i + 1;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
segments.push(text.slice(start).trim());
|
|
944
|
+
return segments.filter(Boolean);
|
|
945
|
+
}
|
|
946
|
+
const DIMENSION_PROPERTIES = [
|
|
947
|
+
"width",
|
|
948
|
+
"min-width",
|
|
949
|
+
"max-width"
|
|
950
|
+
];
|
|
951
|
+
const DIMENSION_PROPERTIES_PATTERN = DIMENSION_PROPERTIES.join("|");
|
|
952
|
+
/**
|
|
953
|
+
* Tests whether a parenthesized media condition's *body* (the text between
|
|
954
|
+
* the outer parens) is a width-related dimension condition. Covers both
|
|
955
|
+
* the colon form (`max-width: 768px`, `width: calc(-1px + 75rem)`) and the
|
|
956
|
+
* range form (`768px <= width`, `width >= 600px`). The `[^a-z-]` boundaries
|
|
957
|
+
* avoid matching inside hyphenated identifiers like `device-width`, so we
|
|
958
|
+
* preserve the existing pass-through behavior for non-targeted features.
|
|
959
|
+
*/ const DIMENSION_BODY_PATTERN = new RegExp(String.raw(viewport_resize_templateObject(), DIMENSION_PROPERTIES_PATTERN) + String.raw(_templateObject1()) + String.raw(_templateObject2(), DIMENSION_PROPERTIES_PATTERN), "i");
|
|
960
|
+
/**
|
|
961
|
+
* Walks a media condition string and yields every paren group whose opening
|
|
962
|
+
* `(` is at depth 0, tracking nested parens so the matching `)` of the outer
|
|
963
|
+
* group is correctly identified even when the body contains functional
|
|
964
|
+
* values like `calc(-1px + 75rem)`, `min(...)`, `max(...)`, `clamp(...)`,
|
|
965
|
+
* `env(...)`, or `var(...)`.
|
|
966
|
+
*
|
|
967
|
+
* The previous regex used `[^)]+` for the value, which stopped at the first
|
|
968
|
+
* inner `)`. For `(max-width: calc(-1px + 75rem))` it produced an unbalanced
|
|
969
|
+
* match `(max-width: calc(-1px + 75rem)` (missing the outer `)`), which then
|
|
970
|
+
* generated invalid `@container` CSS that `insertRule` rejected — and because
|
|
971
|
+
* the original rule had already been deleted, the customer's media query
|
|
972
|
+
* silently stopped applying.
|
|
973
|
+
*
|
|
974
|
+
* "(max-width: calc(-1px + 75rem)) and (orientation: portrait)"
|
|
975
|
+
* → [
|
|
976
|
+
* { start: 0, end: 31, body: "max-width: calc(-1px + 75rem)" },
|
|
977
|
+
* { start: 36, end: 59, body: "orientation: portrait" },
|
|
978
|
+
* ]
|
|
979
|
+
*/ function* topLevelParenGroups(condition) {
|
|
980
|
+
let depth = 0;
|
|
981
|
+
let start = -1;
|
|
982
|
+
for(let i = 0; i < condition.length; i++){
|
|
983
|
+
const c = condition[i];
|
|
984
|
+
if (c === "(") {
|
|
985
|
+
if (depth === 0) start = i;
|
|
986
|
+
depth++;
|
|
987
|
+
} else if (c === ")") {
|
|
988
|
+
depth--;
|
|
989
|
+
if (depth === 0 && start >= 0) {
|
|
990
|
+
yield {
|
|
991
|
+
start,
|
|
992
|
+
end: i + 1,
|
|
993
|
+
body: condition.slice(start + 1, i)
|
|
994
|
+
};
|
|
995
|
+
start = -1;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* Extracts dimension-related conditions from a media query, joined by
|
|
1002
|
+
* " and " for emission inside an `@container` rule. Returns null when no
|
|
1003
|
+
* dimension condition is present so callers can leave the original rule
|
|
1004
|
+
* untouched.
|
|
1005
|
+
*/ function extractDimensionConditions(condition) {
|
|
1006
|
+
const matches = [];
|
|
1007
|
+
for (const { start, end, body } of topLevelParenGroups(condition)){
|
|
1008
|
+
if (DIMENSION_BODY_PATTERN.test(body)) {
|
|
1009
|
+
matches.push(condition.slice(start, end));
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
return matches.length ? matches.join(" and ") : null;
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Removes dimension-related conditions from a media query, leaving any
|
|
1016
|
+
* remaining non-dimension parts (`screen`, `(orientation: portrait)`,
|
|
1017
|
+
* `not`, `and` connectors) so the surrounding @media wrapper can be
|
|
1018
|
+
* preserved. Returns null when nothing meaningful remains.
|
|
1019
|
+
*/ function removeDimensionConditions(condition) {
|
|
1020
|
+
let result = "";
|
|
1021
|
+
let lastEnd = 0;
|
|
1022
|
+
for (const { start, end, body } of topLevelParenGroups(condition)){
|
|
1023
|
+
if (DIMENSION_BODY_PATTERN.test(body)) {
|
|
1024
|
+
result += condition.slice(lastEnd, start);
|
|
1025
|
+
lastEnd = end;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
result += condition.slice(lastEnd);
|
|
1029
|
+
let previous;
|
|
1030
|
+
do {
|
|
1031
|
+
previous = result;
|
|
1032
|
+
result = result.replace(/\s+and\s+and\s+/gi, " and ").replace(/^\s*and\s+/gi, "").replace(/\s+and\s*$/gi, "").replace(/\(\s*and\s+/gi, "(").replace(/\s+and\s*\)/gi, ")");
|
|
1033
|
+
}while (result !== previous);
|
|
1034
|
+
result = result.trim();
|
|
1035
|
+
return !result || result === "all" || result === "screen" ? null : result;
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Recognizes a remainder of the form `not` (bare), `not all`, or `not screen`
|
|
1039
|
+
* — i.e. the negations whose original query, in screen context, is equivalent
|
|
1040
|
+
* to `not (<dimensions>)`. Both `@media not (X)` (CSS MQ Level 4) and
|
|
1041
|
+
* `@media not all and (X)` (Level 3) negate the entire query, so once
|
|
1042
|
+
* dimensions are extracted the remainder is the signal that the original
|
|
1043
|
+
* was negating dimensions wholesale and can fold into a negated `@container`.
|
|
1044
|
+
*
|
|
1045
|
+
* Intentionally narrow on two axes:
|
|
1046
|
+
*
|
|
1047
|
+
* - `not <other media-type>` (e.g. `not print and (X)`) is rejected. The
|
|
1048
|
+
* spec evaluates that as `!(other && X)`, which in screen reduces to
|
|
1049
|
+
* `true` regardless of width — folding to `@container ... not (X)`
|
|
1050
|
+
* would incorrectly reintroduce a width gate the original never had,
|
|
1051
|
+
* so we let it fall through to the legacy path.
|
|
1052
|
+
* - Mixed remainders combining a negation with a non-dimension feature
|
|
1053
|
+
* cannot be expressed as a single negated `@container` by De Morgan,
|
|
1054
|
+
* so they also fall through.
|
|
1055
|
+
*/ const NEGATION_ONLY_REMAINDER = /^\s*not(?:\s+(?:all|screen))?\s*$/i;
|
|
1056
|
+
function isNegationOnlyRemainder(remaining) {
|
|
1057
|
+
return remaining !== null && NEGATION_ONLY_REMAINDER.test(remaining);
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* Per-segment toggle: non-dimension segments are kept verbatim (so `print`,
|
|
1061
|
+
* `(orientation: portrait)` etc. still gate the sheet), dimension segments
|
|
1062
|
+
* collapse to `"all"` / `"not all"` based on the MQL, and mixed segments
|
|
1063
|
+
* (e.g. `print and (min-width: 768px)`) keep just their non-dimension
|
|
1064
|
+
* remainder when matched.
|
|
1065
|
+
*/ function computeMediaForLink(originalMedia, matches) {
|
|
1066
|
+
return splitTopLevelCommas(originalMedia).map((seg)=>{
|
|
1067
|
+
var _removeDimensionConditions;
|
|
1068
|
+
if (extractDimensionConditions(seg) === null) return seg;
|
|
1069
|
+
if (!matches) return "not all";
|
|
1070
|
+
return (_removeDimensionConditions = removeDimensionConditions(seg)) != null ? _removeDimensionConditions : "all";
|
|
1071
|
+
}).join(", ");
|
|
1072
|
+
}
|
|
1073
|
+
// ============================================================================
|
|
1074
|
+
// Selector Utilities
|
|
1075
|
+
// ============================================================================
|
|
1076
|
+
/**
|
|
1077
|
+
* Returns the rightmost compound selector — i.e. the subject that the rule
|
|
1078
|
+
* actually styles. Walks backwards skipping over parens and brackets so
|
|
1079
|
+
* combinators inside `:is(...)`, `:has(...)`, `[attr="x > y"]` etc. are
|
|
1080
|
+
* ignored. CSSOM serializes combinators with a single surrounding space,
|
|
1081
|
+
* but we still treat raw `>`, `+`, `~` as combinators for safety.
|
|
1082
|
+
*
|
|
1083
|
+
* "html > body .foo" → ".foo"
|
|
1084
|
+
* ":is(div, p) > .bar" → ".bar"
|
|
1085
|
+
* "html.dark" → "html.dark"
|
|
1086
|
+
*/ function getRightmostCompound(selector) {
|
|
1087
|
+
let depth = 0;
|
|
1088
|
+
for(let i = selector.length - 1; i >= 0; i--){
|
|
1089
|
+
const c = selector[i];
|
|
1090
|
+
if (c === ")" || c === "]") depth++;
|
|
1091
|
+
else if (c === "(" || c === "[") depth--;
|
|
1092
|
+
else if (depth === 0 && (c === " " || c === "\t" || c === "\n" || c === ">" || c === "+" || c === "~")) {
|
|
1093
|
+
return selector.slice(i + 1).trim();
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
return selector.trim();
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* True when the selector's subject is the document root — `html`, `:root`,
|
|
1100
|
+
* or one of those followed by classes/ids/attributes/pseudo-classes
|
|
1101
|
+
* (`html.dark`, `:root[data-theme="x"]`, `html:focus-within`). These are
|
|
1102
|
+
* exactly the selectors that container queries can't match because the
|
|
1103
|
+
* container *is* the subject.
|
|
1104
|
+
*/ function isHtmlSubjectSelector(selector) {
|
|
1105
|
+
const compound = getRightmostCompound(selector);
|
|
1106
|
+
return /^(?:html|:root)(?:[.#:[]|$)/.test(compound);
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Stable 32-bit FNV-1a hash of a media condition, formatted as a `data-q-bp-*`
|
|
1110
|
+
* attribute name. Determinism guarantees that identical conditions across
|
|
1111
|
+
* different stylesheets resolve to the same attribute (and therefore share
|
|
1112
|
+
* the same MQL via the upstream `mqlByMedia` dedupe).
|
|
1113
|
+
*/ function attrNameForCondition(condition) {
|
|
1114
|
+
let hash = 2166136261;
|
|
1115
|
+
for(let i = 0; i < condition.length; i++){
|
|
1116
|
+
hash ^= condition.charCodeAt(i);
|
|
1117
|
+
hash = Math.imul(hash, 16777619);
|
|
1118
|
+
}
|
|
1119
|
+
return "data-q-bp-" + (hash >>> 0).toString(36);
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* Builds the list of html-subject style rules from `rules`, with
|
|
1123
|
+
* `:where([attr])` appended to each html-subject selector. Returns one
|
|
1124
|
+
* fully-formed style rule per entry — the caller decides whether to wrap
|
|
1125
|
+
* them in a shared `@media` or insert them individually, since
|
|
1126
|
+
* `insertRule()` only accepts a single top-level rule per call.
|
|
1127
|
+
*
|
|
1128
|
+
* Rules with mixed selector lists are split — only the html-subject half is
|
|
1129
|
+
* emitted here; the descendant half is already covered by the surrounding
|
|
1130
|
+
* @container block. `:where()` contributes 0 specificity.
|
|
1131
|
+
*
|
|
1132
|
+
* Nested grouping rules (e.g. an inner `@supports`) are intentionally not
|
|
1133
|
+
* walked: the original CSS is re-emitted verbatim inside the @container, so
|
|
1134
|
+
* html-subject rules in nested groups still no-op acceptably and a deeper
|
|
1135
|
+
* walk would risk double-applying styles.
|
|
1136
|
+
*/ function collectHtmlSubjectInnerCss(rules, attr) {
|
|
1137
|
+
const parts = [];
|
|
1138
|
+
for (const rule of rules){
|
|
1139
|
+
if (rule instanceof CSSStyleRule) {
|
|
1140
|
+
const htmlSelectors = splitTopLevelCommas(rule.selectorText).filter(isHtmlSubjectSelector).map((s)=>s + ":where([" + attr + "])");
|
|
1141
|
+
if (htmlSelectors.length > 0) {
|
|
1142
|
+
parts.push(htmlSelectors.join(", ") + " { " + rule.style.cssText + " }");
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
return parts;
|
|
1147
|
+
}
|
|
1148
|
+
// ============================================================================
|
|
1149
|
+
// VW Unit Utilities
|
|
1150
|
+
// ============================================================================
|
|
1151
|
+
const VW_UNIT_PATTERN = /(-?\d+(?:\.\d+)?)\s*[dsl]?vw/gi;
|
|
1152
|
+
/**
|
|
1153
|
+
* Checks if CSS text contains vw units.
|
|
1154
|
+
*/ function containsVwUnit(cssText) {
|
|
1155
|
+
VW_UNIT_PATTERN.lastIndex = 0;
|
|
1156
|
+
return VW_UNIT_PATTERN.test(cssText);
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Converts vw units to calc expressions if present.
|
|
1160
|
+
* Returns the original value if no vw units are found.
|
|
1161
|
+
*/ function convertVwUnitsIfPresent(cssText) {
|
|
1162
|
+
let hasMatch = false;
|
|
1163
|
+
const result = cssText.replace(VW_UNIT_PATTERN, (_match, value)=>{
|
|
1164
|
+
hasMatch = true;
|
|
1165
|
+
const decimalValue = parseFloat(value) / 100;
|
|
1166
|
+
return "calc(" + decimalValue + " * var(" + (/* inlined export .DOCKED_VIEWPORT_WIDTH_CSS_VARIABLE */"--qdvw") + "))";
|
|
1167
|
+
});
|
|
1168
|
+
return hasMatch ? result : cssText;
|
|
1169
|
+
}
|
|
1170
|
+
function isCSSRuleParent(rule) {
|
|
1171
|
+
return !!rule && "cssRules" in rule;
|
|
1172
|
+
}
|
|
1173
|
+
/**
|
|
1174
|
+
* True when `el` is anchored near the top of the viewport (so bottom-anchored
|
|
1175
|
+
* sticky bars/CTAs are ignored) AND is not so tall that treating it as a header
|
|
1176
|
+
* would shove the widget off-screen (guards full-height hero banners that happen
|
|
1177
|
+
* to use `<header>`/`role="banner"`). Used as the `isValid` predicate for the
|
|
1178
|
+
* header-tracking {@link BoundingBoxObserver}.
|
|
1179
|
+
*/ function isPinnedToTop(el) {
|
|
1180
|
+
const { top, height } = el.getBoundingClientRect();
|
|
1181
|
+
return top <= window.innerHeight * 0.25 && height <= window.innerHeight * 0.5;
|
|
1182
|
+
}
|
|
1183
|
+
function createHeaderObserver() {
|
|
1184
|
+
return new BoundingBoxObserver({
|
|
1185
|
+
selector: PINNED_HEADER_SELECTOR,
|
|
1186
|
+
property: "bottom",
|
|
1187
|
+
isValid: isPinnedToTop,
|
|
1188
|
+
skipShadowRoot: isQualifiedOwnedShadowRoot,
|
|
1189
|
+
onBBoxChange: (rect)=>{
|
|
1190
|
+
const root = document.documentElement;
|
|
1191
|
+
if (rect === null) {
|
|
1192
|
+
root.style.removeProperty(DOCKED_TOP_OFFSET_CSS_VARIABLE);
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
root.style.setProperty(DOCKED_TOP_OFFSET_CSS_VARIABLE, "" + Math.max(0, Math.round(rect.bottom)) + "px");
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
var viewport_resize_STYLESHEET_LINK_SELECTOR = /* unused export */ undefined;
|
|
1201
|
+
var viewport_resize_linkAppliesStylesheet = /* unused export */ undefined;
|
|
1202
|
+
var viewport_resize_linkIsPreloadStyle = /* unused export */ undefined;
|
|
1203
|
+
export { DOCKED_RIGHT_OFFSET_CSS_VARIABLE, DOCKED_WIDTH_PX, createViewportResize, viewport_resize_STYLESHEET_LINK_SELECTOR as STYLESHEET_LINK_SELECTOR, viewport_resize_linkAppliesStylesheet as linkAppliesStylesheet, viewport_resize_linkIsPreloadStyle as linkIsPreloadStyle };
|