@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.
Files changed (576) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-DDcraD5S.js → CreatedOnBrandCrowd-de-de-BtVKllNQ.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-DtOeaisf.js → CreatedOnBrandCrowd-en-us-CX5V0v8u.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-BZpmJPew.js → CreatedOnBrandCrowd-es-es-CbA02PCL.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-CqRwC4e7.js → CreatedOnBrandCrowd-fr-ca-BQAKruBF.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-CqRwC4e7.js → CreatedOnBrandCrowd-fr-fr-BQAKruBF.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-DId9Dfjh.js → CreatedOnBrandCrowd-pt-br-Yk_yzB3s.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-DId9Dfjh.js → CreatedOnBrandCrowd-pt-pt-Yk_yzB3s.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-BTDfmOcm.js → CreatedOnDcom-de-de-DJZQbPSD.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-CeAu9Ayx.js → CreatedOnDcom-en-us-BJvNAa4l.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-WCv0K41H.js → CreatedOnDcom-es-es-CUwB1FRY.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-BlfevQDY.js → CreatedOnDcom-fr-ca-CK54U4oh.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-Cvt7MHPZ.js → CreatedOnDcom-fr-fr-DuUNBGrM.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-DipZuylv.js → CreatedOnDcom-pt-br-BfODpFNV.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-BCw4lcKN.js → CreatedOnDcom-pt-pt-Cf6u2GCg.js} +1 -1
  15. package/lib/src/brand-page/__fixtures__/production-text-style-resolver.fixture.d.ts +16 -0
  16. package/lib/src/brand-page/__fixtures__/production-text-style-resolver.fixture.js +35 -0
  17. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.d.ts +3 -0
  18. package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +19 -13
  19. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.d.ts +3 -1
  20. package/lib/src/brand-page/components/mailing-list/MailingList.mixin.js +17 -2
  21. package/lib/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.d.ts +11 -3
  22. package/lib/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.js +35 -1
  23. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.d.ts +8 -2
  24. package/lib/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.js +27 -3
  25. package/lib/src/brand-page/components/page/Page.mixin.d.ts +5 -2
  26. package/lib/src/brand-page/components/page/Page.mixin.js +33 -27
  27. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.d.ts +7 -2
  28. package/lib/src/brand-page/components/page-footer/PageFooter.mixin.js +21 -1
  29. package/lib/src/brand-page/components/payment/Payment.mixin.d.ts +5 -2
  30. package/lib/src/brand-page/components/payment/Payment.mixin.js +22 -2
  31. package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.d.ts +6 -2
  32. package/lib/src/brand-page/components/payment/support-me/SupportMe.mixin.js +32 -1
  33. package/lib/src/brand-page/components/social-links/SocialLinks.stories.js +0 -3
  34. package/lib/src/brand-page/components/testimonial-section/__fixtures__/data.js +0 -3
  35. package/lib/src/brand-page/components/text/Text.stories.js +0 -17
  36. package/lib/src/brand-page/constants/font.constants.d.ts +62 -0
  37. package/lib/src/brand-page/constants/font.constants.js +35 -0
  38. package/lib/src/brand-page/models/index.d.ts +23 -24
  39. package/lib/src/brand-page/models/index.js +20 -7
  40. package/lib/src/brand-page/models/navigation-styles.model.d.ts +1 -1
  41. package/lib/src/brand-page/models/navigation-styles.model.js +17 -8
  42. package/lib/src/brand-page/models/payment.model.d.ts +11 -6
  43. package/lib/src/brand-page/models/styles.model.d.ts +53 -7
  44. package/lib/src/brand-page/models/styles.model.js +115 -27
  45. package/lib/src/brand-page/utils/color-palette.util.d.ts +43 -23
  46. package/lib/src/brand-page/utils/color-palette.util.js +65 -27
  47. package/lib/src/brand-page/utils/color.util.d.ts +13 -9
  48. package/lib/src/brand-page/utils/color.util.js +56 -15
  49. package/lib/src/brand-page/utils/container-text-color.util.d.ts +46 -13
  50. package/lib/src/brand-page/utils/container-text-color.util.js +321 -41
  51. package/lib/src/brand-page/utils/index.d.ts +1 -0
  52. package/lib/src/brand-page/utils/index.js +1 -0
  53. package/lib/src/brand-page/utils/migration/migration-20.js +6 -2
  54. package/lib/src/brand-page/utils/migration/migration-21.js +34 -6
  55. package/lib/src/brand-page/utils/migration/migration-22.d.ts +99 -0
  56. package/lib/src/brand-page/utils/migration/migration-22.js +909 -0
  57. package/lib/src/brand-page/utils/migration.util.js +17 -0
  58. package/lib/src/brand-page/utils/model.util.d.ts +4 -0
  59. package/lib/src/brand-page/utils/model.util.js +4 -0
  60. package/lib/src/brand-page/utils/personalisation.util.js +9 -1
  61. package/lib/src/brand-page/utils/rte-role-lift.util.d.ts +72 -0
  62. package/lib/src/brand-page/utils/rte-role-lift.util.js +275 -0
  63. package/lib/src/brand-page/utils/style.util.d.ts +5 -1
  64. package/lib/src/brand-page/utils/style.util.js +34 -11
  65. package/lib/src/brand-page/utils/text-role-css.util.d.ts +19 -0
  66. package/lib/src/brand-page/utils/text-role-css.util.js +186 -0
  67. package/lib/src/brand-page/utils/text-role-reconnect.util.d.ts +90 -0
  68. package/lib/src/brand-page/utils/text-role-reconnect.util.js +434 -0
  69. package/lib/src/brand-page/utils/text-style.util.d.ts +53 -23
  70. package/lib/src/brand-page/utils/text-style.util.js +122 -22
  71. package/lib/src/brand-page/utils/view-model.util.d.ts +9 -1
  72. package/lib/src/brand-page/utils/view-model.util.js +124 -111
  73. package/lib/src/brand-page/view-models.d.ts +1 -0
  74. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +4 -1
  75. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +13 -2
  76. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +4 -4
  77. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +4 -1
  78. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +0 -10
  79. package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.js +0 -1
  80. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +23 -138
  81. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.js +0 -28
  82. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +4 -1
  83. package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +1 -1
  84. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +5 -2
  85. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +4 -1
  86. package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +4 -1
  87. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +4 -1
  88. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -0
  89. package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.js +1 -0
  90. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +1 -0
  91. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.d.ts +16 -0
  92. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.js +61 -0
  93. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.d.ts +11 -0
  94. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.js +236 -0
  95. package/lib/src/brand-page-maker/composables/rich-text-editor/font.d.ts +2 -1
  96. package/lib/src/brand-page-maker/composables/rich-text-editor/font.js +25 -6
  97. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.d.ts +17 -4
  98. package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.js +204 -17
  99. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.d.ts +1 -1
  100. package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.js +29 -31
  101. package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.d.ts +20 -0
  102. package/lib/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.js +60 -0
  103. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.d.ts +2 -1
  104. package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.js +22 -6
  105. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +10 -4
  106. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +319 -275
  107. package/lib/src/brand-page-maker/constants/config-settings-constant.js +1 -5
  108. package/lib/src/brand-page-maker/convertors/text-css-style-options.convertor.js +6 -2
  109. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.d.ts +1 -1
  110. package/lib/src/brand-page-maker/convertors/text-size-value.convertor.js +3 -1
  111. package/lib/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.js +7 -14
  112. package/lib/src/brand-page-maker/default-getters/text-color.default-getter.js +6 -13
  113. package/lib/src/brand-page-maker/models/content-settings.d.ts +8 -0
  114. package/lib/src/brand-page-maker/models/content-settings.js +112 -81
  115. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.d.ts +2 -2
  116. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.js +5 -2
  117. package/lib/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.js +4 -3
  118. package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +1257 -117
  119. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +6 -1
  120. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +17 -9
  121. package/lib/src/brand-page-maker/stores/history/history-store.d.ts +59 -5
  122. package/lib/src/brand-page-maker/stores/history/history-store.js +22 -2
  123. package/lib/src/brand-page-maker/utils/apply-color-strategy.js +26 -8
  124. package/lib/src/brand-page-maker/utils/index.d.ts +2 -1
  125. package/lib/src/brand-page-maker/utils/index.js +2 -1
  126. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +117 -15
  127. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +435 -281
  128. package/lib/src/brand-page-maker/utils/rte-authoring.util.d.ts +4 -0
  129. package/lib/src/brand-page-maker/utils/rte-authoring.util.js +101 -0
  130. package/lib/src/brand-page-maker/utils/rte-clipboard.util.d.ts +126 -0
  131. package/lib/src/brand-page-maker/utils/rte-clipboard.util.js +307 -0
  132. package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +13 -3
  133. package/lib/src/{bundled-translations-zfiA5Tsw.js → bundled-translations-yGrvPE5i.js} +17 -17
  134. package/lib/src/{bundled-translations.de-DE-ChsdSyAP.js → bundled-translations.de-DE-L4Znf8Hs.js} +17 -17
  135. package/lib/src/{bundled-translations.es-ES-DflsWQK0.js → bundled-translations.es-ES-D6iticrK.js} +15 -15
  136. package/lib/src/{bundled-translations.fr-CA-fpDRuZ52.js → bundled-translations.fr-CA-BgAVE-9k.js} +25 -25
  137. package/lib/src/{bundled-translations.fr-FR-Bub73Zt-.js → bundled-translations.fr-FR-B8GbyqxQ.js} +17 -17
  138. package/lib/src/{bundled-translations.pt-BR-BlnWE9TB.js → bundled-translations.pt-BR-DjPU3Db7.js} +25 -25
  139. package/lib/src/{bundled-translations.pt-PT-DmzXlnaS.js → bundled-translations.pt-PT-BaepaDpr.js} +23 -23
  140. package/lib/src/bundles/bundled-translations.de-DE.json +21 -2
  141. package/lib/src/bundles/bundled-translations.es-ES.json +21 -2
  142. package/lib/src/bundles/bundled-translations.fr-CA.json +21 -2
  143. package/lib/src/bundles/bundled-translations.fr-FR.json +21 -2
  144. package/lib/src/bundles/bundled-translations.json +21 -2
  145. package/lib/src/bundles/bundled-translations.pt-BR.json +21 -2
  146. package/lib/src/bundles/bundled-translations.pt-PT.json +21 -2
  147. package/lib/src/clients/ai-assistant-client.d.ts +1 -0
  148. package/lib/src/composables/useTranslate.d.ts +1 -1
  149. package/lib/src/composables/useTranslate.js +1 -1
  150. package/lib/src/css/library.brand-page-brandCrowd.min.css +303 -207
  151. package/lib/src/css/library.brand-page-brandPage.min.css +303 -207
  152. package/lib/src/css/library.brand-page-designCom.min.css +303 -207
  153. package/lib/src/css/library.brand-page-preview.min.css +303 -207
  154. package/lib/src/index.d.ts +2 -1
  155. package/lib/src/index.mjs +195 -191
  156. package/lib/src/{lib-1AqtEmvQ.js → lib-kGRlD3_P.js} +36855 -33893
  157. package/lib/src/lib.js +2 -1
  158. package/lib/src/metadata-builder/builders/footer-builder.js +4 -5
  159. package/lib/src/metadata-builder/builders/global-role-propagation.d.ts +58 -0
  160. package/lib/src/metadata-builder/builders/global-role-propagation.js +246 -0
  161. package/lib/src/metadata-builder/builders/global-styles-builder.d.ts +1 -0
  162. package/lib/src/metadata-builder/builders/global-styles-builder.js +116 -45
  163. package/lib/src/metadata-builder/builders/header-builder.js +13 -4
  164. package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +3 -3
  165. package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +3 -3
  166. package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +3 -3
  167. package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +4 -4
  168. package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +3 -3
  169. package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +2 -2
  170. package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +2 -2
  171. package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +4 -4
  172. package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +3 -3
  173. package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +8 -2
  174. package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +2 -2
  175. package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +60 -29
  176. package/lib/src/metadata-builder/builders/section-field-maps.js +1 -0
  177. package/lib/src/metadata-builder/builders/section-field-utils.d.ts +48 -19
  178. package/lib/src/metadata-builder/builders/section-field-utils.js +128 -52
  179. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.d.ts +4 -2
  180. package/lib/src/metadata-builder/builders/section-rules/global-styles.rules.js +28 -12
  181. package/lib/src/metadata-builder/builders/section-rules/social-links.rules.js +5 -1
  182. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +1 -1
  183. package/lib/src/metadata-builder/helpers/rte.helpers.js +97 -40
  184. package/lib/src/metadata-builder/metadata-executor.js +23 -1
  185. package/lib/src/metadata-builder/models.d.ts +2 -0
  186. package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +18 -19
  187. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +18 -1
  188. package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +1 -1
  189. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.d.ts +0 -1
  190. package/lib/src/metadata-builder/sanitizers/sanitizer-rules.js +5 -8
  191. package/lib/src/metadata-builder/sanitizers/section-args-validator.d.ts +7 -16
  192. package/lib/src/metadata-builder/sanitizers/section-args-validator.js +95 -22
  193. package/lib/src/shared/color-palette/section-color-matches.js +9 -25
  194. package/lib/src/shared/color-strategies/color-strategies.d.ts +15 -0
  195. package/lib/src/shared/color-strategies/color-strategies.js +31 -0
  196. package/lib/src/shared/color-strategies/rte-color.d.ts +8 -0
  197. package/lib/src/shared/color-strategies/rte-color.js +16 -0
  198. package/lib/src/shared/color-strategies/rte-field-pairs.d.ts +23 -0
  199. package/lib/src/shared/color-strategies/rte-field-pairs.js +28 -0
  200. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +9 -135
  201. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +1 -27
  202. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +12 -2
  203. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +7 -0
  204. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +75 -6
  205. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +18 -7
  206. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +6 -1
  207. package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +0 -7
  208. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +1 -0
  209. package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +8 -4
  210. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +1255 -26
  211. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.js +203 -59
  212. package/lib/src/shared/content-settings/store/content-settings-store.d.ts +6 -0
  213. package/lib/src/shared/content-settings/store/content-settings-store.js +105 -8
  214. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +5 -1
  215. package/lib/src/shared/navigation-style-settings/store/index.d.ts +7 -3
  216. package/lib/src/shared/navigation-style-settings/store/index.js +40 -15
  217. package/lib/src/shared/page-settings/components/delete-page-modal/DeletePageModal.mixin.d.ts +1 -1
  218. package/lib/src/shared/page-settings/components/new-page-modal/NewPageModal.mixin.d.ts +1 -0
  219. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +17 -5
  220. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +70 -13
  221. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.js +10 -2
  222. package/lib/src/shared/page-settings/store/page-settings-store.d.ts +2 -1
  223. package/lib/src/shared/page-settings/store/page-settings-store.js +17 -0
  224. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +4 -1
  225. package/lib/src/shared/rte-extensions/AutoLink.d.ts +17 -0
  226. package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.js +67 -51
  227. package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.js +4 -1
  228. package/lib/src/shared/rte-extensions/TextEffects.d.ts +28 -0
  229. package/lib/src/shared/rte-extensions/TextEffects.js +96 -0
  230. package/lib/src/shared/rte-extensions/ViewDomParser.d.ts +2 -0
  231. package/lib/src/shared/rte-extensions/ViewDomParser.js +21 -0
  232. package/lib/src/shared/rte-extensions.util.d.ts +25 -0
  233. package/lib/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.js → shared/rte-extensions.util.js} +62 -7
  234. package/lib/src/shared/rte-link.util.d.ts +1 -0
  235. package/lib/src/shared/rte-link.util.js +1 -0
  236. package/lib/src/shared/rte-render.util.d.ts +112 -0
  237. package/lib/src/shared/rte-render.util.js +255 -0
  238. package/lib/src/shared/rte-shape.util.d.ts +6 -0
  239. package/lib/src/shared/rte-shape.util.js +18 -0
  240. package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +2 -1
  241. package/lib/src/shared/side-bar/components/SideBarTabButton.mixin.d.ts +1 -0
  242. package/lib/src/shared/side-bar/store/side-bar-store.d.ts +2 -0
  243. package/lib/src/shared/side-bar/store/side-bar-store.js +9 -0
  244. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +155 -15
  245. package/lib/src/shared/style-settings/components/StyleSettings.mixin.js +7 -1
  246. package/lib/src/shared/style-settings/store/style-settings-store.d.ts +1 -9
  247. package/lib/src/shared/style-settings/store/style-settings-store.js +3 -33
  248. package/lib/src/shared/style-settings/text-style-size-order.d.ts +2 -0
  249. package/lib/src/shared/style-settings/text-style-size-order.js +13 -0
  250. package/lib/src/shared/text-role-typography.util.d.ts +64 -0
  251. package/lib/src/shared/text-role-typography.util.js +183 -0
  252. package/lib/src/utils/minify-brand-page-metadata.d.ts +16 -1
  253. package/lib/src/utils/minify-brand-page-metadata.js +31 -9
  254. package/package.json +1 -1
  255. package/src/brand-page/__fixtures__/migration-22-v21/edited-brandsite-sections.v21.json +982 -0
  256. package/src/brand-page/__fixtures__/migration-22-v21/new-brandcontact-every-section.v21.json +1231 -0
  257. package/src/brand-page/__fixtures__/migration-22-v21/new-brandpage-every-section.v21.json +1231 -0
  258. package/src/brand-page/__fixtures__/migration-22-v21/new-brandsite-every-section.v21.json +1243 -0
  259. package/src/brand-page/__fixtures__/migration-22-v21/real-brandcontact.v21.json +755 -0
  260. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-general-link.v21.json +527 -0
  261. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-links.v21.json +755 -0
  262. package/src/brand-page/__fixtures__/migration-22-v21/real-brandpage-social-links.v21.json +514 -0
  263. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-about.v21.json +459 -0
  264. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-footer.v21.json +469 -0
  265. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-header-banner.v21.json +481 -0
  266. package/src/brand-page/__fixtures__/migration-22-v21/real-brandsite-sections.v21.json +800 -0
  267. package/src/brand-page/__fixtures__/production-text-style-resolver.fixture.ts +52 -0
  268. package/src/brand-page/components/about-section/AboutSection.vue.test.ts +0 -10
  269. package/src/brand-page/components/contact-form/ContactForm.mixin.test.ts +127 -0
  270. package/src/brand-page/components/contact-form/ContactForm.mixin.ts +31 -14
  271. package/src/brand-page/components/contact-form/ContactForm.vue +26 -12
  272. package/src/brand-page/components/contact-form/ContactForm.vue.test.ts +60 -0
  273. package/src/brand-page/components/mailing-list/MailingList.mixin.test.ts +92 -0
  274. package/src/brand-page/components/mailing-list/MailingList.mixin.ts +28 -3
  275. package/src/brand-page/components/mailing-list/MailingList.vue +9 -4
  276. package/src/brand-page/components/mailing-list/MailingList.vue.test.ts +63 -0
  277. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.mixin.ts +51 -1
  278. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.test.ts +114 -0
  279. package/src/brand-page/components/navigation/button-carousel/ButtonCarouselNavigation.vue +8 -2
  280. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.test.ts +182 -0
  281. package/src/brand-page/components/navigation/navigation-carousel/NavigationCarousel.vue +59 -12
  282. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.mixin.ts +40 -3
  283. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue +15 -7
  284. package/src/brand-page/components/navigation/navigation-side-menu/NavigationSideMenu.vue.test.ts +133 -3
  285. package/src/brand-page/components/page/Page.mixin.ts +41 -34
  286. package/src/brand-page/components/page/Page.vue +17 -6
  287. package/src/brand-page/components/page/Page.vue.test.ts +91 -1
  288. package/src/brand-page/components/page-footer/PageFooter.mixin.ts +32 -2
  289. package/src/brand-page/components/page-footer/PageFooter.test.ts +79 -0
  290. package/src/brand-page/components/page-footer/PageFooter.vue +12 -4
  291. package/src/brand-page/components/payment/Payment.mixin.ts +34 -2
  292. package/src/brand-page/components/payment/Payment.test.ts +188 -0
  293. package/src/brand-page/components/payment/Payment.vue +12 -5
  294. package/src/brand-page/components/payment/RequestPaymentStripe.vue +1 -0
  295. package/src/brand-page/components/payment/support-me/SupportMe.mixin.ts +49 -2
  296. package/src/brand-page/components/payment/support-me/SupportMe.test.ts +100 -0
  297. package/src/brand-page/components/payment/support-me/SupportMe.vue +7 -1
  298. package/src/brand-page/components/payment/support-me/SupportMe.vue.test.ts +66 -0
  299. package/src/brand-page/components/save-contact/SaveContactWidget.test.ts +100 -0
  300. package/src/brand-page/components/save-contact/SaveContactWidget.vue +6 -3
  301. package/src/brand-page/components/shop/PaymentModal.vue +2 -6
  302. package/src/brand-page/components/shop/PaymentShippingAddress.vue +6 -0
  303. package/src/brand-page/components/shop/Shop.vue +15 -2
  304. package/src/brand-page/components/shop/Shop.vue.test.ts +74 -2
  305. package/src/brand-page/components/social-links/SocialLinks.stories.ts +0 -3
  306. package/src/brand-page/components/social-links/SocialLinks.vue.test.ts +0 -3
  307. package/src/brand-page/components/testimonial-section/__fixtures__/data.ts +0 -3
  308. package/src/brand-page/components/text/Text.stories.ts +0 -17
  309. package/src/brand-page/components/text-wrapper/TextWrapper.parity.test.ts +136 -0
  310. package/src/brand-page/components/text-wrapper/TextWrapper.test.ts +358 -0
  311. package/src/brand-page/components/text-wrapper/TextWrapper.vue +82 -22
  312. package/src/brand-page/constants/font.constants.ts +37 -0
  313. package/src/brand-page/models/footer-icon-color.test.ts +22 -0
  314. package/src/brand-page/models/index.ts +50 -28
  315. package/src/brand-page/models/navigation-styles.model.test.ts +77 -1
  316. package/src/brand-page/models/navigation-styles.model.ts +26 -9
  317. package/src/brand-page/models/payment.model.ts +15 -6
  318. package/src/brand-page/models/styles.model.test.ts +104 -0
  319. package/src/brand-page/models/styles.model.ts +181 -47
  320. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +619 -115
  321. package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +150 -9
  322. package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +300 -18
  323. package/src/brand-page/utils/color-palette.util.test.ts +126 -1
  324. package/src/brand-page/utils/color-palette.util.ts +92 -26
  325. package/src/brand-page/utils/color.util.test.ts +62 -29
  326. package/src/brand-page/utils/color.util.ts +77 -14
  327. package/src/brand-page/utils/container-text-color.util.test.ts +672 -26
  328. package/src/brand-page/utils/container-text-color.util.ts +472 -46
  329. package/src/brand-page/utils/index.ts +1 -0
  330. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/edited-brandsite-sections.v22.json +1191 -0
  331. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandcontact-every-section.v22.json +2026 -0
  332. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandpage-every-section.v22.json +2017 -0
  333. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandsite-every-section.v22.json +2031 -0
  334. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandcontact.v22.json +1145 -0
  335. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-general-link.v22.json +645 -0
  336. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-links.v22.json +1136 -0
  337. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-social-links.v22.json +662 -0
  338. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-about.v22.json +638 -0
  339. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-footer.v22.json +610 -0
  340. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-header-banner.v22.json +660 -0
  341. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-sections.v22.json +1132 -0
  342. package/src/brand-page/utils/migration/migration-01.ts +293 -237
  343. package/src/brand-page/utils/migration/migration-02.ts +8 -1
  344. package/src/brand-page/utils/migration/migration-20.ts +6 -3
  345. package/src/brand-page/utils/migration/migration-20_5.test.ts +5 -2
  346. package/src/brand-page/utils/migration/migration-21.test.ts +34 -0
  347. package/src/brand-page/utils/migration/migration-21.ts +46 -10
  348. package/src/brand-page/utils/migration/migration-22.fixed-input.test.ts +43 -0
  349. package/src/brand-page/utils/migration/migration-22.test.ts +4103 -0
  350. package/src/brand-page/utils/migration/migration-22.text-font-family.test.ts +72 -0
  351. package/src/brand-page/utils/migration/migration-22.ts +1336 -0
  352. package/src/brand-page/utils/migration.util.test.ts +146 -32
  353. package/src/brand-page/utils/migration.util.ts +18 -0
  354. package/src/brand-page/utils/model.util.ts +4 -0
  355. package/src/brand-page/utils/personalisation.util.test.ts +148 -3
  356. package/src/brand-page/utils/personalisation.util.ts +9 -1
  357. package/src/brand-page/utils/rte-role-lift.util.ts +409 -0
  358. package/src/brand-page/utils/style.util.test.ts +35 -2
  359. package/src/brand-page/utils/style.util.ts +45 -11
  360. package/src/brand-page/utils/text-role-css.util.test.ts +525 -0
  361. package/src/brand-page/utils/text-role-css.util.ts +321 -0
  362. package/src/brand-page/utils/text-role-reconnect.util.test.ts +604 -0
  363. package/src/brand-page/utils/text-role-reconnect.util.ts +727 -0
  364. package/src/brand-page/utils/text-style.util.test.ts +305 -0
  365. package/src/brand-page/utils/text-style.util.ts +198 -24
  366. package/src/brand-page/utils/view-model.page-data.test.ts +232 -0
  367. package/src/brand-page/utils/view-model.util.test.ts +954 -133
  368. package/src/brand-page/utils/view-model.util.ts +187 -139
  369. package/src/brand-page/view-models.ts +4 -0
  370. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.blank-site.test.ts +57 -0
  371. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +9 -5
  372. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +0 -10
  373. package/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.ts +0 -1
  374. package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.ts +0 -44
  375. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +253 -200
  376. package/src/brand-page-maker/components/shop/AddOrEditProductContainer.vue +1 -0
  377. package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +1 -0
  378. package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +2 -0
  379. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +1 -0
  380. package/src/brand-page-maker/composables/rich-text-editor/block-typography.test.ts +519 -0
  381. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +1 -1
  382. package/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.test.ts +26 -1
  383. package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.test.ts +110 -0
  384. package/src/brand-page-maker/composables/rich-text-editor/extensions/RoleTypographyFill.ts +99 -0
  385. package/src/brand-page-maker/composables/rich-text-editor/extensions/RteClipboard.ts +397 -0
  386. package/src/brand-page-maker/composables/rich-text-editor/extensions/ViewDomParser.test.ts +139 -0
  387. package/src/brand-page-maker/composables/rich-text-editor/font.ts +36 -5
  388. package/src/brand-page-maker/composables/rich-text-editor/formatting.test.ts +375 -1
  389. package/src/brand-page-maker/composables/rich-text-editor/formatting.ts +301 -17
  390. package/src/brand-page-maker/composables/rich-text-editor/hyperlink.test.ts +82 -1
  391. package/src/brand-page-maker/composables/rich-text-editor/hyperlink.ts +28 -34
  392. package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.test.ts +80 -0
  393. package/src/brand-page-maker/composables/rich-text-editor/keepMarksOnEmpty.ts +75 -0
  394. package/src/brand-page-maker/composables/rich-text-editor/spacing.ts +31 -6
  395. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.test.ts +2485 -0
  396. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +435 -337
  397. package/src/brand-page-maker/constants/config-settings-constant.ts +0 -6
  398. package/src/brand-page-maker/convertors/text-css-style-options.convertor.test.ts +43 -0
  399. package/src/brand-page-maker/convertors/text-css-style-options.convertor.ts +6 -2
  400. package/src/brand-page-maker/convertors/text-size-value.convertor.test.ts +24 -0
  401. package/src/brand-page-maker/convertors/text-size-value.convertor.ts +17 -13
  402. package/src/brand-page-maker/default-getters/payment-text-and-border-color.default-getter.ts +7 -22
  403. package/src/brand-page-maker/default-getters/text-color.default-getter.ts +5 -21
  404. package/src/brand-page-maker/models/content-settings.test.ts +708 -0
  405. package/src/brand-page-maker/models/content-settings.ts +133 -82
  406. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.test.ts +63 -1
  407. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store-utils.ts +16 -3
  408. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.test.ts +34 -0
  409. package/src/brand-page-maker/stores/admin-logo-settings/admin-logo-settings-store.ts +4 -2
  410. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +185 -1
  411. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +22 -34
  412. package/src/brand-page-maker/stores/history/history-store.ts +35 -2
  413. package/src/brand-page-maker/utils/__snapshots__/apply-color-strategy.golden.test.ts.snap +528 -0
  414. package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +12 -0
  415. package/src/brand-page-maker/utils/apply-color-strategy.golden.test.ts +2 -0
  416. package/src/brand-page-maker/utils/apply-color-strategy.test.ts +181 -3
  417. package/src/brand-page-maker/utils/apply-color-strategy.ts +36 -4
  418. package/src/brand-page-maker/utils/index.ts +2 -1
  419. package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +447 -410
  420. package/src/brand-page-maker/utils/rich-text-editor.util.ts +610 -506
  421. package/src/brand-page-maker/utils/rte-authoring.util.test.ts +244 -0
  422. package/src/brand-page-maker/utils/rte-authoring.util.ts +175 -0
  423. package/src/brand-page-maker/utils/rte-clipboard.util.test.ts +558 -0
  424. package/src/brand-page-maker/utils/rte-clipboard.util.ts +473 -0
  425. package/src/brand-page-maker/utils/rte-features.test.ts +99 -3
  426. package/src/brand-page-maker/utils/rte-render-parity.test.ts +1 -1
  427. package/src/brand-page-maker/utils/rte-render.util.test.ts +230 -0
  428. package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +1 -1
  429. package/src/brand-page-maker/utils/rte-sanitize.util.ts +14 -3
  430. package/src/brand-page-maker/utils/rte-schema-version.test.ts +102 -0
  431. package/src/bundles/bundled-translations.de-DE.json +21 -2
  432. package/src/bundles/bundled-translations.es-ES.json +21 -2
  433. package/src/bundles/bundled-translations.fr-CA.json +21 -2
  434. package/src/bundles/bundled-translations.fr-FR.json +21 -2
  435. package/src/bundles/bundled-translations.json +21 -2
  436. package/src/bundles/bundled-translations.pt-BR.json +21 -2
  437. package/src/bundles/bundled-translations.pt-PT.json +21 -2
  438. package/src/clients/ai-assistant-client.ts +1 -0
  439. package/src/composables/useTranslate.ts +2 -1
  440. package/src/lib.ts +2 -2
  441. package/src/metadata-builder/builders/footer-builder.test.ts +70 -45
  442. package/src/metadata-builder/builders/footer-builder.ts +4 -8
  443. package/src/metadata-builder/builders/global-role-propagation.test.ts +907 -0
  444. package/src/metadata-builder/builders/global-role-propagation.ts +430 -0
  445. package/src/metadata-builder/builders/global-styles-builder.test.ts +1020 -0
  446. package/src/metadata-builder/builders/global-styles-builder.ts +194 -48
  447. package/src/metadata-builder/builders/header-builder.test.ts +112 -40
  448. package/src/metadata-builder/builders/header-builder.ts +18 -8
  449. package/src/metadata-builder/builders/section-builders/about-section-builder.ts +5 -3
  450. package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +5 -3
  451. package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +5 -3
  452. package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +7 -4
  453. package/src/metadata-builder/builders/section-builders/images-section-builder.ts +5 -3
  454. package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +3 -2
  455. package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +3 -2
  456. package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +7 -7
  457. package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +5 -3
  458. package/src/metadata-builder/builders/section-builders/social-links-builder.test.ts +2 -2
  459. package/src/metadata-builder/builders/section-builders/social-links-builder.ts +21 -10
  460. package/src/metadata-builder/builders/section-builders/support-me-builder.test.ts +10 -0
  461. package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +3 -2
  462. package/src/metadata-builder/builders/section-builders/text-section-builder.ts +111 -61
  463. package/src/metadata-builder/builders/section-field-maps.ts +1 -0
  464. package/src/metadata-builder/builders/section-field-utils.test.ts +545 -2
  465. package/src/metadata-builder/builders/section-field-utils.ts +202 -69
  466. package/src/metadata-builder/builders/section-rules/global-styles.rules.ts +38 -13
  467. package/src/metadata-builder/builders/section-rules/social-links.rules.ts +5 -0
  468. package/src/metadata-builder/helpers/rte.helpers.test.ts +101 -0
  469. package/src/metadata-builder/helpers/rte.helpers.ts +129 -43
  470. package/src/metadata-builder/metadata-executor.test.ts +167 -0
  471. package/src/metadata-builder/metadata-executor.ts +34 -1
  472. package/src/metadata-builder/models.ts +2 -0
  473. package/src/metadata-builder/parsers/ai-toolcall-parser.ts +23 -7
  474. package/src/metadata-builder/parsers/section-tool-arguments.ts +21 -1
  475. package/src/metadata-builder/sanitizers/__tests__/section-args-validator.test.ts +215 -0
  476. package/src/metadata-builder/sanitizers/rte-schema-check.ts +1 -1
  477. package/src/metadata-builder/sanitizers/sanitizer-rules.ts +4 -8
  478. package/src/metadata-builder/sanitizers/section-args-validator.ts +136 -53
  479. package/src/shared/color-palette/section-color-matches.test.ts +15 -11
  480. package/src/shared/color-palette/section-color-matches.ts +9 -28
  481. package/src/shared/color-strategies/color-strategies.ts +35 -0
  482. package/src/shared/color-strategies/rte-color.test.ts +1 -1
  483. package/src/shared/color-strategies/rte-color.ts +19 -0
  484. package/src/shared/color-strategies/rte-field-pairs.test.ts +26 -5
  485. package/src/shared/color-strategies/rte-field-pairs.ts +33 -0
  486. package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.test.ts +43 -66
  487. package/src/shared/content-settings/components/color-matches-panel/ColorMatchesPanel.vue +7 -1
  488. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +1 -48
  489. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +33 -7
  490. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.test.ts +128 -1
  491. package/src/shared/content-settings/components/draggable-item-list/DraggableItemList.vue +1 -0
  492. package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +0 -6
  493. package/src/shared/content-settings/components/logo-selection-field/LogoSelection.vue +3 -0
  494. package/src/shared/content-settings/components/logo-size-field/LogoSizeSlider.vue +3 -0
  495. package/src/shared/content-settings/components/logo-size-field/LogoSizeSliderField.vue +1 -0
  496. package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +1 -0
  497. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.test.ts +56 -3
  498. package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +11 -4
  499. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.test.ts +335 -25
  500. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.ts +248 -70
  501. package/src/shared/content-settings/components/text-style-field/TextStyleField.vue +113 -25
  502. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.de-DE.json +17 -10
  503. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.es-ES.json +17 -10
  504. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-CA.json +17 -10
  505. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.fr-FR.json +17 -10
  506. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.json +8 -1
  507. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-BR.json +17 -10
  508. package/src/shared/content-settings/components/text-style-field/i18n/text-style-field.pt-PT.json +17 -10
  509. package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.test.ts +141 -0
  510. package/src/shared/content-settings/components/text-style-role-dropdown/TextStyleRoleDropdown.vue +136 -0
  511. package/src/shared/content-settings/store/content-settings-store.test.ts +491 -6
  512. package/src/shared/content-settings/store/content-settings-store.ts +159 -17
  513. package/src/shared/logo-settings/components/EditLogoSettings.vue +1 -0
  514. package/src/shared/logo-settings/components/LogoVariations.vue +1 -0
  515. package/src/shared/navigation-style-settings/components/navigation-style-settings/NavigationStyleSettings.vue +1 -0
  516. package/src/shared/navigation-style-settings/store/index.test.ts +295 -0
  517. package/src/shared/navigation-style-settings/store/index.ts +65 -15
  518. package/src/shared/page-settings/components/header-settings-panel/HeaderSettingsPanel.vue +2 -0
  519. package/src/shared/page-settings/components/page-settings/PageElement.vue +1 -0
  520. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.test.ts +44 -4
  521. package/src/shared/page-settings/components/page-settings-section-styles/HeaderButtonSettings.vue +13 -4
  522. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.navigation.test.ts +89 -0
  523. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.text-style.test.ts +91 -0
  524. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.ts +14 -2
  525. package/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.vue +2 -0
  526. package/src/shared/page-settings/store/page-settings-store.text-style.test.ts +84 -0
  527. package/src/shared/page-settings/store/page-settings-store.ts +30 -1
  528. package/src/shared/rte-extensions/AutoLink.test.ts +98 -0
  529. package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/AutoLink.ts +87 -58
  530. package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.ts +4 -1
  531. package/src/shared/rte-extensions/TextEffects.ts +151 -0
  532. package/src/shared/rte-extensions/ViewDomParser.ts +27 -0
  533. package/src/{brand-page-maker/composables/rich-text-editor/getRteExtensions.ts → shared/rte-extensions.util.ts} +66 -9
  534. package/src/shared/rte-link.util.ts +2 -0
  535. package/src/shared/rte-render.util.ts +385 -0
  536. package/src/shared/rte-shape.util.ts +29 -0
  537. package/src/shared/side-bar/store/side-bar-store.test.ts +27 -1
  538. package/src/shared/side-bar/store/side-bar-store.ts +11 -0
  539. package/src/shared/style-settings/components/StyleSettings.mixin.ts +7 -3
  540. package/src/shared/style-settings/components/StyleSettings.test.ts +116 -0
  541. package/src/shared/style-settings/components/StyleSettings.vue +75 -25
  542. package/src/shared/style-settings/components/i18n/style-settings.de-DE.json +32 -20
  543. package/src/shared/style-settings/components/i18n/style-settings.es-ES.json +32 -20
  544. package/src/shared/style-settings/components/i18n/style-settings.fr-CA.json +32 -20
  545. package/src/shared/style-settings/components/i18n/style-settings.fr-FR.json +32 -20
  546. package/src/shared/style-settings/components/i18n/style-settings.json +13 -3
  547. package/src/shared/style-settings/components/i18n/style-settings.pt-BR.json +32 -20
  548. package/src/shared/style-settings/components/i18n/style-settings.pt-PT.json +32 -20
  549. package/src/shared/style-settings/components/text-style-options-settings-with-state/TextStyleOptionsSettingsWithState.vue +14 -34
  550. package/src/shared/style-settings/store/style-settings-store.ts +3 -49
  551. package/src/shared/style-settings/text-style-size-order.test.ts +76 -0
  552. package/src/shared/style-settings/text-style-size-order.ts +28 -0
  553. package/src/shared/template-settings/components/TemplatesSettings.vue +4 -0
  554. package/src/shared/text-role-typography.util.ts +277 -0
  555. package/src/utils/minify-brand-page-metadata.test.ts +102 -7
  556. package/src/utils/minify-brand-page-metadata.ts +62 -8
  557. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.d.ts +0 -2
  558. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
  559. package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -63
  560. package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -106
  561. package/lib/src/brand-page-maker/utils/rte-shape.d.ts +0 -18
  562. package/lib/src/brand-page-maker/utils/rte-shape.js +0 -21
  563. package/lib/src/metadata-builder/builders/global-font-propagation.d.ts +0 -41
  564. package/lib/src/metadata-builder/builders/global-font-propagation.js +0 -146
  565. package/src/brand-page-maker/utils/rte-render.util.ts +0 -179
  566. package/src/brand-page-maker/utils/rte-shape.ts +0 -29
  567. package/src/metadata-builder/builders/global-font-propagation.test.ts +0 -401
  568. package/src/metadata-builder/builders/global-font-propagation.ts +0 -238
  569. package/src/shared/style-settings/components/StyleSettingsSection.vue +0 -8
  570. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.d.ts +0 -0
  571. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.js +0 -0
  572. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.d.ts +0 -0
  573. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.js +0 -0
  574. /package/lib/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/MaxLength.d.ts +0 -0
  575. /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/FontFamily.ts +0 -0
  576. /package/src/{brand-page-maker/composables/rich-text-editor/extensions → shared/rte-extensions}/LetterSpacing.ts +0 -0
