@designcrowd/library.brand-page 6.2.11 → 6.2.12
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/lib/src/{CreatedOnBrandCrowd-de-de-DDcraD5S.js → CreatedOnBrandCrowd-de-de-BtVKllNQ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-DtOeaisf.js → CreatedOnBrandCrowd-en-us-CX5V0v8u.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-BZpmJPew.js → CreatedOnBrandCrowd-es-es-CbA02PCL.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-CqRwC4e7.js → CreatedOnBrandCrowd-fr-ca-BQAKruBF.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-CqRwC4e7.js → CreatedOnBrandCrowd-fr-fr-BQAKruBF.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-DId9Dfjh.js → CreatedOnBrandCrowd-pt-br-Yk_yzB3s.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-DId9Dfjh.js → CreatedOnBrandCrowd-pt-pt-Yk_yzB3s.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-BTDfmOcm.js → CreatedOnDcom-de-de-DJZQbPSD.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-CeAu9Ayx.js → CreatedOnDcom-en-us-BJvNAa4l.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-WCv0K41H.js → CreatedOnDcom-es-es-CUwB1FRY.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-BlfevQDY.js → CreatedOnDcom-fr-ca-CK54U4oh.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-Cvt7MHPZ.js → CreatedOnDcom-fr-fr-DuUNBGrM.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-DipZuylv.js → CreatedOnDcom-pt-br-BfODpFNV.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-BCw4lcKN.js → CreatedOnDcom-pt-pt-Cf6u2GCg.js} +1 -1
- package/lib/src/brand-page/__fixtures__/production-text-style-resolver.fixture.d.ts +16 -0
- package/lib/src/brand-page/__fixtures__/production-text-style-resolver.fixture.js +35 -0
- package/lib/src/brand-page/components/contact-form/ContactForm.mixin.d.ts +3 -0
- package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +19 -13
- package/lib/src/brand-page/components/mailing-list/MailingList.mixin.d.ts +3 -1
- package/lib/src/brand-page/components/mailing-list/MailingList.mixin.js +17 -2
- package/lib/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.d.ts +11 -3
- package/lib/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.js +35 -1
- package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.d.ts +8 -2
- package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.js +27 -3
- package/lib/src/brand-page/components/page/Page.mixin.d.ts +5 -2
- package/lib/src/brand-page/components/page/Page.mixin.js +33 -27
- package/lib/src/brand-page/components/page-footer/PageFooter.mixin.d.ts +7 -2
- package/lib/src/brand-page/components/page-footer/PageFooter.mixin.js +21 -1
- package/lib/src/brand-page/components/payment/Payment.mixin.d.ts +5 -2
- package/lib/src/brand-page/components/payment/Payment.mixin.js +22 -2
- package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.d.ts +6 -2
- package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.js +32 -1
- package/lib/src/brand-page/components/social-links/SocialLinks.stories.js +0 -3
- package/lib/src/brand-page/components/testimonial-section/__fixtures__/data.js +0 -3
- package/lib/src/brand-page/components/text/Text.stories.js +0 -17
- package/lib/src/brand-page/constants/font.constants.d.ts +62 -0
- package/lib/src/brand-page/constants/font.constants.js +35 -0
- package/lib/src/brand-page/models/index.d.ts +23 -24
- package/lib/src/brand-page/models/index.js +20 -7
- package/lib/src/brand-page/models/navigation-styles.model.d.ts +1 -1
- package/lib/src/brand-page/models/navigation-styles.model.js +17 -8
- package/lib/src/brand-page/models/payment.model.d.ts +11 -6
- package/lib/src/brand-page/models/styles.model.d.ts +53 -7
- package/lib/src/brand-page/models/styles.model.js +115 -27
- package/lib/src/brand-page/utils/color-palette.util.d.ts +43 -23
- package/lib/src/brand-page/utils/color-palette.util.js +65 -27
- package/lib/src/brand-page/utils/color.util.d.ts +13 -9
- package/lib/src/brand-page/utils/color.util.js +56 -15
- package/lib/src/brand-page/utils/container-text-color.util.d.ts +46 -13
- package/lib/src/brand-page/utils/container-text-color.util.js +321 -41
- package/lib/src/brand-page/utils/index.d.ts +1 -0
- package/lib/src/brand-page/utils/index.js +1 -0
- package/lib/src/brand-page/utils/migration/migration-20.js +6 -2
- package/lib/src/brand-page/utils/migration/migration-21.js +34 -6
- package/lib/src/brand-page/utils/migration/migration-22.d.ts +99 -0
- package/lib/src/brand-page/utils/migration/migration-22.js +909 -0
- package/lib/src/brand-page/utils/migration.util.js +17 -0
- package/lib/src/brand-page/utils/model.util.d.ts +4 -0
- package/lib/src/brand-page/utils/model.util.js +4 -0
- package/lib/src/brand-page/utils/personalisation.util.js +9 -1
- package/lib/src/brand-page/utils/rte-role-lift.util.d.ts +72 -0
- package/lib/src/brand-page/utils/rte-role-lift.util.js +275 -0
- package/lib/src/brand-page/utils/style.util.d.ts +5 -1
- package/lib/src/brand-page/utils/style.util.js +34 -11
- package/lib/src/brand-page/utils/text-role-css.util.d.ts +19 -0
- package/lib/src/brand-page/utils/text-role-css.util.js +186 -0
- package/lib/src/brand-page/utils/text-role-reconnect.util.d.ts +90 -0
- package/lib/src/brand-page/utils/text-role-reconnect.util.js +434 -0
- package/lib/src/brand-page/utils/text-style.util.d.ts +53 -23
- package/lib/src/brand-page/utils/text-style.util.js +122 -22
- package/lib/src/brand-page/utils/view-model.util.d.ts +9 -1
- package/lib/src/brand-page/utils/view-model.util.js +124 -111
- package/lib/src/brand-page/view-models.d.ts +1 -0
- package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +4 -1
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +13 -2
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +4 -4
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +4 -1
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -10
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.js +0 -1
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +23 -138
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.js +0 -28
- package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +4 -1
- package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +1 -1
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +5 -2
- package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +4 -1
- package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +4 -1
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +4 -1
- package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +1 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.d.ts +16 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.js +61 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.d.ts +11 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.js +236 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/font.d.ts +2 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/font.js +25 -6
- package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.d.ts +17 -4
- package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.js +204 -17
- package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.js +29 -31
- package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.d.ts +20 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.js +60 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.d.ts +2 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.js +22 -6
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +10 -4
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +319 -275
- package/lib/src/brand-page-maker/constants/config-settings-constant.js +1 -5
- package/lib/src/brand-page-maker/convertors/text-css-style-options.convertor.js +6 -2
- package/lib/src/brand-page-maker/convertors/text-size-value.convertor.d.ts +1 -1
- package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
- package/lib/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.js +7 -14
- package/lib/src/brand-page-maker/default-getters/text-color.default-getter.js +6 -13
- package/lib/src/brand-page-maker/models/content-settings.d.ts +8 -0
- package/lib/src/brand-page-maker/models/content-settings.js +112 -81
- package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.d.ts +2 -2
- package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.js +5 -2
- package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.js +4 -3
- package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +1257 -117
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +6 -1
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +17 -9
- package/lib/src/brand-page-maker/stores/history/history-store.d.ts +59 -5
- package/lib/src/brand-page-maker/stores/history/history-store.js +22 -2
- package/lib/src/brand-page-maker/utils/apply-color-strategy.js +26 -8
- package/lib/src/brand-page-maker/utils/index.d.ts +2 -1
- package/lib/src/brand-page-maker/utils/index.js +2 -1
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +117 -15
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +435 -281
- package/lib/src/brand-page-maker/utils/rte-authoring.util.d.ts +4 -0
- package/lib/src/brand-page-maker/utils/rte-authoring.util.js +101 -0
- package/lib/src/brand-page-maker/utils/rte-clipboard.util.d.ts +126 -0
- package/lib/src/brand-page-maker/utils/rte-clipboard.util.js +307 -0
- package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +13 -3
- package/lib/src/{bundled-translations-zfiA5Tsw.js → bundled-translations-yGrvPE5i.js} +17 -17
- package/lib/src/{bundled-translations.de-DE-ChsdSyAP.js → bundled-translations.de-DE-L4Znf8Hs.js} +17 -17
- package/lib/src/{bundled-translations.es-ES-DflsWQK0.js → bundled-translations.es-ES-D6iticrK.js} +15 -15
- package/lib/src/{bundled-translations.fr-CA-fpDRuZ52.js → bundled-translations.fr-CA-BgAVE-9k.js} +25 -25
- package/lib/src/{bundled-translations.fr-FR-Bub73Zt-.js → bundled-translations.fr-FR-B8GbyqxQ.js} +17 -17
- package/lib/src/{bundled-translations.pt-BR-BlnWE9TB.js → bundled-translations.pt-BR-DjPU3Db7.js} +25 -25
- package/lib/src/{bundled-translations.pt-PT-DmzXlnaS.js → bundled-translations.pt-PT-BaepaDpr.js} +23 -23
- package/lib/src/bundles/bundled-translations.de-DE.json +21 -2
- package/lib/src/bundles/bundled-translations.es-ES.json +21 -2
- package/lib/src/bundles/bundled-translations.fr-CA.json +21 -2
- package/lib/src/bundles/bundled-translations.fr-FR.json +21 -2
- package/lib/src/bundles/bundled-translations.json +21 -2
- package/lib/src/bundles/bundled-translations.pt-BR.json +21 -2
- package/lib/src/bundles/bundled-translations.pt-PT.json +21 -2
- package/lib/src/clients/ai-assistant-client.d.ts +1 -0
- package/lib/src/composables/useTranslate.d.ts +1 -1
- package/lib/src/composables/useTranslate.js +1 -1
- package/lib/src/css/library.brand-page-brandCrowd.min.css +303 -207
- package/lib/src/css/library.brand-page-brandPage.min.css +303 -207
- package/lib/src/css/library.brand-page-designCom.min.css +303 -207
- package/lib/src/css/library.brand-page-preview.min.css +303 -207
- package/lib/src/index.d.ts +2 -1
- package/lib/src/index.mjs +195 -191
- package/lib/src/{lib-1AqtEmvQ.js → lib-kGRlD3_P.js} +36855 -33893
- package/lib/src/lib.js +2 -1
- package/lib/src/metadata-builder/builders/footer-builder.js +4 -5
- package/lib/src/metadata-builder/builders/global-role-propagation.d.ts +58 -0
- package/lib/src/metadata-builder/builders/global-role-propagation.js +246 -0
- package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +1 -0
- package/lib/src/metadata-builder/builders/global-styles-builder.js +116 -45
- package/lib/src/metadata-builder/builders/header-builder.js +13 -4
- package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +3 -3
- package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +3 -3
- package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +3 -3
- package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +4 -4
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +3 -3
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +2 -2
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +2 -2
- package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +4 -4
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +3 -3
- package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +8 -2
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +2 -2
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +60 -29
- package/lib/src/metadata-builder/builders/section-field-maps.js +1 -0
- package/lib/src/metadata-builder/builders/section-field-utils.d.ts +48 -19
- package/lib/src/metadata-builder/builders/section-field-utils.js +128 -52
- package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +4 -2
- package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +28 -12
- package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +5 -1
- package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +1 -1
- package/lib/src/metadata-builder/helpers/rte.helpers.js +97 -40
- package/lib/src/metadata-builder/metadata-executor.js +23 -1
- package/lib/src/metadata-builder/models.d.ts +2 -0
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +18 -19
- package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +18 -1
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +1 -1
- package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +0 -1
- package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +5 -8
- package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +7 -16
- package/lib/src/metadata-builder/sanitizers/section-args-validator.js +95 -22
- package/lib/src/shared/color-palette/section-color-matches.js +9 -25
- package/lib/src/shared/color-strategies/color-strategies.d.ts +15 -0
- package/lib/src/shared/color-strategies/color-strategies.js +31 -0
- package/lib/src/shared/color-strategies/rte-color.d.ts +8 -0
- package/lib/src/shared/color-strategies/rte-color.js +16 -0
- package/lib/src/shared/color-strategies/rte-field-pairs.d.ts +23 -0
- package/lib/src/shared/color-strategies/rte-field-pairs.js +28 -0
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +9 -135
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +1 -27
- package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +12 -2
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +7 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +75 -6
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +18 -7
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +6 -1
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +0 -7
- package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +1 -0
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +8 -4
- package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +1255 -26
- package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.js +203 -59
- package/lib/src/shared/content-settings/store/content-settings-store.d.ts +6 -0
- package/lib/src/shared/content-settings/store/content-settings-store.js +105 -8
- package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +5 -1
- package/lib/src/shared/navigation-style-settings/store/index.d.ts +7 -3
- package/lib/src/shared/navigation-style-settings/store/index.js +40 -15
- package/lib/src/shared/page-settings/components/delete-page-modal/DeletePageModal.mixin.d.ts +1 -1
- package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.d.ts +1 -0
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +17 -5
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +70 -13
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +10 -2
- package/lib/src/shared/page-settings/store/page-settings-store.d.ts +2 -1
- package/lib/src/shared/page-settings/store/page-settings-store.js +17 -0
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +4 -1
- package/lib/src/shared/rte-extensions/AutoLink.d.ts +17 -0
- package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.js +67 -51
- package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.js +4 -1
- package/lib/src/shared/rte-extensions/TextEffects.d.ts +28 -0
- package/lib/src/shared/rte-extensions/TextEffects.js +96 -0
- package/lib/src/shared/rte-extensions/ViewDomParser.d.ts +2 -0
- package/lib/src/shared/rte-extensions/ViewDomParser.js +21 -0
- package/lib/src/shared/rte-extensions.util.d.ts +25 -0
- package/lib/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.js → shared/rte-extensions.util.js} +62 -7
- package/lib/src/shared/rte-link.util.d.ts +1 -0
- package/lib/src/shared/rte-link.util.js +1 -0
- package/lib/src/shared/rte-render.util.d.ts +112 -0
- package/lib/src/shared/rte-render.util.js +255 -0
- package/lib/src/shared/rte-shape.util.d.ts +6 -0
- package/lib/src/shared/rte-shape.util.js +18 -0
- package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +2 -1
- package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +1 -0
- package/lib/src/shared/side-bar/store/side-bar-store.d.ts +2 -0
- package/lib/src/shared/side-bar/store/side-bar-store.js +9 -0
- package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +155 -15
- package/lib/src/shared/style-settings/components/StyleSettings.mixin.js +7 -1
- package/lib/src/shared/style-settings/store/style-settings-store.d.ts +1 -9
- package/lib/src/shared/style-settings/store/style-settings-store.js +3 -33
- package/lib/src/shared/style-settings/text-style-size-order.d.ts +2 -0
- package/lib/src/shared/style-settings/text-style-size-order.js +13 -0
- package/lib/src/shared/text-role-typography.util.d.ts +64 -0
- package/lib/src/shared/text-role-typography.util.js +183 -0
- package/lib/src/utils/minify-brand-page-metadata.d.ts +16 -1
- package/lib/src/utils/minify-brand-page-metadata.js +31 -9
- package/package.json +1 -1
- package/src/brand-page/__fixtures__/migration-22-v21/edited-brandsite-sections.v21.json +982 -0
- package/src/brand-page/__fixtures__/migration-22-v21/new-brandcontact-every-section.v21.json +1231 -0
- package/src/brand-page/__fixtures__/migration-22-v21/new-brandpage-every-section.v21.json +1231 -0
- package/src/brand-page/__fixtures__/migration-22-v21/new-brandsite-every-section.v21.json +1243 -0
- package/src/brand-page/__fixtures__/migration-22-v21/real-brandcontact.v21.json +755 -0
- package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-general-link.v21.json +527 -0
- package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-links.v21.json +755 -0
- package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-social-links.v21.json +514 -0
- package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-about.v21.json +459 -0
- package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-footer.v21.json +469 -0
- package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-header-banner.v21.json +481 -0
- package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-sections.v21.json +800 -0
- package/src/brand-page/__fixtures__/production-text-style-resolver.fixture.ts +52 -0
- package/src/brand-page/components/about-section/AboutSection.vue.test.ts +0 -10
- package/src/brand-page/components/contact-form/ContactForm.mixin.test.ts +127 -0
- package/src/brand-page/components/contact-form/ContactForm.mixin.ts +31 -14
- package/src/brand-page/components/contact-form/ContactForm.vue +26 -12
- package/src/brand-page/components/contact-form/ContactForm.vue.test.ts +60 -0
- package/src/brand-page/components/mailing-list/MailingList.mixin.test.ts +92 -0
- package/src/brand-page/components/mailing-list/MailingList.mixin.ts +28 -3
- package/src/brand-page/components/mailing-list/MailingList.vue +9 -4
- package/src/brand-page/components/mailing-list/MailingList.vue.test.ts +63 -0
- package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.ts +51 -1
- package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.test.ts +114 -0
- package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.vue +8 -2
- package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.test.ts +182 -0
- package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.vue +59 -12
- package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +40 -3
- package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue +15 -7
- package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue.test.ts +133 -3
- package/src/brand-page/components/page/Page.mixin.ts +41 -34
- package/src/brand-page/components/page/Page.vue +17 -6
- package/src/brand-page/components/page/Page.vue.test.ts +91 -1
- package/src/brand-page/components/page-footer/PageFooter.mixin.ts +32 -2
- package/src/brand-page/components/page-footer/PageFooter.test.ts +79 -0
- package/src/brand-page/components/page-footer/PageFooter.vue +12 -4
- package/src/brand-page/components/payment/Payment.mixin.ts +34 -2
- package/src/brand-page/components/payment/Payment.test.ts +188 -0
- package/src/brand-page/components/payment/Payment.vue +12 -5
- package/src/brand-page/components/payment/RequestPaymentStripe.vue +1 -0
- package/src/brand-page/components/payment/support-me/SupportMe.mixin.ts +49 -2
- package/src/brand-page/components/payment/support-me/SupportMe.test.ts +100 -0
- package/src/brand-page/components/payment/support-me/SupportMe.vue +7 -1
- package/src/brand-page/components/payment/support-me/SupportMe.vue.test.ts +66 -0
- package/src/brand-page/components/save-contact/SaveContactWidget.test.ts +100 -0
- package/src/brand-page/components/save-contact/SaveContactWidget.vue +6 -3
- package/src/brand-page/components/shop/PaymentModal.vue +2 -6
- package/src/brand-page/components/shop/PaymentShippingAddress.vue +6 -0
- package/src/brand-page/components/shop/Shop.vue +15 -2
- package/src/brand-page/components/shop/Shop.vue.test.ts +74 -2
- package/src/brand-page/components/social-links/SocialLinks.stories.ts +0 -3
- package/src/brand-page/components/social-links/SocialLinks.vue.test.ts +0 -3
- package/src/brand-page/components/testimonial-section/__fixtures__/data.ts +0 -3
- package/src/brand-page/components/text/Text.stories.ts +0 -17
- package/src/brand-page/components/text-wrapper/TextWrapper.parity.test.ts +136 -0
- package/src/brand-page/components/text-wrapper/TextWrapper.test.ts +358 -0
- package/src/brand-page/components/text-wrapper/TextWrapper.vue +82 -22
- package/src/brand-page/constants/font.constants.ts +37 -0
- package/src/brand-page/models/footer-icon-color.test.ts +22 -0
- package/src/brand-page/models/index.ts +50 -28
- package/src/brand-page/models/navigation-styles.model.test.ts +77 -1
- package/src/brand-page/models/navigation-styles.model.ts +26 -9
- package/src/brand-page/models/payment.model.ts +15 -6
- package/src/brand-page/models/styles.model.test.ts +104 -0
- package/src/brand-page/models/styles.model.ts +181 -47
- package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +619 -115
- package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +150 -9
- package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +300 -18
- package/src/brand-page/utils/color-palette.util.test.ts +126 -1
- package/src/brand-page/utils/color-palette.util.ts +92 -26
- package/src/brand-page/utils/color.util.test.ts +62 -29
- package/src/brand-page/utils/color.util.ts +77 -14
- package/src/brand-page/utils/container-text-color.util.test.ts +672 -26
- package/src/brand-page/utils/container-text-color.util.ts +472 -46
- package/src/brand-page/utils/index.ts +1 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/edited-brandsite-sections.v22.json +1191 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandcontact-every-section.v22.json +2026 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandpage-every-section.v22.json +2017 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandsite-every-section.v22.json +2031 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandcontact.v22.json +1145 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-general-link.v22.json +645 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-links.v22.json +1136 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-social-links.v22.json +662 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-about.v22.json +638 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-footer.v22.json +610 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-header-banner.v22.json +660 -0
- package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-sections.v22.json +1132 -0
- package/src/brand-page/utils/migration/migration-01.ts +293 -237
- package/src/brand-page/utils/migration/migration-02.ts +8 -1
- package/src/brand-page/utils/migration/migration-20.ts +6 -3
- package/src/brand-page/utils/migration/migration-20_5.test.ts +5 -2
- package/src/brand-page/utils/migration/migration-21.test.ts +34 -0
- package/src/brand-page/utils/migration/migration-21.ts +46 -10
- package/src/brand-page/utils/migration/migration-22.fixed-input.test.ts +43 -0
- package/src/brand-page/utils/migration/migration-22.test.ts +4103 -0
- package/src/brand-page/utils/migration/migration-22.text-font-family.test.ts +72 -0
- package/src/brand-page/utils/migration/migration-22.ts +1336 -0
- package/src/brand-page/utils/migration.util.test.ts +146 -32
- package/src/brand-page/utils/migration.util.ts +18 -0
- package/src/brand-page/utils/model.util.ts +4 -0
- package/src/brand-page/utils/personalisation.util.test.ts +148 -3
- package/src/brand-page/utils/personalisation.util.ts +9 -1
- package/src/brand-page/utils/rte-role-lift.util.ts +409 -0
- package/src/brand-page/utils/style.util.test.ts +35 -2
- package/src/brand-page/utils/style.util.ts +45 -11
- package/src/brand-page/utils/text-role-css.util.test.ts +525 -0
- package/src/brand-page/utils/text-role-css.util.ts +321 -0
- package/src/brand-page/utils/text-role-reconnect.util.test.ts +604 -0
- package/src/brand-page/utils/text-role-reconnect.util.ts +727 -0
- package/src/brand-page/utils/text-style.util.test.ts +305 -0
- package/src/brand-page/utils/text-style.util.ts +198 -24
- package/src/brand-page/utils/view-model.page-data.test.ts +232 -0
- package/src/brand-page/utils/view-model.util.test.ts +954 -133
- package/src/brand-page/utils/view-model.util.ts +187 -139
- package/src/brand-page/view-models.ts +4 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.blank-site.test.ts +57 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +9 -5
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -10
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.ts +0 -1
- package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.ts +0 -44
- package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +253 -200
- package/src/brand-page-maker/components/shop/AddOrEditProductContainer.vue +1 -0
- package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +1 -0
- package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +2 -0
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +1 -0
- package/src/brand-page-maker/composables/rich-text-editor/block-typography.test.ts +519 -0
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +1 -1
- package/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.test.ts +26 -1
- package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.test.ts +110 -0
- package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.ts +99 -0
- package/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.ts +397 -0
- package/src/brand-page-maker/composables/rich-text-editor/extensions/ViewDomParser.test.ts +139 -0
- package/src/brand-page-maker/composables/rich-text-editor/font.ts +36 -5
- package/src/brand-page-maker/composables/rich-text-editor/formatting.test.ts +375 -1
- package/src/brand-page-maker/composables/rich-text-editor/formatting.ts +301 -17
- package/src/brand-page-maker/composables/rich-text-editor/hyperlink.test.ts +82 -1
- package/src/brand-page-maker/composables/rich-text-editor/hyperlink.ts +28 -34
- package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.test.ts +80 -0
- package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.ts +75 -0
- package/src/brand-page-maker/composables/rich-text-editor/spacing.ts +31 -6
- package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.test.ts +2485 -0
- package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +435 -337
- package/src/brand-page-maker/constants/config-settings-constant.ts +0 -6
- package/src/brand-page-maker/convertors/text-css-style-options.convertor.test.ts +43 -0
- package/src/brand-page-maker/convertors/text-css-style-options.convertor.ts +6 -2
- package/src/brand-page-maker/convertors/text-size-value.convertor.test.ts +24 -0
- package/src/brand-page-maker/convertors/text-size-value.convertor.ts +17 -13
- package/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.ts +7 -22
- package/src/brand-page-maker/default-getters/text-color.default-getter.ts +5 -21
- package/src/brand-page-maker/models/content-settings.test.ts +708 -0
- package/src/brand-page-maker/models/content-settings.ts +133 -82
- package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.test.ts +63 -1
- package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.ts +16 -3
- package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.test.ts +34 -0
- package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.ts +4 -2
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +185 -1
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +22 -34
- package/src/brand-page-maker/stores/history/history-store.ts +35 -2
- package/src/brand-page-maker/utils/__snapshots__/apply-color-strategy.golden.test.ts.snap +528 -0
- package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +12 -0
- package/src/brand-page-maker/utils/apply-color-strategy.golden.test.ts +2 -0
- package/src/brand-page-maker/utils/apply-color-strategy.test.ts +181 -3
- package/src/brand-page-maker/utils/apply-color-strategy.ts +36 -4
- package/src/brand-page-maker/utils/index.ts +2 -1
- package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +447 -410
- package/src/brand-page-maker/utils/rich-text-editor.util.ts +610 -506
- package/src/brand-page-maker/utils/rte-authoring.util.test.ts +244 -0
- package/src/brand-page-maker/utils/rte-authoring.util.ts +175 -0
- package/src/brand-page-maker/utils/rte-clipboard.util.test.ts +558 -0
- package/src/brand-page-maker/utils/rte-clipboard.util.ts +473 -0
- package/src/brand-page-maker/utils/rte-features.test.ts +99 -3
- package/src/brand-page-maker/utils/rte-render-parity.test.ts +1 -1
- package/src/brand-page-maker/utils/rte-render.util.test.ts +230 -0
- package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +1 -1
- package/src/brand-page-maker/utils/rte-sanitize.util.ts +14 -3
- package/src/brand-page-maker/utils/rte-schema-version.test.ts +102 -0
- package/src/bundles/bundled-translations.de-DE.json +21 -2
- package/src/bundles/bundled-translations.es-ES.json +21 -2
- package/src/bundles/bundled-translations.fr-CA.json +21 -2
- package/src/bundles/bundled-translations.fr-FR.json +21 -2
- package/src/bundles/bundled-translations.json +21 -2
- package/src/bundles/bundled-translations.pt-BR.json +21 -2
- package/src/bundles/bundled-translations.pt-PT.json +21 -2
- package/src/clients/ai-assistant-client.ts +1 -0
- package/src/composables/useTranslate.ts +2 -1
- package/src/lib.ts +2 -2
- package/src/metadata-builder/builders/footer-builder.test.ts +70 -45
- package/src/metadata-builder/builders/footer-builder.ts +4 -8
- package/src/metadata-builder/builders/global-role-propagation.test.ts +907 -0
- package/src/metadata-builder/builders/global-role-propagation.ts +430 -0
- package/src/metadata-builder/builders/global-styles-builder.test.ts +1020 -0
- package/src/metadata-builder/builders/global-styles-builder.ts +194 -48
- package/src/metadata-builder/builders/header-builder.test.ts +112 -40
- package/src/metadata-builder/builders/header-builder.ts +18 -8
- package/src/metadata-builder/builders/section-builders/about-section-builder.ts +5 -3
- package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +5 -3
- package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +5 -3
- package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +7 -4
- package/src/metadata-builder/builders/section-builders/images-section-builder.ts +5 -3
- package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +7 -7
- package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +5 -3
- package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +2 -2
- package/src/metadata-builder/builders/section-builders/social-links-builder.ts +21 -10
- package/src/metadata-builder/builders/section-builders/support-me-builder.test.ts +10 -0
- package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/text-section-builder.ts +111 -61
- package/src/metadata-builder/builders/section-field-maps.ts +1 -0
- package/src/metadata-builder/builders/section-field-utils.test.ts +545 -2
- package/src/metadata-builder/builders/section-field-utils.ts +202 -69
- package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +38 -13
- package/src/metadata-builder/builders/section-rules/social-links.rules.ts +5 -0
- package/src/metadata-builder/helpers/rte.helpers.test.ts +101 -0
- package/src/metadata-builder/helpers/rte.helpers.ts +129 -43
- package/src/metadata-builder/metadata-executor.test.ts +167 -0
- package/src/metadata-builder/metadata-executor.ts +34 -1
- package/src/metadata-builder/models.ts +2 -0
- package/src/metadata-builder/parsers/ai-toolcall-parser.ts +23 -7
- package/src/metadata-builder/parsers/section-tool-arguments.ts +21 -1
- package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +215 -0
- package/src/metadata-builder/sanitizers/rte-schema-check.ts +1 -1
- package/src/metadata-builder/sanitizers/sanitizer-rules.ts +4 -8
- package/src/metadata-builder/sanitizers/section-args-validator.ts +136 -53
- package/src/shared/color-palette/section-color-matches.test.ts +15 -11
- package/src/shared/color-palette/section-color-matches.ts +9 -28
- package/src/shared/color-strategies/color-strategies.ts +35 -0
- package/src/shared/color-strategies/rte-color.test.ts +1 -1
- package/src/shared/color-strategies/rte-color.ts +19 -0
- package/src/shared/color-strategies/rte-field-pairs.test.ts +26 -5
- package/src/shared/color-strategies/rte-field-pairs.ts +33 -0
- package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.test.ts +43 -66
- package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.vue +7 -1
- package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +1 -48
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +33 -7
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.test.ts +128 -1
- package/src/shared/content-settings/components/draggable-item-list/DraggableItemList.vue +1 -0
- package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +0 -6
- package/src/shared/content-settings/components/logo-selection-field/LogoSelection.vue +3 -0
- package/src/shared/content-settings/components/logo-size-field/LogoSizeSlider.vue +3 -0
- package/src/shared/content-settings/components/logo-size-field/LogoSizeSliderField.vue +1 -0
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +1 -0
- package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.test.ts +56 -3
- package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +11 -4
- package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.test.ts +335 -25
- package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.ts +248 -70
- package/src/shared/content-settings/components/text-style-field/TextStyleField.vue +113 -25
- package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.de-DE.json +17 -10
- package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.es-ES.json +17 -10
- package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-CA.json +17 -10
- package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-FR.json +17 -10
- package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.json +8 -1
- package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-BR.json +17 -10
- package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-PT.json +17 -10
- package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.test.ts +141 -0
- package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.vue +136 -0
- package/src/shared/content-settings/store/content-settings-store.test.ts +491 -6
- package/src/shared/content-settings/store/content-settings-store.ts +159 -17
- package/src/shared/logo-settings/components/EditLogoSettings.vue +1 -0
- package/src/shared/logo-settings/components/LogoVariations.vue +1 -0
- package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.vue +1 -0
- package/src/shared/navigation-style-settings/store/index.test.ts +295 -0
- package/src/shared/navigation-style-settings/store/index.ts +65 -15
- package/src/shared/page-settings/components/header-settings-panel/HeaderSettingsPanel.vue +2 -0
- package/src/shared/page-settings/components/page-settings/PageElement.vue +1 -0
- package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.test.ts +44 -4
- package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.vue +13 -4
- package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.navigation.test.ts +89 -0
- package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.text-style.test.ts +91 -0
- package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +14 -2
- package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.vue +2 -0
- package/src/shared/page-settings/store/page-settings-store.text-style.test.ts +84 -0
- package/src/shared/page-settings/store/page-settings-store.ts +30 -1
- package/src/shared/rte-extensions/AutoLink.test.ts +98 -0
- package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.ts +87 -58
- package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.ts +4 -1
- package/src/shared/rte-extensions/TextEffects.ts +151 -0
- package/src/shared/rte-extensions/ViewDomParser.ts +27 -0
- package/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.ts → shared/rte-extensions.util.ts} +66 -9
- package/src/shared/rte-link.util.ts +2 -0
- package/src/shared/rte-render.util.ts +385 -0
- package/src/shared/rte-shape.util.ts +29 -0
- package/src/shared/side-bar/store/side-bar-store.test.ts +27 -1
- package/src/shared/side-bar/store/side-bar-store.ts +11 -0
- package/src/shared/style-settings/components/StyleSettings.mixin.ts +7 -3
- package/src/shared/style-settings/components/StyleSettings.test.ts +116 -0
- package/src/shared/style-settings/components/StyleSettings.vue +75 -25
- package/src/shared/style-settings/components/i18n/style-settings.de-DE.json +32 -20
- package/src/shared/style-settings/components/i18n/style-settings.es-ES.json +32 -20
- package/src/shared/style-settings/components/i18n/style-settings.fr-CA.json +32 -20
- package/src/shared/style-settings/components/i18n/style-settings.fr-FR.json +32 -20
- package/src/shared/style-settings/components/i18n/style-settings.json +13 -3
- package/src/shared/style-settings/components/i18n/style-settings.pt-BR.json +32 -20
- package/src/shared/style-settings/components/i18n/style-settings.pt-PT.json +32 -20
- package/src/shared/style-settings/components/text-style-options-settings-with-state/TextStyleOptionsSettingsWithState.vue +14 -34
- package/src/shared/style-settings/store/style-settings-store.ts +3 -49
- package/src/shared/style-settings/text-style-size-order.test.ts +76 -0
- package/src/shared/style-settings/text-style-size-order.ts +28 -0
- package/src/shared/template-settings/components/TemplatesSettings.vue +4 -0
- package/src/shared/text-role-typography.util.ts +277 -0
- package/src/utils/minify-brand-page-metadata.test.ts +102 -7
- package/src/utils/minify-brand-page-metadata.ts +62 -8
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.d.ts +0 -2
- package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
- package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -63
- package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -106
- package/lib/src/brand-page-maker/utils/rte-shape.d.ts +0 -18
- package/lib/src/brand-page-maker/utils/rte-shape.js +0 -21
- package/lib/src/metadata-builder/builders/global-font-propagation.d.ts +0 -41
- package/lib/src/metadata-builder/builders/global-font-propagation.js +0 -146
- package/src/brand-page-maker/utils/rte-render.util.ts +0 -179
- package/src/brand-page-maker/utils/rte-shape.ts +0 -29
- package/src/metadata-builder/builders/global-font-propagation.test.ts +0 -401
- package/src/metadata-builder/builders/global-font-propagation.ts +0 -238
- package/src/shared/style-settings/components/StyleSettingsSection.vue +0 -8
- /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.d.ts +0 -0
- /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.js +0 -0
- /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.d.ts +0 -0
- /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.js +0 -0
- /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.d.ts +0 -0
- /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.ts +0 -0
- /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.ts +0 -0
|
@@ -1,18 +1,370 @@
|
|
|
1
|
-
import { STYLE_THEME_KEYS, } from '@brand-page';
|
|
1
|
+
import { STYLE_THEME_KEYS, CANONICAL_TEXT_STYLE_TYPES, } from '@brand-page';
|
|
2
2
|
import { collectRteTextColors } from '@shared/color-strategies/rte-color';
|
|
3
|
-
import {
|
|
4
|
-
import { getRenderText } from '@brand-page/utils';
|
|
3
|
+
import { composeTextDecoration, localTextDecoration, roleVarRef, } from '@shared/text-role-typography.util';
|
|
5
4
|
import createDomPurify, {} from 'dompurify';
|
|
6
5
|
import Color from 'color';
|
|
7
|
-
import { isHrefPageId } from '
|
|
8
|
-
import { RTE_SECTION_FIELD_PAIRS, } from '@shared/color-strategies/rte-field-pairs';
|
|
6
|
+
import { isHrefPageId } from '@shared/rte-link.util';
|
|
7
|
+
import { RTE_SECTION_FIELD_PAIRS, PLAIN_TEXT_PAIR_SECTIONS, } from '@shared/color-strategies/rte-field-pairs';
|
|
9
8
|
// Re-exported below so every existing caller keeps importing them from here; they
|
|
10
9
|
// live in a leaf module because this one pulls dompurify at runtime.
|
|
11
|
-
import {
|
|
12
|
-
export {
|
|
13
|
-
|
|
10
|
+
import { getRteJsonPlainText, isRteHtmlString, isTiptapDocument, } from '@shared/rte-shape.util';
|
|
11
|
+
export { getRteJsonPlainText, isRteHtmlString, isTiptapDocument, } from '@shared/rte-shape.util';
|
|
12
|
+
/**
|
|
13
|
+
* BP-5969 (ADR-0019, Option B): a block linked to a CANONICAL role gets its typography
|
|
14
|
+
* from the page-scoped CSS class (`text-role-css.util`), so authoring must NOT bake
|
|
15
|
+
* family/size/spacing/line-height/weight/style/decoration into the marks — a value baked
|
|
16
|
+
* post-migration would pin the block forever (migration-22 never re-runs to strip it).
|
|
17
|
+
* Colour is exempt (it isn't in the class). Legacy/unlinked types have no class, so they
|
|
18
|
+
* still bake inline. Mirrors `TextWrapper`'s canonical-only `roleClass`.
|
|
19
|
+
*/
|
|
20
|
+
export const isCanonicalLinked = (style) => !!style?.textStyleType &&
|
|
21
|
+
CANONICAL_TEXT_STYLE_TYPES.includes(style.textStyleType);
|
|
22
|
+
/** True when a mark value is a role reference (`var(--role-…)`) rather than a literal. */
|
|
23
|
+
export const isRoleVarRef = (value) => typeof value === 'string' && value.startsWith('var(--role-');
|
|
24
|
+
// A prop's CSS "default" keyword that renders identically to the prop being absent — e.g.
|
|
25
|
+
// font-weight:normal == no font-weight. The toolbar writes these literals when a format is
|
|
26
|
+
// toggled OFF (bold→'normal', italic→'normal', underline/strike→'none'); a role that simply
|
|
27
|
+
// omits the prop must still read as equal, so both collapse to '' for the role-equality compare.
|
|
28
|
+
const DEFAULT_EQUIVALENT_VALUE = {
|
|
29
|
+
fontWeight: 'normal',
|
|
30
|
+
fontStyle: 'normal',
|
|
31
|
+
textDecoration: 'none',
|
|
32
|
+
lineHeight: 'normal',
|
|
33
|
+
letterSpacing: 'normal',
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Normalise a typography value for a role-equality compare: quote-strip + trim for fontFamily,
|
|
37
|
+
* trim otherwise, then fold a prop's default keyword (`normal`/`none`) to '' so it matches a role
|
|
38
|
+
* that leaves the prop unset (`'normal'`/`'none'`/absent are the same override-wise).
|
|
39
|
+
*/
|
|
40
|
+
export const normTypographyValue = (key, value) => {
|
|
41
|
+
const trimmed = key === 'fontFamily'
|
|
42
|
+
? (value ?? '').replace(/['"]/g, '').trim()
|
|
43
|
+
: (value ?? '').trim();
|
|
44
|
+
return trimmed === DEFAULT_EQUIVALENT_VALUE[key] ? '' : trimmed;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* BP-5969 — the RTE mark value to write for a typography attr change: the role var (so the run
|
|
48
|
+
* stays linked and follows role edits) when the picked value equals the linked role, else the
|
|
49
|
+
* literal raw override. `roleStyle` undefined (legacy/unlinked block, no role class to resolve a
|
|
50
|
+
* var) → always the literal. The equality test runs at the mutation point, per ADR-0019.
|
|
51
|
+
*/
|
|
52
|
+
export const roleVarOrLiteral = (markAttr, picked, roleStyle) => {
|
|
53
|
+
const ref = roleVarRef(markAttr);
|
|
54
|
+
const roleValue = roleStyle?.[markAttr];
|
|
55
|
+
return ref &&
|
|
56
|
+
typeof roleValue === 'string' &&
|
|
57
|
+
normTypographyValue(markAttr, picked) ===
|
|
58
|
+
normTypographyValue(markAttr, roleValue)
|
|
59
|
+
? ref
|
|
60
|
+
: picked;
|
|
61
|
+
};
|
|
62
|
+
const BLOCK_TYPOGRAPHY_ATTRS = [
|
|
63
|
+
'fontFamily',
|
|
64
|
+
'fontSize',
|
|
65
|
+
'lineHeight',
|
|
66
|
+
'letterSpacing',
|
|
67
|
+
'fontWeight',
|
|
68
|
+
'fontStyle',
|
|
69
|
+
'textDecoration',
|
|
70
|
+
];
|
|
71
|
+
const LINK_TYPOGRAPHY_ATTRS = BLOCK_TYPOGRAPHY_ATTRS.filter((attr) => attr !== 'textDecoration');
|
|
72
|
+
// A link's underline is the link's own look (the toolbar and AutoLink add it), not a
|
|
73
|
+
// typography choice, so it neither lights the asterisk nor joins the block's value.
|
|
74
|
+
const typographyAttrsOf = (node) => node.marks.some((mark) => mark.type.name === 'link')
|
|
75
|
+
? LINK_TYPOGRAPHY_ATTRS
|
|
76
|
+
: BLOCK_TYPOGRAPHY_ATTRS;
|
|
77
|
+
export const LEGACY_TYPOGRAPHY_MARKS = {
|
|
78
|
+
fontWeight: ['bold'],
|
|
79
|
+
fontStyle: ['italic'],
|
|
80
|
+
textDecoration: ['underline', 'strike'],
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* A run's marks without the legacy semantic marks (`<strong>`/`<em>`/`<u>`/`<s>`) that compete with
|
|
84
|
+
* `attrs`. A link keeps its underline, as Reset does (`restoreLinkUnderlines`).
|
|
85
|
+
*/
|
|
86
|
+
export const withoutTypographyMarks = (marks, attrs, isLink) => {
|
|
87
|
+
const dropped = new Set(attrs.flatMap((attr) => LEGACY_TYPOGRAPHY_MARKS[attr] ?? []));
|
|
88
|
+
return marks.filter((mark) => !dropped.has(mark.type) || (isLink && mark.type === 'underline'));
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* One text run's typography: its `textStyle` attrs, falling back to a legacy semantic mark
|
|
92
|
+
* (`<strong>`/`<em>`/`<u>`/`<s>`) for un-migrated / pasted runs (mirrors `formatting.ts` `effective`).
|
|
93
|
+
* An absent attr is undefined — the run inherits the role class.
|
|
94
|
+
*/
|
|
95
|
+
export const runTypography = (node) => {
|
|
96
|
+
const textStyle = node.marks.find((mark) => mark.type.name === 'textStyle');
|
|
97
|
+
const attrOf = (attr) => {
|
|
98
|
+
const value = textStyle?.attrs?.[attr];
|
|
99
|
+
return typeof value === 'string' && value !== '' ? value : undefined;
|
|
100
|
+
};
|
|
101
|
+
const has = (markName) => node.marks.some((mark) => mark.type.name === markName);
|
|
102
|
+
const legacyDecoration = [has('underline') && 'underline', has('strike') && 'line-through']
|
|
103
|
+
.filter(Boolean)
|
|
104
|
+
.join(' ') || undefined;
|
|
105
|
+
return {
|
|
106
|
+
fontFamily: attrOf('fontFamily'),
|
|
107
|
+
fontSize: attrOf('fontSize'),
|
|
108
|
+
lineHeight: attrOf('lineHeight'),
|
|
109
|
+
letterSpacing: attrOf('letterSpacing'),
|
|
110
|
+
fontWeight: attrOf('fontWeight') ?? (has('bold') ? 'bold' : undefined),
|
|
111
|
+
fontStyle: attrOf('fontStyle') ?? (has('italic') ? 'italic' : undefined),
|
|
112
|
+
textDecoration: localTextDecoration(attrOf('textDecoration') ?? legacyDecoration, textStyle?.attrs?.textDecorationReset === true),
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
const isRoleEqualLiteral = (attr, value, role, previousRole) => value !== undefined &&
|
|
116
|
+
!isRoleVarRef(value) &&
|
|
117
|
+
normTypographyValue(attr, attr === 'textDecoration'
|
|
118
|
+
? composeTextDecoration(previousRole?.textDecoration, value)
|
|
119
|
+
: value) === normTypographyValue(attr, role[attr]);
|
|
120
|
+
/**
|
|
121
|
+
* True when any run's typography differs from `role` — the role dropdown's asterisk. Unlike
|
|
122
|
+
* `readBlockTypography`, one bold word counts. Absent attrs and role refs follow the role.
|
|
123
|
+
*/
|
|
124
|
+
export const hasRunTypographyOverride = (editor, role) => {
|
|
125
|
+
let found = false;
|
|
126
|
+
editor.state.doc.descendants((node) => {
|
|
127
|
+
if (found)
|
|
128
|
+
return false;
|
|
129
|
+
if (!node.isText || !node.text)
|
|
130
|
+
return;
|
|
131
|
+
const run = runTypography(node);
|
|
132
|
+
found = typographyAttrsOf(node).some((attr) => run[attr] !== undefined &&
|
|
133
|
+
!isRoleVarRef(run[attr]) &&
|
|
134
|
+
!isRoleEqualLiteral(attr, run[attr], role));
|
|
135
|
+
});
|
|
136
|
+
return found;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* "Apply changes to all", on the live editor: every run value now equal to `role` becomes its
|
|
140
|
+
* `var(--role-*)` ref (or is unset when the role leaves the attr undefined), and the legacy mark it
|
|
141
|
+
* came from is dropped. A value that still differs — a word-level override — stays. Colour and the
|
|
142
|
+
* selection are untouched. The editor twin of `relinkRoleEqualMarks`; the caller runs the chain.
|
|
143
|
+
*/
|
|
144
|
+
export const relinkRoleEqualRunsChain = (editor, role, previousRole) => editor.chain().command(({ tr }) => {
|
|
145
|
+
const { schema } = tr.doc.type;
|
|
146
|
+
const textStyleType = schema.marks.textStyle;
|
|
147
|
+
// Mark steps never shift positions, so walking the pre-edit doc stays valid.
|
|
148
|
+
tr.doc.descendants((node, pos) => {
|
|
149
|
+
if (!node.isText || !node.text)
|
|
150
|
+
return;
|
|
151
|
+
const run = runTypography(node);
|
|
152
|
+
const relinked = typographyAttrsOf(node).filter((attr) => isRoleEqualLiteral(attr, run[attr], role, previousRole));
|
|
153
|
+
if (!relinked.length)
|
|
154
|
+
return;
|
|
155
|
+
const from = pos;
|
|
156
|
+
const to = pos + node.nodeSize;
|
|
157
|
+
const attrs = {
|
|
158
|
+
...node.marks.find((mark) => mark.type === textStyleType)?.attrs,
|
|
159
|
+
};
|
|
160
|
+
relinked.forEach((attr) => {
|
|
161
|
+
attrs[attr] = role[attr] ? roleVarRef(attr) : null;
|
|
162
|
+
if (attr === 'textDecoration')
|
|
163
|
+
attrs.textDecorationReset = null;
|
|
164
|
+
LEGACY_TYPOGRAPHY_MARKS[attr]?.forEach((name) => {
|
|
165
|
+
if (schema.marks[name])
|
|
166
|
+
tr.removeMark(from, to, schema.marks[name]);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
// Attr defaults are '' or null, so any falsy value is empty (as Tiptap's `removeEmptyTextStyle`).
|
|
170
|
+
if (Object.values(attrs).some(Boolean))
|
|
171
|
+
tr.addMark(from, to, textStyleType.create(attrs));
|
|
172
|
+
else
|
|
173
|
+
tr.removeMark(from, to, textStyleType);
|
|
174
|
+
});
|
|
175
|
+
return true;
|
|
176
|
+
});
|
|
177
|
+
/**
|
|
178
|
+
* The block's whole-box typography — what "Apply changes to all" can promote into the role. A prop
|
|
179
|
+
* is included only when UNIFORM across every text run: one bold word has no single value to promote
|
|
180
|
+
* (`hasRunTypographyOverride` still flags it). A role-var ref rides through as the block value; the
|
|
181
|
+
* caller (`getTypographyOverride`) treats it as "linked", not an override.
|
|
182
|
+
*/
|
|
183
|
+
export const readBlockTypography = (editor) => {
|
|
184
|
+
const seen = Object.fromEntries(BLOCK_TYPOGRAPHY_ATTRS.map((attr) => [attr, new Set()]));
|
|
185
|
+
let hasText = false;
|
|
186
|
+
editor.state.doc.descendants((node) => {
|
|
187
|
+
if (!node.isText || !node.text)
|
|
188
|
+
return;
|
|
189
|
+
hasText = true;
|
|
190
|
+
const effective = runTypography(node);
|
|
191
|
+
typographyAttrsOf(node).forEach((attr) => seen[attr].add(effective[attr]));
|
|
192
|
+
});
|
|
193
|
+
if (!hasText)
|
|
194
|
+
return {};
|
|
195
|
+
const typography = {};
|
|
196
|
+
BLOCK_TYPOGRAPHY_ATTRS.forEach((attr) => {
|
|
197
|
+
const value = seen[attr].size === 1
|
|
198
|
+
? [...seen[attr]][0]
|
|
199
|
+
: undefined;
|
|
200
|
+
if (value)
|
|
201
|
+
typography[attr] = value;
|
|
202
|
+
});
|
|
203
|
+
return typography;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* BP-5969 — build the "reset to role" chain for the whole selection: re-link every typography attr
|
|
207
|
+
* the role DEFINES to its `var(--role-*)` token (self-describing, follows future role edits), unset
|
|
208
|
+
* the attrs the role leaves undefined, and clear the legacy semantic marks (bold/italic/underline/
|
|
209
|
+
* strike) that the attr resets don't touch. Returns the un-run chain so the caller can wrap it in
|
|
210
|
+
* `skipStyleDetection` (keeping the role link) before running. Colour marks are left alone.
|
|
211
|
+
*/
|
|
212
|
+
export const relinkTypographyChain = (editor, role) => {
|
|
213
|
+
const chain = editor.chain().selectAll();
|
|
214
|
+
if (role?.fontFamily)
|
|
215
|
+
chain.setFontFamily(roleVarRef('fontFamily'));
|
|
216
|
+
else
|
|
217
|
+
chain.unsetFontFamily();
|
|
218
|
+
if (role?.fontSize)
|
|
219
|
+
chain.setFontSize(roleVarRef('fontSize'));
|
|
220
|
+
else
|
|
221
|
+
chain.unsetFontSize();
|
|
222
|
+
if (role?.lineHeight)
|
|
223
|
+
chain.setLineHeight(roleVarRef('lineHeight'));
|
|
224
|
+
else
|
|
225
|
+
chain.unsetLineHeight();
|
|
226
|
+
if (role?.letterSpacing)
|
|
227
|
+
chain.setLetterSpacing(roleVarRef('letterSpacing'));
|
|
228
|
+
else
|
|
229
|
+
chain.unsetLetterSpacing();
|
|
230
|
+
if (role?.fontWeight)
|
|
231
|
+
chain.setFontWeight(roleVarRef('fontWeight'));
|
|
232
|
+
else
|
|
233
|
+
chain.unsetFontWeight();
|
|
234
|
+
if (role?.fontStyle)
|
|
235
|
+
chain.setFontStyle(roleVarRef('fontStyle'));
|
|
236
|
+
else
|
|
237
|
+
chain.unsetFontStyle();
|
|
238
|
+
if (role?.textDecoration)
|
|
239
|
+
chain.setTextDecoration(roleVarRef('textDecoration'));
|
|
240
|
+
else
|
|
241
|
+
chain.unsetTextDecoration();
|
|
242
|
+
return chain
|
|
243
|
+
.unsetBold()
|
|
244
|
+
.unsetItalic()
|
|
245
|
+
.unsetUnderline()
|
|
246
|
+
.unsetStrike()
|
|
247
|
+
.command(restoreLinkUnderlines(editor));
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* A chain step that puts the underline back on link text that had one before the chain cleared
|
|
251
|
+
* every underline: a link's underline is its own look, not a typography choice (`typographyAttrsOf`).
|
|
252
|
+
* Captures the link ranges now, so build it before the chain changes the doc; mark steps keep
|
|
253
|
+
* positions, so the ranges still hold when it runs.
|
|
254
|
+
*/
|
|
255
|
+
export const restoreLinkUnderlines = (editor) => {
|
|
256
|
+
const ranges = [];
|
|
257
|
+
editor.state.doc.descendants((node, pos) => {
|
|
258
|
+
if (node.isText &&
|
|
259
|
+
node.marks.some((mark) => mark.type.name === 'link') &&
|
|
260
|
+
node.marks.some((mark) => mark.type.name === 'underline'))
|
|
261
|
+
ranges.push([pos, pos + node.nodeSize]);
|
|
262
|
+
});
|
|
263
|
+
return ({ tr }) => {
|
|
264
|
+
const underline = tr.doc.type.schema.marks.underline;
|
|
265
|
+
if (underline)
|
|
266
|
+
ranges.forEach(([from, to]) => tr.addMark(from, to, underline.create()));
|
|
267
|
+
return true;
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* The document-level twin of `relinkTypographyChain`, for a block that isn't being edited: each run's
|
|
272
|
+
* typography literal that equals any of `roles` (a literal the asterisk never counted as an override)
|
|
273
|
+
* becomes the `var(--role-*)` ref when `roles[0]` — the role the block links now — defines the attr,
|
|
274
|
+
* else it's unset. Literals that differ from every role, role refs, colour and link marks are left
|
|
275
|
+
* alone. Returns the same doc when nothing changes.
|
|
276
|
+
*/
|
|
277
|
+
export const relinkRoleEqualMarks = (doc, roles) => {
|
|
278
|
+
const [linkedRole] = roles;
|
|
279
|
+
const clone = JSON.parse(JSON.stringify(doc));
|
|
280
|
+
let changed = false;
|
|
281
|
+
const visit = (node) => {
|
|
282
|
+
const mark = node.marks?.find((m) => m.type === 'textStyle');
|
|
283
|
+
if (mark?.attrs) {
|
|
284
|
+
for (const attr of BLOCK_TYPOGRAPHY_ATTRS) {
|
|
285
|
+
const value = mark.attrs[attr];
|
|
286
|
+
if (typeof value !== 'string' || value === '' || isRoleVarRef(value))
|
|
287
|
+
continue;
|
|
288
|
+
const equalsARole = roles.some((role) => role &&
|
|
289
|
+
normTypographyValue(attr, value) ===
|
|
290
|
+
normTypographyValue(attr, role[attr]));
|
|
291
|
+
if (!equalsARole)
|
|
292
|
+
continue;
|
|
293
|
+
mark.attrs[attr] = linkedRole?.[attr] ? roleVarRef(attr) : null;
|
|
294
|
+
if (attr === 'textDecoration')
|
|
295
|
+
delete mark.attrs.textDecorationReset;
|
|
296
|
+
changed = true;
|
|
297
|
+
}
|
|
298
|
+
if (Object.values(mark.attrs).every((v) => v === null || v === undefined))
|
|
299
|
+
node.marks = node.marks?.filter((m) => m !== mark);
|
|
300
|
+
}
|
|
301
|
+
node.content?.forEach(visit);
|
|
302
|
+
};
|
|
303
|
+
visit(clone);
|
|
304
|
+
return changed ? clone : doc;
|
|
305
|
+
};
|
|
306
|
+
/**
|
|
307
|
+
* BP-5969 (R19) — the stored-document twin of `relinkTypographyChain`'s reset-to-role chain, for a
|
|
308
|
+
* doc that isn't mounted in an editor (the AI boundary's role switch). Unlike `relinkRoleEqualMarks`
|
|
309
|
+
* (which only relinks a literal that already equals a role), every run's typography is reset to
|
|
310
|
+
* `role` — a deliberate accent override included — mirroring the maker's Reset: a `var(--role-*)`
|
|
311
|
+
* ref where `role` defines the attr, else unset. The legacy semantic marks (bold/italic/underline/
|
|
312
|
+
* strike) that the attr resets don't touch are dropped too. Colour and link marks are left alone.
|
|
313
|
+
*
|
|
314
|
+
* `styleOverrides` is the call's own surviving style-object override — e.g. a switch call that
|
|
315
|
+
* also sends `fontFamily: 'Playfair Display'`. Those attrs are nulled, not ref'd: the render fill
|
|
316
|
+
* (`fillRteRunTypography`) treats a non-null mark value as final, so baking the ref here would bury
|
|
317
|
+
* the override under it; nulling leaves the render fill free to resolve the literal from the style
|
|
318
|
+
* object, same as any other block-level override.
|
|
319
|
+
*/
|
|
320
|
+
export const relinkDocToRole = (doc, role, styleOverrides) => {
|
|
321
|
+
const clone = JSON.parse(JSON.stringify(doc));
|
|
322
|
+
const visit = (node) => {
|
|
323
|
+
if (node.type === 'text' && node.marks?.length) {
|
|
324
|
+
const marks = withoutTypographyMarks(node.marks, BLOCK_TYPOGRAPHY_ATTRS, node.marks.some((mark) => mark.type === 'link'));
|
|
325
|
+
const textStyle = marks.find((mark) => mark.type === 'textStyle');
|
|
326
|
+
const attrs = { ...textStyle?.attrs };
|
|
327
|
+
for (const attr of BLOCK_TYPOGRAPHY_ATTRS) {
|
|
328
|
+
const override = styleOverrides?.[attr];
|
|
329
|
+
const isOverridden = typeof override === 'string' &&
|
|
330
|
+
override !== '' &&
|
|
331
|
+
!isRoleVarRef(override);
|
|
332
|
+
attrs[attr] = !isOverridden && role?.[attr] ? roleVarRef(attr) : null;
|
|
333
|
+
}
|
|
334
|
+
delete attrs.textDecorationReset;
|
|
335
|
+
// A mark with no colour and every typography attr null (role undefined, or every attr
|
|
336
|
+
// overridden by a non-role value) carries nothing — drop it rather than leave a no-op
|
|
337
|
+
// `textStyle` mark behind, same as `relinkRoleEqualMarks` above.
|
|
338
|
+
const isEmptyMark = Object.values(attrs).every((v) => v === null || v === undefined);
|
|
339
|
+
if (textStyle) {
|
|
340
|
+
if (isEmptyMark)
|
|
341
|
+
node.marks = marks.filter((m) => m !== textStyle);
|
|
342
|
+
else {
|
|
343
|
+
textStyle.attrs = attrs;
|
|
344
|
+
node.marks = marks;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
else if (!isEmptyMark) {
|
|
348
|
+
marks.push({ type: 'textStyle', attrs });
|
|
349
|
+
node.marks = marks;
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
node.marks = marks;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
node.content?.forEach(visit);
|
|
356
|
+
};
|
|
357
|
+
visit(clone);
|
|
358
|
+
return clone;
|
|
359
|
+
};
|
|
360
|
+
// The sections the maker mounts an RTE editor on. Derived from the pairs map, but the
|
|
361
|
+
// PLAIN_TEXT_PAIR_SECTIONS are excluded: they appear in the map only for the colour strategy's
|
|
362
|
+
// pairing lookup — their title/description are plain strings whose colour lives on `*.style.color`
|
|
363
|
+
// (rendered by TextWrapper's plain path), so mounting an editor would convert them to a Tiptap doc
|
|
364
|
+
// and strand that colour (the doc renders from the mark, which the plain bake never sets).
|
|
365
|
+
// 'text' has special textItems handling, so it's not in the map but is RTE-enabled.
|
|
14
366
|
export const RTE_ALLOWED_SECTION_TYPES = [
|
|
15
|
-
...Object.keys(RTE_SECTION_FIELD_PAIRS),
|
|
367
|
+
...Object.keys(RTE_SECTION_FIELD_PAIRS).filter((type) => !PLAIN_TEXT_PAIR_SECTIONS.has(type)),
|
|
16
368
|
'text',
|
|
17
369
|
];
|
|
18
370
|
export const isRTEManagedStyleField = (sectionType, fieldName) => {
|
|
@@ -135,20 +487,6 @@ export const skipStyleDetection = (chain, marks) => chain.command(({ tr }) => {
|
|
|
135
487
|
}
|
|
136
488
|
return true;
|
|
137
489
|
});
|
|
138
|
-
/**
|
|
139
|
-
* Extract visible plain text from a Tiptap JSON document (concatenated text
|
|
140
|
-
* nodes). Dependency-free — no editor instantiation.
|
|
141
|
-
*/
|
|
142
|
-
export const getRteJsonPlainText = (doc) => {
|
|
143
|
-
const parts = [];
|
|
144
|
-
const walk = (node) => {
|
|
145
|
-
if (typeof node.text === 'string')
|
|
146
|
-
parts.push(node.text);
|
|
147
|
-
node.content?.forEach(walk);
|
|
148
|
-
};
|
|
149
|
-
walk(doc);
|
|
150
|
-
return parts.join(' ').replace(/\s+/g, ' ').trim();
|
|
151
|
-
};
|
|
152
490
|
// True for RTE content in EITHER shape: a Tiptap JSON document (post-migration)
|
|
153
491
|
// or a legacy inline-HTML string (pre-migration, or a not-yet-migrated site).
|
|
154
492
|
export const hasRTEContent = (content) => isTiptapDocument(content) || isRteHtmlString(content);
|
|
@@ -311,280 +649,96 @@ export const replaceTextInRTE = (existingHtml, newText) => {
|
|
|
311
649
|
return tempDiv.innerHTML;
|
|
312
650
|
};
|
|
313
651
|
/**
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
* - **store-driven** (section-select / add-content): only convert genuine plain text, so an
|
|
319
|
-
* already-authored mark (the migration-baked frame colour) is never overwritten on select.
|
|
652
|
+
* Helper to build stored marks from a style declaration. BP-5969: when `bakeTypography`
|
|
653
|
+
* is false (a canonical-role block — the class supplies typography), only colour and
|
|
654
|
+
* highlight are baked; family/size/spacing/line-height/weight/style/decoration are left
|
|
655
|
+
* to the role class so freshly-typed text follows the role and repaints on a role edit.
|
|
320
656
|
*/
|
|
321
|
-
const
|
|
322
|
-
(textStyleType === type ||
|
|
323
|
-
(!!uiStyleSettingsStore && !hasRTEContent(textValue)));
|
|
324
|
-
const transformRTEField = (content, pair, externalEditor, uiStyleSettingsStore, newContent, type, newStyle) => {
|
|
325
|
-
const fields = content;
|
|
326
|
-
const style = fields[pair.styleField];
|
|
327
|
-
const textStyleType = style?.textStyleType;
|
|
328
|
-
if (shouldRewrapRteField(textStyleType, type, uiStyleSettingsStore, fields[pair.textField])) {
|
|
329
|
-
let globalContentStyle = uiStyleSettingsStore
|
|
330
|
-
? uiStyleSettingsStore.textStyles.textStyleOptions[textStyleType].style
|
|
331
|
-
: (newStyle ?? {});
|
|
332
|
-
globalContentStyle = {
|
|
333
|
-
...globalContentStyle,
|
|
334
|
-
textAlign: style?.textAlign,
|
|
335
|
-
// Element-first colour: a creation-time contrast bake (or a colour picked while
|
|
336
|
-
// linked) lives on the style field and must survive the rewrap into rich text.
|
|
337
|
-
// The linked global colour applies only when the element has none — mirroring
|
|
338
|
-
// `resolveTextColor`'s element-first cascade, so the rewrap can't overpaint the
|
|
339
|
-
// override with the global colour.
|
|
340
|
-
color: style?.color || globalContentStyle.color,
|
|
341
|
-
};
|
|
342
|
-
fields[pair.textField] = getUpdatedHTMLFromEditor(externalEditor, fields[pair.textField], globalContentStyle);
|
|
343
|
-
}
|
|
344
|
-
else if (!textStyleType &&
|
|
345
|
-
newContent &&
|
|
346
|
-
newContent.id === content.id &&
|
|
347
|
-
!hasRTEContent(fields[pair.textField])) {
|
|
348
|
-
const newContentFields = newContent;
|
|
349
|
-
const newContentStyle = newContentFields[pair.styleField] ||
|
|
350
|
-
style;
|
|
351
|
-
if (newContentStyle) {
|
|
352
|
-
fields[pair.textField] = getUpdatedHTMLFromEditor(externalEditor, fields[pair.textField], newContentStyle);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
const switchRTEField = (content, pair, externalEditor, uiStyleSettingsStore) => {
|
|
357
|
-
const fields = content;
|
|
358
|
-
const style = fields[pair.styleField];
|
|
359
|
-
const textStyleType = style?.textStyleType;
|
|
360
|
-
if (textStyleType && uiStyleSettingsStore) {
|
|
361
|
-
let globalContentStyle = uiStyleSettingsStore.textStyles.textStyleOptions[textStyleType].style;
|
|
362
|
-
globalContentStyle = {
|
|
363
|
-
...globalContentStyle,
|
|
364
|
-
textAlign: style?.textAlign,
|
|
365
|
-
};
|
|
366
|
-
if (!hasRTEContent(fields[pair.textField]))
|
|
367
|
-
fields[pair.textField] = getUpdatedHTMLFromEditor(externalEditor, fields[pair.textField], globalContentStyle);
|
|
368
|
-
}
|
|
369
|
-
else if (!textStyleType &&
|
|
370
|
-
style &&
|
|
371
|
-
!hasRTEContent(fields[pair.textField])) {
|
|
372
|
-
fields[pair.textField] = getUpdatedHTMLFromEditor(externalEditor, fields[pair.textField], style);
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
export const transformToRTE = (uiPageSettingStore, externalEditor, uiStyleSettingsStore, newContent, type, newStyle) => {
|
|
376
|
-
for (const page of uiPageSettingStore.pages) {
|
|
377
|
-
for (const contentItem of page.contents) {
|
|
378
|
-
const fieldPairs = RTE_SECTION_FIELD_PAIRS[contentItem.type];
|
|
379
|
-
if (fieldPairs) {
|
|
380
|
-
const content = contentItem.settings.content;
|
|
381
|
-
for (const pair of fieldPairs) {
|
|
382
|
-
transformRTEField(content, pair, externalEditor, uiStyleSettingsStore, newContent, type, newStyle);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
if (contentItem.type === 'text') {
|
|
386
|
-
const textContent = contentItem.settings.content;
|
|
387
|
-
if (textContent.textItems && textContent.textItems.length > 0) {
|
|
388
|
-
for (const [itemIndex, textItemContent,] of textContent.textItems.entries()) {
|
|
389
|
-
const textItemStyleType = textItemContent.textStyle.textStyleType;
|
|
390
|
-
if (shouldRewrapRteField(textItemStyleType, type, uiStyleSettingsStore, textItemContent.text)) {
|
|
391
|
-
let globalContentStyle = uiStyleSettingsStore
|
|
392
|
-
? uiStyleSettingsStore.textStyles.textStyleOptions[textItemStyleType].style
|
|
393
|
-
: (newStyle ?? {});
|
|
394
|
-
globalContentStyle = {
|
|
395
|
-
...globalContentStyle,
|
|
396
|
-
textAlign: textItemContent.textStyle.textAlign,
|
|
397
|
-
// Element-first colour — see `transformRTEField`.
|
|
398
|
-
color: textItemContent.textStyle.color || globalContentStyle.color,
|
|
399
|
-
};
|
|
400
|
-
textItemContent.text = getUpdatedHTMLFromEditor(externalEditor, textItemContent.text, globalContentStyle);
|
|
401
|
-
}
|
|
402
|
-
else if (!textItemStyleType &&
|
|
403
|
-
newContent &&
|
|
404
|
-
newContent.id === textContent.id &&
|
|
405
|
-
!hasRTEContent(textItemContent.text)) {
|
|
406
|
-
const newContentStyle = newContent?.textItems?.[itemIndex]
|
|
407
|
-
?.textStyle ?? newContent.textStyle;
|
|
408
|
-
textItemContent.text = getUpdatedHTMLFromEditor(externalEditor, textItemContent.text, newContentStyle);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
if ((!textContent.textItems || textContent.textItems.length === 0) &&
|
|
413
|
-
textContent.textStyle) {
|
|
414
|
-
const textStyleType = textContent.textStyle.textStyleType;
|
|
415
|
-
if (shouldRewrapRteField(textStyleType, type, uiStyleSettingsStore, textContent.text)) {
|
|
416
|
-
let globalContentStyle = uiStyleSettingsStore
|
|
417
|
-
? uiStyleSettingsStore.textStyles.textStyleOptions[textStyleType]
|
|
418
|
-
.style
|
|
419
|
-
: (newStyle ?? {});
|
|
420
|
-
globalContentStyle = {
|
|
421
|
-
...globalContentStyle,
|
|
422
|
-
textAlign: textContent.textStyle.textAlign,
|
|
423
|
-
// Element-first colour — see `transformRTEField`.
|
|
424
|
-
color: textContent.textStyle.color || globalContentStyle.color,
|
|
425
|
-
};
|
|
426
|
-
textContent.text = getUpdatedHTMLFromEditor(externalEditor, textContent.text, globalContentStyle);
|
|
427
|
-
}
|
|
428
|
-
else if (!textStyleType &&
|
|
429
|
-
newContent &&
|
|
430
|
-
newContent.id === textContent.id &&
|
|
431
|
-
!hasRTEContent(textContent.text)) {
|
|
432
|
-
const newContentStyle = newContent.textStyle;
|
|
433
|
-
textContent.text = getUpdatedHTMLFromEditor(externalEditor, textContent.text, newContentStyle);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
};
|
|
440
|
-
export const switchAllContentToRTE = (uiPageSettingStore, externalEditor, uiStyleSettingsStore) => {
|
|
441
|
-
for (const page of uiPageSettingStore.pages) {
|
|
442
|
-
for (const contentItem of page.contents) {
|
|
443
|
-
const fieldPairs = RTE_SECTION_FIELD_PAIRS[contentItem.type];
|
|
444
|
-
if (fieldPairs) {
|
|
445
|
-
const content = contentItem.settings.content;
|
|
446
|
-
for (const pair of fieldPairs) {
|
|
447
|
-
switchRTEField(content, pair, externalEditor, uiStyleSettingsStore);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
if (contentItem.type === 'text') {
|
|
451
|
-
const textContent = contentItem.settings.content;
|
|
452
|
-
if (textContent.textItems && textContent.textItems.length > 0) {
|
|
453
|
-
for (const [_itemIndex, textItemContent,] of textContent.textItems.entries()) {
|
|
454
|
-
const textItemStyleType = textItemContent.textStyle.textStyleType;
|
|
455
|
-
if (textItemStyleType && uiStyleSettingsStore) {
|
|
456
|
-
let globalContentStyle = uiStyleSettingsStore.textStyles
|
|
457
|
-
.textStyleOptions[textItemStyleType]
|
|
458
|
-
.style;
|
|
459
|
-
globalContentStyle = {
|
|
460
|
-
...globalContentStyle,
|
|
461
|
-
textAlign: textItemContent.textStyle.textAlign,
|
|
462
|
-
};
|
|
463
|
-
if (!hasRTEContent(textItemContent.text))
|
|
464
|
-
textItemContent.text = getUpdatedHTMLFromEditor(externalEditor, textItemContent.text, globalContentStyle);
|
|
465
|
-
}
|
|
466
|
-
else if (!textItemStyleType &&
|
|
467
|
-
!hasRTEContent(textItemContent.text)) {
|
|
468
|
-
const newContentStyle = textItemContent.textStyle;
|
|
469
|
-
textItemContent.text = getUpdatedHTMLFromEditor(externalEditor, textItemContent.text, newContentStyle);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
if ((!textContent.textItems || textContent.textItems.length === 0) &&
|
|
474
|
-
textContent.textStyle) {
|
|
475
|
-
const textStyleType = textContent.textStyle.textStyleType;
|
|
476
|
-
if (textStyleType && uiStyleSettingsStore) {
|
|
477
|
-
let globalContentStyle = uiStyleSettingsStore.textStyles
|
|
478
|
-
.textStyleOptions[textStyleType].style;
|
|
479
|
-
globalContentStyle = {
|
|
480
|
-
...globalContentStyle,
|
|
481
|
-
textAlign: textContent.textStyle.textAlign,
|
|
482
|
-
};
|
|
483
|
-
if (!hasRTEContent(textContent.text))
|
|
484
|
-
textContent.text = getUpdatedHTMLFromEditor(externalEditor, textContent.text, globalContentStyle);
|
|
485
|
-
}
|
|
486
|
-
else if (!textStyleType && !hasRTEContent(textContent.text)) {
|
|
487
|
-
const newContentStyle = textContent.textStyle;
|
|
488
|
-
textContent.text = getUpdatedHTMLFromEditor(externalEditor, textContent.text, newContentStyle);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
export const getUpdatedHTMLFromEditor = (externalEditor, contentText, newContentStyle) => {
|
|
496
|
-
if (!contentText) {
|
|
497
|
-
return contentText;
|
|
498
|
-
}
|
|
499
|
-
// BP-5787: accept a string (legacy HTML) or a Tiptap JSON doc. setContent
|
|
500
|
-
// handles both; only the newline-escaping shim applies to strings.
|
|
501
|
-
const content = typeof contentText === 'string' &&
|
|
502
|
-
contentText.includes(ESCAPED_NEWLINE_CHARACTER)
|
|
503
|
-
? getRenderText(contentText)
|
|
504
|
-
: contentText;
|
|
505
|
-
externalEditor.commands.setContent(content);
|
|
506
|
-
const currentAlignment = externalEditor.getAttributes(externalEditor.state.selection.$anchor.node().type.name);
|
|
507
|
-
let chain = externalEditor.chain().selectAll();
|
|
508
|
-
if (newContentStyle?.fontFamily) {
|
|
509
|
-
chain = chain.setFontFamily(newContentStyle.fontFamily);
|
|
510
|
-
}
|
|
511
|
-
if (newContentStyle?.fontSize) {
|
|
512
|
-
chain = chain.setFontSize(newContentStyle.fontSize);
|
|
513
|
-
}
|
|
514
|
-
if (newContentStyle?.letterSpacing) {
|
|
515
|
-
chain = chain.setLetterSpacing(newContentStyle.letterSpacing);
|
|
516
|
-
}
|
|
517
|
-
if (newContentStyle?.lineHeight) {
|
|
518
|
-
chain = chain.setLineHeight(newContentStyle.lineHeight);
|
|
519
|
-
}
|
|
520
|
-
if (newContentStyle?.color) {
|
|
521
|
-
chain = chain.setMark('textStyle', {
|
|
522
|
-
color: getRTEColor(newContentStyle.color, 'text'),
|
|
523
|
-
});
|
|
524
|
-
}
|
|
525
|
-
// Handle backgroundColor
|
|
526
|
-
if ('backgroundColor' in (newContentStyle || {})) {
|
|
527
|
-
chain = newContentStyle.backgroundColor
|
|
528
|
-
? chain.setMark('highlight', {
|
|
529
|
-
color: getRTEColor(newContentStyle.backgroundColor, 'background'),
|
|
530
|
-
})
|
|
531
|
-
: chain.unsetHighlight();
|
|
532
|
-
}
|
|
533
|
-
if (!currentAlignment.textAlign && newContentStyle?.textAlign) {
|
|
534
|
-
chain = chain.setTextAlign(newContentStyle.textAlign);
|
|
535
|
-
}
|
|
536
|
-
const hasStrike = newContentStyle?.textDecoration?.includes('line-through');
|
|
537
|
-
const hasUnderline = newContentStyle?.textDecoration?.includes('underline');
|
|
538
|
-
chain = hasStrike ? chain.setStrike() : chain.unsetStrike();
|
|
539
|
-
chain = hasUnderline ? chain.setUnderline() : chain.unsetUnderline();
|
|
540
|
-
chain =
|
|
541
|
-
newContentStyle?.fontWeight === 'bold'
|
|
542
|
-
? chain.setBold()
|
|
543
|
-
: chain.unsetBold();
|
|
544
|
-
chain = newContentStyle?.fontStyle ? chain.setItalic() : chain.unsetItalic();
|
|
545
|
-
chain.run();
|
|
546
|
-
// BP-5787: return the JSON form, consistent with how RTE is now stored.
|
|
547
|
-
return externalEditor.getJSON();
|
|
548
|
-
};
|
|
549
|
-
// Helper to build stored marks from a style declaration
|
|
550
|
-
export const buildInitialMarks = (state, style) => {
|
|
657
|
+
export const buildInitialMarks = (state, style, bakeTypography = true) => {
|
|
551
658
|
const marks = [];
|
|
552
659
|
const { fontFamily, fontSize, color, lineHeight, letterSpacing, fontWeight, fontStyle, textDecoration, backgroundColor, } = style;
|
|
553
660
|
// TextStyle mark attributes
|
|
554
661
|
const textStyleAttrs = {};
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
662
|
+
// BP-5969: a canonical-linked block (bakeTypography === false) references the role via
|
|
663
|
+
// cascade vars — self-describing marks that follow role edits — instead of baking a
|
|
664
|
+
// literal that would pin the run. Legacy/unlinked bakes the resolved literal as before.
|
|
665
|
+
// `style` here is the role's resolved style, so the guards write a ref only for the attrs
|
|
666
|
+
// the role actually defines.
|
|
667
|
+
if (bakeTypography) {
|
|
668
|
+
if (fontFamily)
|
|
669
|
+
textStyleAttrs.fontFamily = fontFamily;
|
|
670
|
+
if (fontSize)
|
|
671
|
+
textStyleAttrs.fontSize = fontSize;
|
|
672
|
+
if (letterSpacing)
|
|
673
|
+
textStyleAttrs.letterSpacing = letterSpacing;
|
|
674
|
+
if (lineHeight)
|
|
675
|
+
textStyleAttrs.lineHeight = lineHeight;
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
if (fontFamily)
|
|
679
|
+
textStyleAttrs.fontFamily = roleVarRef('fontFamily');
|
|
680
|
+
if (fontSize)
|
|
681
|
+
textStyleAttrs.fontSize = roleVarRef('fontSize');
|
|
682
|
+
if (letterSpacing)
|
|
683
|
+
textStyleAttrs.letterSpacing = roleVarRef('letterSpacing');
|
|
684
|
+
if (lineHeight)
|
|
685
|
+
textStyleAttrs.lineHeight = roleVarRef('lineHeight');
|
|
686
|
+
// BP-5969 (Phase A): weight/style/decoration are var-backed textStyle attrs too, so newly-typed
|
|
687
|
+
// linked text follows the role for these as well (not baked as semantic <strong>/<u> marks).
|
|
688
|
+
if (fontWeight)
|
|
689
|
+
textStyleAttrs.fontWeight = roleVarRef('fontWeight');
|
|
690
|
+
if (fontStyle)
|
|
691
|
+
textStyleAttrs.fontStyle = roleVarRef('fontStyle');
|
|
692
|
+
if (textDecoration)
|
|
693
|
+
textStyleAttrs.textDecoration = roleVarRef('textDecoration');
|
|
694
|
+
}
|
|
559
695
|
if (color) {
|
|
560
696
|
textStyleAttrs.color = getRTEColor(color, 'text');
|
|
561
697
|
}
|
|
562
|
-
if (
|
|
563
|
-
textStyleAttrs
|
|
564
|
-
|
|
565
|
-
textStyleAttrs.lineHeight = lineHeight;
|
|
566
|
-
marks.push(state.schema.marks.textStyle.create(textStyleAttrs));
|
|
698
|
+
if (Object.keys(textStyleAttrs).length > 0) {
|
|
699
|
+
marks.push(state.schema.marks.textStyle.create(textStyleAttrs));
|
|
700
|
+
}
|
|
567
701
|
if (backgroundColor) {
|
|
568
702
|
marks.push(state.schema.marks.highlight.create({
|
|
569
703
|
color: getRTEColor(backgroundColor, 'background'),
|
|
570
704
|
}));
|
|
571
705
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
706
|
+
if (bakeTypography) {
|
|
707
|
+
// Bold and italic
|
|
708
|
+
if (fontWeight === 'bold') {
|
|
709
|
+
marks.push(state.schema.marks.bold.create());
|
|
710
|
+
}
|
|
711
|
+
if (fontStyle) {
|
|
712
|
+
marks.push(state.schema.marks.italic.create());
|
|
713
|
+
}
|
|
714
|
+
// Underline and strike-through
|
|
715
|
+
if (textDecoration?.includes('underline')) {
|
|
716
|
+
marks.push(state.schema.marks.underline.create());
|
|
717
|
+
}
|
|
718
|
+
if (textDecoration?.includes('line-through')) {
|
|
719
|
+
marks.push(state.schema.marks.strike.create());
|
|
720
|
+
}
|
|
585
721
|
}
|
|
586
722
|
return marks;
|
|
587
723
|
};
|
|
724
|
+
/**
|
|
725
|
+
* The first-type seed for an empty field, with what the customer picked before typing laid over it:
|
|
726
|
+
* a picked mark wins per attribute (its unset attrs keep the seed's), and a picked mark the seed
|
|
727
|
+
* lacks is added. With nothing picked, the seed as is.
|
|
728
|
+
*/
|
|
729
|
+
export const mergePickedMarks = (seed, picked) => {
|
|
730
|
+
if (!picked?.length)
|
|
731
|
+
return [...seed];
|
|
732
|
+
const merged = seed.map((mark) => {
|
|
733
|
+
const pick = picked.find((p) => p.type === mark.type);
|
|
734
|
+
if (!pick)
|
|
735
|
+
return mark;
|
|
736
|
+
const pickedAttrs = Object.fromEntries(Object.entries(pick.attrs).filter(([, value]) => value !== null && value !== undefined));
|
|
737
|
+
return mark.type.create({ ...mark.attrs, ...pickedAttrs });
|
|
738
|
+
});
|
|
739
|
+
const added = picked.filter((pick) => !seed.some((mark) => mark.type === pick.type));
|
|
740
|
+
return [...merged, ...added];
|
|
741
|
+
};
|
|
588
742
|
export const retainStyleOnEmptyLine = (editor, selection) => {
|
|
589
743
|
const { $head } = selection;
|
|
590
744
|
if ($head.parent.content.size === 0) {
|