@@ -10,7 +10,8 @@ import {
10
10
  VIEWPORTS,
11
11
  getNavigationType,
12
12
  } from '@brand-page';
13
- import type { NavigationType } from '@brand-page';
13
+ import type { NavigationType, TextStyleOptions } from '@brand-page';
14
+ import { normalizeTextStyleAgainstRole } from '@brand-page/utils/text-style.util';
14
15
  import type {
15
16
  ButtonLinkType,
16
17
  Content,
@@ -290,6 +291,34 @@ export const useUiPageSettingsStore = defineStore('uiPageSettings', {
290
291
  }): void {
291
292
  this.pages.find((p) => p.id === pageId)!.isHidden = isHidden;
292
293
  },
294
+ renormalizeTextStylesForRole(
295
+ type: string,
296
+ textStyleOptions: TextStyleOptions | undefined,
297
+ ): void {
298
+ for (const viewport of [VIEWPORTS.desktop, VIEWPORTS.mobile] as const) {
299
+ const footer = this.sections[PAGE_SECTIONS.footer][viewport];
300
+
301
+ if (footer.copyrightStyle?.textStyleType === type) {
302
+ footer.copyrightStyle = normalizeTextStyleAgainstRole(
303
+ footer.copyrightStyle,
304
+ textStyleOptions,
305
+ );
306
+ }
307
+
308
+ const header = this.sections[PAGE_SECTIONS.header][viewport];
309
+ const buttonTextStyle = header.headerButton?.buttonTextStyle;
310
+
311
+ if (header.headerButton && buttonTextStyle?.textStyleType === type) {
312
+ header.headerButton = {
313
+ ...header.headerButton,
314
+ buttonTextStyle: normalizeTextStyleAgainstRole(
315
+ buttonTextStyle,
316
+ textStyleOptions,
317
+ ),
318
+ };
319
+ }
320
+ }
321
+ },
293
322
  setPageSettingsSectionValue({
294
323
  sectionName,
295
324
  propName,
@@ -0,0 +1,98 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import { Editor, type JSONContent } from '@tiptap/vue-3';
3
+ import { getRteExtensions } from '@shared/rte-extensions.util';
4
+ import { DEFAULT_LINK_COLOR } from '@src/constants/rich-text-editor.constants';
5
+
6
+ const link = { type: 'link', attrs: { href: 'https://example.com' } };
7
+
8
+ // "Read our guide today", where "guide" is a link the user made red with no underline.
9
+ const customLinkDoc = (): JSONContent => ({
10
+ type: 'doc',
11
+ content: [
12
+ {
13
+ type: 'paragraph',
14
+ content: [
15
+ { type: 'text', text: 'Read our ' },
16
+ {
17
+ type: 'text',
18
+ text: 'guide',
19
+ marks: [link, { type: 'textStyle', attrs: { color: '#ff0000' } }],
20
+ },
21
+ { type: 'text', text: ' today' },
22
+ ],
23
+ },
24
+ ],
25
+ });
26
+
27
+ const linkMarksOf = (editor: Editor) => {
28
+ let marks: string[] = [];
29
+ let color: unknown;
30
+
31
+ editor.state.doc.descendants((node) => {
32
+ if (node.isText && node.marks.some((mark) => mark.type.name === 'link')) {
33
+ marks = node.marks.map((mark) => mark.type.name);
34
+ color = node.marks.find((mark) => mark.type.name === 'textStyle')?.attrs
35
+ .color;
36
+ }
37
+ });
38
+
39
+ return { marks, color };
40
+ };
41
+
42
+ describe('AutoLink new-link styling', () => {
43
+ let editors: Editor[] = [];
44
+
45
+ const mk = (content: JSONContent | string) => {
46
+ const editor = new Editor({ extensions: getRteExtensions(), content });
47
+
48
+ editors.push(editor);
49
+
50
+ return editor;
51
+ };
52
+
53
+ afterEach(() => {
54
+ editors.forEach((editor) => editor.destroy());
55
+ editors = [];
56
+ });
57
+
58
+ it("leaves an existing link's own colour and underline after an earlier delete", () => {
59
+ const editor = mk(customLinkDoc());
60
+
61
+ editor.commands.deleteRange({ from: 2, to: 3 }); // "Read" → "Rad"
62
+
63
+ expect(editor.state.doc.textContent).toBe('Rad our guide today');
64
+ expect(linkMarksOf(editor)).toEqual({
65
+ marks: ['link', 'textStyle'],
66
+ color: '#ff0000',
67
+ });
68
+ });
69
+
70
+ it('leaves an existing link alone after a delete in an earlier paragraph', () => {
71
+ const doc = customLinkDoc();
72
+
73
+ doc.content!.unshift({
74
+ type: 'paragraph',
75
+ content: [{ type: 'text', text: 'Intro line' }],
76
+ });
77
+
78
+ const editor = mk(doc);
79
+
80
+ editor.commands.deleteRange({ from: 1, to: 7 }); // "Intro " gone
81
+
82
+ expect(linkMarksOf(editor).color).toBe('#ff0000');
83
+ expect(linkMarksOf(editor).marks).not.toContain('underline');
84
+ });
85
+
86
+ it('still gives a newly linked word the link blue and an underline', () => {
87
+ const editor = mk('<p>Read our guide today</p>');
88
+
89
+ editor
90
+ .chain()
91
+ .setTextSelection({ from: 10, to: 15 })
92
+ .setLink({ href: 'https://example.com' })
93
+ .run();
94
+
95
+ expect(linkMarksOf(editor).color).toBe(DEFAULT_LINK_COLOR);
96
+ expect(linkMarksOf(editor).marks).toContain('underline');
97
+ });
98
+ });
@@ -1,9 +1,14 @@
1
1
  import { Extension } from '@tiptap/core';
2
2
  import { Plugin, PluginKey } from 'prosemirror-state';
3
- import type { Transaction } from 'prosemirror-state';
3
+ import type { EditorState, Transaction } from 'prosemirror-state';
4
4
  import type { Node, Mark } from 'prosemirror-model';
5
5
  import { DEFAULT_LINK_COLOR as LINK_COLOR } from '@src/constants/rich-text-editor.constants';
6
6
 
7
+ /** A transaction carrying this meta skips the new-link styling pass below: a clipboard paste
8
+ * brings its own look (a copied link keeps its colour; a text-only paste brings no links), so
9
+ * neither wants AutoLink's "force blue + underline" treatment for a newly-created link. */
10
+ export const AUTO_LINK_SKIP_STYLING_META = 'autoLinkSkipStyling';
11
+
7
12
  const isLinkMark = (mark: Mark) => mark.type.name === 'link';
8
13
  const isUnderlineMark = (mark: Mark) => mark.type.name === 'underline';
9
14
  const isTextStyleMark = (mark: Mark) => mark.type.name === 'textStyle';
@@ -61,6 +66,55 @@ const applyDefaultLinkStyling = (
61
66
  return modified;
62
67
  };
63
68
 
69
+ /**
70
+ * The end-of-link detach a typed character gets right after a link's last position: the link
71
+ * mark (and its auto-blue colour, unless the user manually added an underline) drops from what
72
+ * comes next, so continuing to type doesn't extend the link. `null` when `pos` isn't at the end
73
+ * of a link — mid-link, or no link at all — so the caller keeps its own marks unchanged.
74
+ * Exported for `RteClipboard.ts`'s text-only paste, which takes the same detach a typed
75
+ * character would.
76
+ */
77
+ export const linkDetachMarksAt = (
78
+ state: EditorState,
79
+ pos: number,
80
+ ): Mark[] | null => {
81
+ const currentMarks = state.doc.resolve(pos).marks();
82
+ const linkMark = currentMarks.find(isLinkMark);
83
+
84
+ if (!linkMark) return null;
85
+
86
+ const nextPos = pos + 1;
87
+ const hasLinkAfter =
88
+ nextPos <= state.doc.content.size &&
89
+ state.doc
90
+ .resolve(Math.min(nextPos, state.doc.content.size))
91
+ .marks()
92
+ .some((mark) => isLinkMark(mark) && mark.eq(linkMark));
93
+
94
+ if (hasLinkAfter) return null;
95
+
96
+ return currentMarks
97
+ .filter((mark) => {
98
+ if (isLinkMark(mark)) return false;
99
+
100
+ // Only preserve underlines if there's no blue color (manually added underlines)
101
+ // Remove underlines that were part of link styling (with blue color)
102
+ if (isUnderlineMark(mark)) {
103
+ const hasBlueColor = currentMarks.some(isBlueColorMark);
104
+
105
+ return !hasBlueColor;
106
+ }
107
+
108
+ // Remove blue color styling but preserve other text styles
109
+ if (isBlueColorMark(mark)) {
110
+ return createStylesWithoutColor(state.schema, mark);
111
+ }
112
+
113
+ return true;
114
+ })
115
+ .filter(Boolean) as Mark[];
116
+ };
117
+
64
118
  const removeHyperlinkStyles = (
65
119
  tr: Transaction,
66
120
  schema: any,
@@ -109,66 +163,28 @@ export const AutoLink = Extension.create({
109
163
  props: {
110
164
  handleTextInput(view, from, to, text) {
111
165
  const { state } = view;
112
- const { selection } = state;
113
- const { $anchor } = selection;
114
166
 
115
167
  // Only handle when typing at a cursor position (from === to)
116
168
  if (from !== to) {
117
169
  return false;
118
170
  }
119
171
 
120
- // Check if we have link marks at cursor position
121
- const currentMarks = $anchor.marks();
122
- const linkMark = currentMarks.find(isLinkMark);
123
-
124
- if (linkMark) {
125
- // Check if we're at the end of the link
126
- const currentPos = $anchor.pos;
127
- const nextPos = currentPos + 1;
128
-
129
- const hasLinkAfter =
130
- nextPos <= state.doc.content.size &&
131
- state.doc
132
- .resolve(Math.min(nextPos, state.doc.content.size))
133
- .marks()
134
- .some((mark) => isLinkMark(mark) && mark.eq(linkMark));
135
-
136
- if (!hasLinkAfter) {
137
- // detach the link after the attached link mark
138
- const preservedMarks = currentMarks
139
- .filter((mark) => {
140
- if (isLinkMark(mark)) return false;
141
-
142
- // Only preserve underlines if there's no blue color (manually added underlines)
143
- // Remove underlines that were part of link styling (with blue color)
144
- if (isUnderlineMark(mark)) {
145
- const hasBlueColor = currentMarks.some(isBlueColorMark);
172
+ const detached = linkDetachMarksAt(
173
+ state,
174
+ state.selection.$anchor.pos,
175
+ );
146
176
 
147
- return !hasBlueColor; // Keep underline only if no blue color
148
- }
177
+ if (!detached) return false;
149
178
 
150
- // Remove blue color styling but preserve other text styles
151
- if (isBlueColorMark(mark)) {
152
- return createStylesWithoutColor(state.schema, mark);
153
- }
179
+ let tr = state.tr;
154
180
 
155
- return true;
156
- })
157
- .filter(Boolean); // Insert text with only preserved marks
181
+ tr = tr.setStoredMarks(detached);
182
+ tr = tr.insertText(text, from, to);
183
+ tr = tr.setMeta('autoLinkDetached', true);
158
184
 
159
- let tr = state.tr;
185
+ view.dispatch(tr);
160
186
 
161
- tr = tr.setStoredMarks(preservedMarks);
162
- tr = tr.insertText(text, from, to);
163
- tr = tr.setMeta('autoLinkDetached', true);
164
-
165
- view.dispatch(tr);
166
-
167
- return true;
168
- }
169
- }
170
-
171
- return false;
187
+ return true;
172
188
  },
173
189
  },
174
190
 
@@ -185,26 +201,39 @@ export const AutoLink = Extension.create({
185
201
  const wasDetached = transactions.some((transaction) =>
186
202
  transaction.getMeta('autoLinkDetached'),
187
203
  );
204
+ const skipsNewLinkStyling = transactions.some((transaction) =>
205
+ transaction.getMeta(AUTO_LINK_SKIP_STYLING_META),
206
+ );
207
+
208
+ // Apply default styling to links (unless just detached, or the transaction brings its
209
+ // own look — a clipboard paste)
210
+ if (!wasDetached && !skipsNewLinkStyling) {
211
+ // A link is new when its text wasn't a link before these transactions. Map each
212
+ // position back through them: an edit earlier in the doc shifts every later link, so
213
+ // the same raw position in the old doc lands on other text.
214
+ const toOldPos = transactions
215
+ .map((transaction) => transaction.mapping.invert())
216
+ .reverse();
188
217
 
189
- // Apply default styling to links (unless just detached)
190
- if (!wasDetached) {
191
218
  newState.doc.descendants((node, pos) => {
192
219
  if (!node.isText || !node.text || !hasLinkMark(node.marks))
193
220
  return;
194
221
 
195
- // Check if this is a newly created link by comparing with old state
222
+ const oldPos = toOldPos.reduce(
223
+ (mapped, mapping) => mapping.map(mapped, 1),
224
+ pos,
225
+ );
196
226
  const oldNode =
197
- pos < oldState.doc.nodeSize ? oldState.doc.nodeAt(pos) : null;
227
+ oldPos < oldState.doc.content.size
228
+ ? oldState.doc.nodeAt(oldPos)
229
+ : null;
198
230
  const wasAlreadyLink = oldNode && hasLinkMark(oldNode.marks);
199
231
 
200
- // Only apply full styling (including underline) to newly created links
232
+ // An existing link keeps the colour and underline it has now.
201
233
  if (wasAlreadyLink === false) {
202
234
  if (applyDefaultLinkStyling(tr, newState.schema, node, pos)) {
203
235
  modified = true;
204
236
  }
205
- } else {
206
- // For existing links, preserve their current color and underline choices
207
- // Don't override user customizations on existing links
208
237
  }
209
238
  });
210
239
  }
@@ -26,7 +26,10 @@ export const MaxLength = Extension.create<MaxLengthOptions>({
26
26
  const { maxLength } = this.options;
27
27
  const { state } = view;
28
28
  const { from, to } = view.state.selection;
29
- const selectionSize = to - from;
29
+ // The selected TEXT being replaced, not its position span: a selection crossing a
30
+ // paragraph boundary spans 2 extra positions (the closing/opening block nodes) that
31
+ // aren't characters.
32
+ const selectionSize = state.doc.textBetween(from, to).length;
30
33
  const currentTextLength =
31
34
  state.doc.textContent.length - selectionSize;
32
35
  const incomingText = slice.content.textBetween(
@@ -0,0 +1,151 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import {
3
+ composeTextDecoration,
4
+ roleVarRef,
5
+ rteTextDecorationClassName,
6
+ } from '@shared/text-role-typography.util';
7
+
8
+ export type TextEffectsOptions = {
9
+ types: string[];
10
+ renderTextDecorationClasses?: boolean;
11
+ };
12
+
13
+ declare module '@tiptap/core' {
14
+ interface Commands<ReturnType> {
15
+ textEffects: {
16
+ setFontWeight: (value: string) => ReturnType;
17
+ unsetFontWeight: () => ReturnType;
18
+ setFontStyle: (value: string) => ReturnType;
19
+ unsetFontStyle: () => ReturnType;
20
+ setTextDecoration: (value: string) => ReturnType;
21
+ unsetTextDecoration: () => ReturnType;
22
+ };
23
+ }
24
+ }
25
+
26
+ /**
27
+ * BP-5969 — weight / style / decoration as `textStyle` mark ATTRIBUTES, not semantic marks.
28
+ *
29
+ * Every typography property now lives on the run's `textStyle` mark, each defaulting to its role
30
+ * `var(--role-*)` (or a raw override) — identical to family/size/line-height/letter-spacing. So
31
+ * editing a role's font-weight / font-style / text-decoration changes one CSS custom-property
32
+ * declaration and repaints every linked run through the cascade, with no doc rewrite. (The
33
+ * container applies nothing, so a per-run `font-weight: normal` / `text-decoration: none` override
34
+ * cleanly wins — the reason these can leave the semantic `<strong>`/`<u>` model.)
35
+ */
36
+ export const TextEffects = Extension.create<TextEffectsOptions>({
37
+ name: 'textEffects',
38
+
39
+ addOptions() {
40
+ return {
41
+ types: ['textStyle'],
42
+ renderTextDecorationClasses: false,
43
+ };
44
+ },
45
+
46
+ addGlobalAttributes() {
47
+ return [
48
+ {
49
+ types: this.options.types,
50
+ attributes: {
51
+ fontWeight: {
52
+ default: null,
53
+ parseHTML: (element) => element.style.fontWeight || null,
54
+ renderHTML: (attributes) =>
55
+ attributes.fontWeight
56
+ ? { style: `font-weight: ${attributes.fontWeight}` }
57
+ : {},
58
+ },
59
+ fontStyle: {
60
+ default: null,
61
+ parseHTML: (element) => element.style.fontStyle || null,
62
+ renderHTML: (attributes) =>
63
+ attributes.fontStyle
64
+ ? { style: `font-style: ${attributes.fontStyle}` }
65
+ : {},
66
+ },
67
+ textDecoration: {
68
+ default: null,
69
+ parseHTML: (element) => element.style.textDecoration || null,
70
+ renderHTML: (attributes) => {
71
+ if (!attributes.textDecoration) return {};
72
+
73
+ const className = this.options.renderTextDecorationClasses
74
+ ? rteTextDecorationClassName(
75
+ attributes.textDecoration,
76
+ attributes.textDecorationReset === true,
77
+ )
78
+ : undefined;
79
+
80
+ if (this.options.renderTextDecorationClasses)
81
+ return className ? { class: className } : {};
82
+
83
+ const value =
84
+ attributes.textDecoration === roleVarRef('textDecoration')
85
+ ? attributes.textDecoration
86
+ : composeTextDecoration(undefined, attributes.textDecoration);
87
+
88
+ return value ? { style: `text-decoration: ${value}` } : {};
89
+ },
90
+ },
91
+ textDecorationReset: {
92
+ default: null,
93
+ parseHTML: (element) =>
94
+ element.getAttribute('data-bp-text-decoration-reset') === 'true'
95
+ ? true
96
+ : null,
97
+ renderHTML: (attributes) =>
98
+ attributes.textDecorationReset
99
+ ? { 'data-bp-text-decoration-reset': 'true' }
100
+ : {},
101
+ },
102
+ },
103
+ },
104
+ ];
105
+ },
106
+
107
+ addCommands() {
108
+ return {
109
+ setFontWeight:
110
+ (fontWeight) =>
111
+ ({ chain }) =>
112
+ chain().setMark('textStyle', { fontWeight }).run(),
113
+ unsetFontWeight:
114
+ () =>
115
+ ({ chain }) =>
116
+ chain()
117
+ .setMark('textStyle', { fontWeight: null })
118
+ .removeEmptyTextStyle()
119
+ .run(),
120
+ setFontStyle:
121
+ (fontStyle) =>
122
+ ({ chain }) =>
123
+ chain().setMark('textStyle', { fontStyle }).run(),
124
+ unsetFontStyle:
125
+ () =>
126
+ ({ chain }) =>
127
+ chain()
128
+ .setMark('textStyle', { fontStyle: null })
129
+ .removeEmptyTextStyle()
130
+ .run(),
131
+ // A reset marker qualifies only the value it was written with; setMark merges attrs, so a
132
+ // new value must clear it or the run would drop its role's lines.
133
+ setTextDecoration:
134
+ (textDecoration) =>
135
+ ({ chain }) =>
136
+ chain()
137
+ .setMark('textStyle', { textDecoration, textDecorationReset: null })
138
+ .run(),
139
+ unsetTextDecoration:
140
+ () =>
141
+ ({ chain }) =>
142
+ chain()
143
+ .setMark('textStyle', {
144
+ textDecoration: null,
145
+ textDecorationReset: null,
146
+ })
147
+ .removeEmptyTextStyle()
148
+ .run(),
149
+ };
150
+ },
151
+ });
@@ -0,0 +1,27 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { DOMParser } from 'prosemirror-model';
3
+ import { Plugin, PluginKey } from 'prosemirror-state';
4
+
5
+ // The legacy bold/italic/underline/strike style rules misread the textStyle span's own styles on the
6
+ // per-keystroke DOM read-back, so the whole run is retyped with the armed format — see
7
+ // rich-text-editor.md. Paste keeps them: foreign HTML may carry bold only as a style.
8
+ export const ViewDomParser = Extension.create({
9
+ name: 'viewDomParser',
10
+
11
+ addProseMirrorPlugins() {
12
+ const schemaParser = DOMParser.fromSchema(this.editor.schema);
13
+
14
+ return [
15
+ new Plugin({
16
+ key: new PluginKey('viewDomParser'),
17
+ props: {
18
+ domParser: new DOMParser(
19
+ this.editor.schema,
20
+ schemaParser.rules.filter((rule) => 'tag' in rule),
21
+ ),
22
+ clipboardParser: schemaParser,
23
+ },
24
+ }),
25
+ ];
26
+ },
27
+ });
@@ -7,11 +7,13 @@ import ColorExtension from '@tiptap/extension-color';
7
7
  import Highlight from '@tiptap/extension-highlight';
8
8
  import Placeholder from '@tiptap/extension-placeholder';
9
9
  import Link from '@tiptap/extension-link';
10
- import { FontFamily } from './extensions/FontFamily';
11
- import { LetterSpacing } from './extensions/LetterSpacing';
12
- import { MaxLength } from './extensions/MaxLength';
13
- import { AutoLink } from './extensions/AutoLink';
14
- import { isHrefPageId } from './hyperlink';
10
+ import { FontFamily } from './rte-extensions/FontFamily';
11
+ import { LetterSpacing } from './rte-extensions/LetterSpacing';
12
+ import { TextEffects } from './rte-extensions/TextEffects';
13
+ import { MaxLength } from './rte-extensions/MaxLength';
14
+ import { ViewDomParser } from './rte-extensions/ViewDomParser';
15
+ import { AutoLink } from './rte-extensions/AutoLink';
16
+ import { isHrefPageId } from './rte-link.util';
15
17
 
16
18
  /**
17
19
  * Single source of truth for the Tiptap extension set (BP-5787).
@@ -23,27 +25,68 @@ import { isHrefPageId } from './hyperlink';
23
25
  *
24
26
  * Known, intentional differences are parameterised:
25
27
  * - `restrictStarterKit` — the live editor disables list/hr/code nodes.
26
- * - `editing` — only the live editor carries the Placeholder + MaxLength plugins
27
- * (neither affects serialised output; they are editing-time only).
28
+ * - `editing` — only the live editor carries the Placeholder, MaxLength and
29
+ * ViewDomParser plugins (none affects serialised output; they are editing-time only).
28
30
  *
29
31
  * Link target/rel are NOT parameterised: they are a pure function of the href
30
32
  * applied in the Link mark's renderHTML (below), so every consumer — live
31
33
  * editor, static renderer, schema check — emits identical link markup.
32
34
  */
35
+ /**
36
+ * The RTE schema is piecewise-constant across model-version ranges: it only changes when an
37
+ * extension is added, so every version between two change points shares one schema. Today the one
38
+ * change point is v22 — where `TextEffects` (weight/style/decoration on the `textStyle` mark) was
39
+ * added — giving two generations: below 22 is the pre-BP-5969 schema, 22-and-later (and the latest)
40
+ * carries TextEffects. Add the next version here if the schema grows.
41
+ *
42
+ * MIGRATION-22 SNAPSHOT DEPENDENCY: B1 parses v21 plain RTE strings with generation 22, so the
43
+ * extensions' `parseHTML` rules shape its output. Pinning the generation does not freeze those rules;
44
+ * after migration-22 releases, pin them in the migration before changing them.
45
+ */
46
+ const RTE_SCHEMA_CHANGE_VERSIONS = [22];
47
+
48
+ /**
49
+ * The schema generation a requested version resolves to: the highest change point at or below it
50
+ * (0 = the base schema). `undefined` = latest → the newest generation. So versions in the same
51
+ * range share one schema — asking for 5 or 20 both give the base — and callers cache one built
52
+ * schema per generation rather than per exact number.
53
+ */
54
+ export const rteSchemaGeneration = (schemaVersion?: number): number =>
55
+ RTE_SCHEMA_CHANGE_VERSIONS.reduce(
56
+ (generation, changeVersion) =>
57
+ // undefined = latest → reaches every change point → the newest generation.
58
+ schemaVersion === undefined || schemaVersion >= changeVersion
59
+ ? changeVersion
60
+ : generation,
61
+ 0,
62
+ );
63
+
33
64
  export interface RteExtensionOptions {
34
65
  /** Disable StarterKit nodes the editor doesn't use (lists, hr, code). */
35
66
  restrictStarterKit?: boolean;
36
- /** When present, add the live-editing-only plugins (Placeholder, MaxLength). */
67
+ /** When present, add the live-editing-only plugins (Placeholder, MaxLength, ViewDomParser). */
37
68
  editing?: {
38
69
  placeholder?: string;
39
70
  maxLength?: number;
40
71
  };
72
+ /**
73
+ * Pin the schema to a model version's extension set. A migration passes its own version so the
74
+ * parse reproduces that era's schema (see `rteSchemaGeneration`); omit for the latest (runtime).
75
+ */
76
+ schemaVersion?: number;
77
+ /** Render text-decoration marks as role-aware classes instead of inline styles. */
78
+ renderTextDecorationClasses?: boolean;
41
79
  }
42
80
 
43
81
  export const getRteExtensions = (
44
82
  options: RteExtensionOptions = {},
45
83
  ): Extensions => {
46
- const { restrictStarterKit = false, editing } = options;
84
+ const {
85
+ restrictStarterKit = false,
86
+ editing,
87
+ schemaVersion,
88
+ renderTextDecorationClasses = false,
89
+ } = options;
47
90
 
48
91
  const extensions: Extensions = [
49
92
  // v3 StarterKit bundles Link + Underline; we register both separately (with
@@ -93,6 +136,19 @@ export const getRteExtensions = (
93
136
  FontSize.configure({ types: ['textStyle'] }),
94
137
  LetterSpacing,
95
138
  LineHeight.configure({ types: ['textStyle'] }),
139
+ // BP-5969: weight / style / decoration as textStyle attrs (role var or literal override), so a
140
+ // role edit to any of them repaints linked RTE via the cascade — like family/size already do.
141
+ // TextEffects entered at v22 (RTE_SCHEMA_CHANGE_VERSIONS). Gated in place — not appended — so the
142
+ // latest schema's extension order is byte-unchanged; a parse resolving below 22 omits it,
143
+ // reproducing the pre-BP-5969 schema.
144
+ ...(rteSchemaGeneration(schemaVersion) >= 22
145
+ ? [
146
+ TextEffects.configure({
147
+ types: ['textStyle'],
148
+ renderTextDecorationClasses,
149
+ }),
150
+ ]
151
+ : []),
96
152
  ColorExtension.configure({
97
153
  types: ['textStyle'],
98
154
  }),
@@ -106,6 +162,7 @@ export const getRteExtensions = (
106
162
  extensions.push(
107
163
  Placeholder.configure({ placeholder: editing.placeholder }),
108
164
  MaxLength.configure({ maxLength: editing.maxLength }),
165
+ ViewDomParser,
109
166
  );
110
167
  }
111
168
 
@@ -0,0 +1,2 @@
1
+ export const isHrefPageId = (href: string): boolean =>
2
+ !!href && href.startsWith('pageid:');