@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
@@ -0,0 +1,473 @@
1
+ import { getSchema } from '@tiptap/core';
2
+ import type { JSONContent } from '@tiptap/vue-3';
3
+ import { Slice } from 'prosemirror-model';
4
+ import type { Schema } from 'prosemirror-model';
5
+ import type {
6
+ ColorItem,
7
+ GlobalTextStyleDeclaration,
8
+ TextStyleDeclaration,
9
+ } from '@brand-page';
10
+ import {
11
+ canonicalSolidHex,
12
+ isBlankColorValue,
13
+ isPaletteRoleId,
14
+ paletteRoleIdForToken,
15
+ resolveColorReference,
16
+ roleIdsByCanonicalValue,
17
+ toColorVarReference,
18
+ } from '@brand-page/utils/color-palette.util';
19
+ import {
20
+ ROLE_VAR_ATTRS,
21
+ roleVarRef,
22
+ runTypographyFillValue,
23
+ type RoleVarMarkAttr,
24
+ NEUTRAL_TYPOGRAPHY_VALUE,
25
+ } from '@shared/text-role-typography.util';
26
+ import { DEFAULT_LINK_COLOR } from '@src/constants/rich-text-editor.constants';
27
+ import { isRoleVarRef, normTypographyValue } from './rich-text-editor.util';
28
+ import { sanitizeRteJson } from './rte-sanitize.util';
29
+ import { emToPx } from './text.util';
30
+ import { getRteExtensions } from '@shared/rte-extensions.util';
31
+
32
+ /**
33
+ * Pure transforms for the maker RTE's copy, cut and paste. No editor, no DOM: every
34
+ * function here takes and returns Tiptap JSON (or a bare value), so `RteClipboard.ts`
35
+ * can call them from real clipboard events without this module knowing ProseMirror's
36
+ * live `Node`/`Mark` instances exist. Kept off the `brand-page-maker/utils` barrel
37
+ * (imported by path) — see `rich-text-editor.md` *Entry points* for why it stays out
38
+ * of `getRteExtensions`.
39
+ */
40
+
41
+ export const RTE_CLIPBOARD_MIME_TYPE = 'application/x-rte-slice';
42
+ export const RTE_CLIPBOARD_VERSION = 1 as const;
43
+
44
+ export interface RteClipboardContext {
45
+ /** The field's canonical role style, or undefined for a legacy/unlinked field. */
46
+ role: GlobalTextStyleDeclaration | undefined;
47
+ /** The field's own style object (whole-field overrides, colour, alignment). */
48
+ block: TextStyleDeclaration | undefined;
49
+ /** The site palette, for resolving and relinking colour references. */
50
+ colors: ColorItem[];
51
+ }
52
+
53
+ export type ResolvedRunStyle = Partial<Record<RoleVarMarkAttr, string>> & {
54
+ color?: string;
55
+ };
56
+
57
+ export interface RteClipboardSliceJSON {
58
+ content: JSONContent[];
59
+ openStart?: number;
60
+ openEnd?: number;
61
+ }
62
+
63
+ export interface RteClipboardPayload {
64
+ v: typeof RTE_CLIPBOARD_VERSION;
65
+ slice: RteClipboardSliceJSON;
66
+ }
67
+
68
+ type RteRunMark = { type: string; attrs?: Record<string, unknown> };
69
+
70
+ type RteRunNode = { marks?: RteRunMark[] };
71
+
72
+ /**
73
+ * The JSON-node twin of `runTypography` (`rich-text-editor.util.ts`): a run's own
74
+ * typography, falling back to a legacy semantic mark for un-migrated/pasted runs. Works
75
+ * on a Tiptap JSON node directly (no schema needed), because a copy/paste payload is
76
+ * JSON — never a live ProseMirror `Node` — end to end.
77
+ */
78
+ const runTypographyFromJson = (
79
+ node: RteRunNode,
80
+ ): Partial<Record<RoleVarMarkAttr, string>> => {
81
+ const marks = node.marks ?? [];
82
+ const textStyle = marks.find((mark) => mark.type === 'textStyle');
83
+ const attrOf = (attr: string): string | undefined => {
84
+ const value = textStyle?.attrs?.[attr];
85
+
86
+ return typeof value === 'string' && value !== '' ? value : undefined;
87
+ };
88
+ const has = (markType: string): boolean =>
89
+ marks.some((mark) => mark.type === markType);
90
+ const legacyDecoration =
91
+ [has('underline') && 'underline', has('strike') && 'line-through']
92
+ .filter(Boolean)
93
+ .join(' ') || undefined;
94
+
95
+ return {
96
+ fontFamily: attrOf('fontFamily'),
97
+ fontSize: attrOf('fontSize'),
98
+ lineHeight: attrOf('lineHeight'),
99
+ letterSpacing: attrOf('letterSpacing'),
100
+ fontWeight: attrOf('fontWeight') ?? (has('bold') ? 'bold' : undefined),
101
+ fontStyle: attrOf('fontStyle') ?? (has('italic') ? 'italic' : undefined),
102
+ textDecoration: attrOf('textDecoration') ?? legacyDecoration,
103
+ };
104
+ };
105
+
106
+ /**
107
+ * Resolve one typography attr the way the canvas renders it: the run's own value
108
+ * (a role ref resolved to the source role's value, or its neutral; a literal — including
109
+ * a legacy bold/italic/underline/strike mark — kept as written), else, for an attr the
110
+ * run doesn't carry, `runTypographyFillValue`'s whole-field fill, resolved the same way.
111
+ * Never invents a value the canvas wouldn't show (D2).
112
+ */
113
+ const resolveTypographyAttrForCopy = (
114
+ attr: RoleVarMarkAttr,
115
+ own: string | undefined,
116
+ role: GlobalTextStyleDeclaration | undefined,
117
+ block: TextStyleDeclaration | undefined,
118
+ ): string | undefined => {
119
+ const value =
120
+ own !== undefined
121
+ ? own
122
+ : runTypographyFillValue(
123
+ attr,
124
+ role as Partial<Record<RoleVarMarkAttr, string>> | undefined,
125
+ block as Partial<Record<RoleVarMarkAttr, string>> | undefined,
126
+ );
127
+
128
+ if (value === undefined) return undefined;
129
+
130
+ const resolved = isRoleVarRef(value)
131
+ ? (role?.[attr] ?? NEUTRAL_TYPOGRAPHY_VALUE[attr])
132
+ : value;
133
+
134
+ // A quoted family (`"Playfair Display"`, or a stack like `"Playfair Display", serif`)
135
+ // fails sanitizeRteJson's safe-CSS-value check and is dropped outright, not kept
136
+ // quoted — so strip every quote, not just an outer pair, rather than lose it.
137
+ return attr === 'fontFamily' ? resolved?.replace(/['"]+/g, '') : resolved;
138
+ };
139
+
140
+ /**
141
+ * Resolve a colour value (text or highlight) to what the canvas shows, in one
142
+ * normalised form: a legacy `logo-*` token maps to its palette role first; a
143
+ * `var(--id)` reference resolves against `colors` (a blank role reads as its default);
144
+ * a resolvable solid canonicalises to lowercase `#rrggbb`/`#rrggbbaa`. A reference the
145
+ * palette doesn't hold stays exactly as written (D3) — copy never invents a look the
146
+ * canvas doesn't have.
147
+ */
148
+ export const resolveRunColorForCopy = (
149
+ value: string | undefined,
150
+ colors: ColorItem[],
151
+ ): string | undefined => {
152
+ if (!value) return undefined;
153
+
154
+ const roleId = paletteRoleIdForToken(value);
155
+ const ref = roleId ? toColorVarReference(roleId) : value;
156
+ const resolved = resolveColorReference(ref, colors, {
157
+ withRoleDefaults: true,
158
+ });
159
+
160
+ return canonicalSolidHex(resolved) ?? resolved;
161
+ };
162
+
163
+ /**
164
+ * A run's typography and colour, resolved to what the canvas shows (A5): every role
165
+ * reference becomes a literal value, so the slice carries "what it looks like" rather
166
+ * than "what it's linked to" — the destination decides what re-links (see
167
+ * `relinkRunTypographyToRole`). An uncoloured run stays uncoloured (ADR-0020: no base
168
+ * coat) — colour has no whole-field fallback, unlike typography.
169
+ */
170
+ export const resolveRunStyleForCopy = (
171
+ node: RteRunNode,
172
+ context: RteClipboardContext,
173
+ ): ResolvedRunStyle => {
174
+ const own = runTypographyFromJson(node);
175
+ const style: ResolvedRunStyle = {};
176
+
177
+ for (const { markAttr } of ROLE_VAR_ATTRS) {
178
+ const value = resolveTypographyAttrForCopy(
179
+ markAttr,
180
+ own[markAttr],
181
+ context.role,
182
+ context.block,
183
+ );
184
+
185
+ if (value !== undefined) style[markAttr] = value;
186
+ }
187
+
188
+ const textStyle = node.marks?.find((mark) => mark.type === 'textStyle');
189
+ const color = resolveRunColorForCopy(
190
+ textStyle?.attrs?.color as string | undefined,
191
+ context.colors,
192
+ );
193
+
194
+ if (color !== undefined) style.color = color;
195
+
196
+ return style;
197
+ };
198
+
199
+ /**
200
+ * The external (`text/html`, other apps) reading of a run: the same resolved look, with
201
+ * `fontSize` converted from em to px at the 16px root (the toolbar's own readout) so an
202
+ * app with no `--role-*`/em context still shows the right size, and the run's link href
203
+ * (if any) carried through untouched.
204
+ */
205
+ export const resolveRunStyleForExternal = (
206
+ node: RteRunNode,
207
+ context: RteClipboardContext,
208
+ ): ResolvedRunStyle & { href?: string } => {
209
+ const style = resolveRunStyleForCopy(node, context);
210
+ const link = (node.marks ?? []).find((mark) => mark.type === 'link');
211
+ const href = link?.attrs?.href as string | undefined;
212
+ const fontSizePx = sizeToPx(style.fontSize);
213
+
214
+ return {
215
+ ...style,
216
+ ...(fontSizePx !== undefined ? { fontSize: `${fontSizePx}px` } : {}),
217
+ ...(href ? { href } : {}),
218
+ };
219
+ };
220
+
221
+ const SIZE_UNIT = /^(-?[\d.]+)(px|em)$/;
222
+
223
+ /** A typography value's px size at the 16px root, or undefined for anything else. */
224
+ const sizeToPx = (value: string | undefined): number | undefined => {
225
+ const match = value?.trim().match(SIZE_UNIT);
226
+
227
+ if (!match) return undefined;
228
+
229
+ const [, amount, unit] = match;
230
+
231
+ return unit === 'px' ? parseFloat(amount) : parseFloat(emToPx(`${amount}em`));
232
+ };
233
+
234
+ /**
235
+ * "Same value written differently" (A6): family ignores quoting, weight/style/
236
+ * decoration/spacing treat their CSS-neutral keyword as equal to unset, and — local to
237
+ * this comparator, so the asterisk and relink paths don't widen — `fontSize` compares
238
+ * as px at the 16px root, so `1.375em` and `22px` are one size.
239
+ */
240
+ export const isSameTypographyValue = (
241
+ attr: RoleVarMarkAttr,
242
+ a: string | undefined,
243
+ b: string | undefined,
244
+ ): boolean => {
245
+ if (attr === 'fontSize') {
246
+ const pxA = sizeToPx(a);
247
+
248
+ return pxA !== undefined && pxA === sizeToPx(b);
249
+ }
250
+
251
+ return normTypographyValue(attr, a) === normTypographyValue(attr, b);
252
+ };
253
+
254
+ /**
255
+ * Relink a resolved run to the destination role (A5 step 2, R2): a value equal to the
256
+ * destination's (or its neutral) becomes the role var, so it keeps following that role;
257
+ * any other value stays the run's own literal. With no canonical role at the
258
+ * destination, every value stays literal — `roleVarOrLiteral`'s rule, applied per run
259
+ * instead of at the mutation point. An attr the copy left absent stays absent.
260
+ */
261
+ export const relinkRunTypographyToRole = (
262
+ resolved: ResolvedRunStyle,
263
+ destinationRole: GlobalTextStyleDeclaration | undefined,
264
+ ): ResolvedRunStyle => {
265
+ const relinked: ResolvedRunStyle = { ...resolved };
266
+
267
+ if (!destinationRole) return relinked;
268
+
269
+ for (const { markAttr } of ROLE_VAR_ATTRS) {
270
+ const value = resolved[markAttr];
271
+
272
+ if (value === undefined) continue;
273
+
274
+ relinked[markAttr] = isSameTypographyValue(
275
+ markAttr,
276
+ value,
277
+ destinationRole[markAttr],
278
+ )
279
+ ? roleVarRef(markAttr)!
280
+ : value;
281
+ }
282
+
283
+ return relinked;
284
+ };
285
+
286
+ /**
287
+ * Relink a resolved colour to the destination palette (A5 step 3, R3, D3). On a link
288
+ * run, the fixed link colour is never remapped, so a coincidental match doesn't mint a
289
+ * spurious reference. Otherwise (including a non-link run that happens to equal the
290
+ * fixed link colour): a destination palette ROLE holding the same canonical value wins
291
+ * first (lowest index — `roleIdsByCanonicalValue`'s tie-break), then a custom in stored
292
+ * order (blanks skipped); with no match, the canonical hex stays fixed and nothing is
293
+ * added to the palette.
294
+ */
295
+ export const relinkColorToPalette = (
296
+ canonicalHex: string,
297
+ colors: ColorItem[],
298
+ isLinkColor = false,
299
+ ): string => {
300
+ if (isLinkColor && canonicalHex === DEFAULT_LINK_COLOR) return canonicalHex;
301
+
302
+ const roleId = roleIdsByCanonicalValue(colors).get(canonicalHex);
303
+
304
+ if (roleId) return toColorVarReference(roleId);
305
+
306
+ const custom = colors.find(
307
+ (color) =>
308
+ !isPaletteRoleId(color.id) &&
309
+ !isBlankColorValue(color.value) &&
310
+ canonicalSolidHex(color.value) === canonicalHex,
311
+ );
312
+
313
+ return custom ? toColorVarReference(custom.id) : canonicalHex;
314
+ };
315
+
316
+ /**
317
+ * Every paragraph/heading a paste touches takes the destination's alignment (Reading
318
+ * 14) — overriding whatever the source paragraphs carried. With no destination
319
+ * alignment resolved, the source's own alignment is cleared rather than left in place:
320
+ * an open-ended LAST paragraph merges into the following text using the SLICE's own
321
+ * attrs, so a leftover source alignment would repaint the destination's own trailing
322
+ * text — the open-ended FIRST paragraph merges the other way, keeping the destination
323
+ * paragraph's own attrs untouched.
324
+ */
325
+ export const alignPastedParagraphs = (
326
+ content: JSONContent[],
327
+ destinationAlign: string | undefined,
328
+ ): JSONContent[] =>
329
+ content.map((node) => {
330
+ if (node.type !== 'paragraph' && node.type !== 'heading') return node;
331
+
332
+ const { textAlign: _sourceAlign, ...attrs } = (node.attrs ?? {}) as {
333
+ textAlign?: string;
334
+ };
335
+
336
+ return {
337
+ ...node,
338
+ attrs: destinationAlign
339
+ ? { ...attrs, textAlign: destinationAlign }
340
+ : attrs,
341
+ };
342
+ });
343
+
344
+ const LINE_BREAK_RUN = /(?:\r\n?|\n)+/;
345
+
346
+ /**
347
+ * A plain-text (no valid own-editor form) paste's paragraphs (Approach step 4): split on
348
+ * runs of line breaks — prosemirror-view's own rule — dropping empty pieces, each line
349
+ * becomes a paragraph carrying the caller's marks (the seed a first type, or the
350
+ * paste-point's marks, would take) and the destination's alignment. Open at both ends,
351
+ * so the first and last line join the surrounding text. `null` for text with no visible
352
+ * line (nothing to insert).
353
+ */
354
+ export const plainTextToParagraphSlice = (
355
+ text: string,
356
+ marks: RteRunMark[],
357
+ textAlign: string | undefined,
358
+ ): RteClipboardSliceJSON | null => {
359
+ const lines = text.split(LINE_BREAK_RUN).filter((line) => line !== '');
360
+
361
+ if (!lines.length) return null;
362
+
363
+ return {
364
+ content: lines.map((line) => ({
365
+ type: 'paragraph',
366
+ ...(textAlign ? { attrs: { textAlign } } : {}),
367
+ content: [
368
+ {
369
+ type: 'text',
370
+ text: line,
371
+ ...(marks.length ? { marks } : {}),
372
+ },
373
+ ],
374
+ })),
375
+ openStart: 1,
376
+ openEnd: 1,
377
+ };
378
+ };
379
+
380
+ // The ProseMirror schema a paste is validated against: the SAME extension set the live
381
+ // maker editor mounts (`restrictStarterKit`), so a node/mark the editor lacks — lists,
382
+ // code — fails here exactly as it would fail reaching the real editor. `getSchema` is
383
+ // DOM-less (mirrors `rte-schema-check.ts`), so this stays a pure check; built once and
384
+ // cached.
385
+ let cachedRteClipboardSchema: Schema | undefined;
386
+
387
+ const getRteClipboardSchema = (): Schema =>
388
+ (cachedRteClipboardSchema ??= getSchema(
389
+ getRteExtensions({ restrictStarterKit: true }),
390
+ ));
391
+
392
+ const canonicalSliceJSON = (
393
+ sliceJson: RteClipboardSliceJSON,
394
+ ): RteClipboardSliceJSON => {
395
+ const sanitized = sanitizeRteJson({
396
+ type: 'doc',
397
+ content: sliceJson.content,
398
+ });
399
+
400
+ return {
401
+ content: sanitized.content ?? [],
402
+ ...(sliceJson.openStart ? { openStart: sliceJson.openStart } : {}),
403
+ ...(sliceJson.openEnd ? { openEnd: sliceJson.openEnd } : {}),
404
+ };
405
+ };
406
+
407
+ /**
408
+ * Validate a clipboard string as our own, un-tampered `x-rte-slice` payload (R13): it
409
+ * parses, its version is ours, and it is byte-for-byte its own `sanitizeRteJson` form —
410
+ * an unsafe link or CSS value, an unknown mark, or even a key reordered from the
411
+ * sanitised form changes it and fails this. It must also build against the live editor
412
+ * schema — catching a node/mark `sanitizeRteJson`'s broader allowlist accepts but this
413
+ * editor's restricted schema doesn't (lists, code). `Slice.fromJSON` alone only checks
414
+ * that node/mark types exist; it neither validates a node's content against its type's
415
+ * content expression nor its mark set, and it accepts any `openStart`/`openEnd` number —
416
+ * fractional included — regardless of the content's actual depth — so every top-level node
417
+ * is also `check()`ed, and the open depths must be integers bounded by `Slice.maxOpen`. Any
418
+ * failure returns `null`, so the caller falls back to the text-only path instead of
419
+ * inserting a malformed slice.
420
+ */
421
+ export const parseOwnRteClipboardPayload = (
422
+ raw: string,
423
+ ): RteClipboardPayload | null => {
424
+ let candidate: unknown;
425
+
426
+ try {
427
+ candidate = JSON.parse(raw);
428
+ } catch {
429
+ return null;
430
+ }
431
+
432
+ if (
433
+ !candidate ||
434
+ typeof candidate !== 'object' ||
435
+ (candidate as { v?: unknown }).v !== RTE_CLIPBOARD_VERSION
436
+ ) {
437
+ return null;
438
+ }
439
+
440
+ const slice = (candidate as { slice?: unknown }).slice;
441
+
442
+ if (!slice || typeof slice !== 'object') return null;
443
+
444
+ const canonical: RteClipboardPayload = {
445
+ v: RTE_CLIPBOARD_VERSION,
446
+ slice: canonicalSliceJSON(slice as RteClipboardSliceJSON),
447
+ };
448
+
449
+ if (JSON.stringify(candidate) !== JSON.stringify(canonical)) return null;
450
+
451
+ try {
452
+ const parsed = Slice.fromJSON(getRteClipboardSchema(), slice);
453
+
454
+ parsed.content.forEach((node) => node.check());
455
+
456
+ const maxOpen = Slice.maxOpen(parsed.content);
457
+
458
+ if (
459
+ !Number.isInteger(parsed.openStart) ||
460
+ !Number.isInteger(parsed.openEnd) ||
461
+ parsed.openStart < 0 ||
462
+ parsed.openEnd < 0 ||
463
+ parsed.openStart > maxOpen.openStart ||
464
+ parsed.openEnd > maxOpen.openEnd
465
+ ) {
466
+ return null;
467
+ }
468
+ } catch {
469
+ return null;
470
+ }
471
+
472
+ return canonical;
473
+ };
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect, afterEach } from 'vitest';
2
- import { Editor } from '@tiptap/vue-3';
3
- import { getRteExtensions } from '../composables/rich-text-editor/getRteExtensions';
4
- import { toRteJson, renderRteToHtml } from './rte-render.util';
2
+ import { Editor, type JSONContent } from '@tiptap/vue-3';
3
+ import { getRteExtensions } from '@shared/rte-extensions.util';
4
+ import { toRteJson, renderRteToHtml } from '@shared/rte-render.util';
5
5
  import { sanitizeRteJson } from './rte-sanitize.util';
6
6
 
7
7
  /**
@@ -61,6 +61,102 @@ describe('RTE features — mark nesting (decoration must inherit font-size)', ()
61
61
  });
62
62
 
63
63
  describe('RTE features — textStyle attrs (colour/font/spacing)', () => {
64
+ it('keeps text-decoration in JSON and emits a class only for role-aware rendering', () => {
65
+ const doc = {
66
+ type: 'doc',
67
+ content: [
68
+ {
69
+ type: 'paragraph',
70
+ content: [
71
+ {
72
+ type: 'text',
73
+ text: 'x',
74
+ marks: [
75
+ {
76
+ type: 'textStyle',
77
+ attrs: { textDecoration: 'line-through' },
78
+ },
79
+ ],
80
+ },
81
+ ],
82
+ },
83
+ ],
84
+ };
85
+
86
+ expect(doc.content[0].content[0].marks[0].attrs.textDecoration).toBe(
87
+ 'line-through',
88
+ );
89
+ const storedDoc = JSON.stringify(doc);
90
+
91
+ expect(renderRteToHtml(doc)).toContain('text-decoration: line-through');
92
+ expect(renderRteToHtml(doc, { textDecorationClasses: true })).toContain(
93
+ 'class="bp-rte-text-decoration-linethrough"',
94
+ );
95
+ expect(JSON.stringify(doc)).toBe(storedDoc);
96
+ });
97
+
98
+ it('keeps a role-reset decoration valid for renderers that do not know the reset marker', () => {
99
+ const doc = {
100
+ type: 'doc',
101
+ content: [
102
+ {
103
+ type: 'paragraph',
104
+ content: [
105
+ {
106
+ type: 'text',
107
+ text: 'x',
108
+ marks: [
109
+ {
110
+ type: 'textStyle',
111
+ attrs: {
112
+ textDecoration: 'line-through',
113
+ textDecorationReset: true,
114
+ },
115
+ },
116
+ ],
117
+ },
118
+ ],
119
+ },
120
+ ],
121
+ };
122
+
123
+ expect(renderRteToHtml(doc)).toContain('text-decoration: line-through');
124
+ expect(renderRteToHtml(doc)).not.toContain('none line-through');
125
+ expect(renderRteToHtml(doc, { textDecorationClasses: true })).toContain(
126
+ 'class="bp-rte-text-decoration-reset-linethrough"',
127
+ );
128
+ });
129
+
130
+ const decoratedDoc = (textDecoration: string): JSONContent => ({
131
+ type: 'doc',
132
+ content: [
133
+ {
134
+ type: 'paragraph',
135
+ content: [
136
+ {
137
+ type: 'text',
138
+ text: 'x',
139
+ marks: [{ type: 'textStyle', attrs: { textDecoration } }],
140
+ },
141
+ ],
142
+ },
143
+ ],
144
+ });
145
+
146
+ it('keeps the role text-decoration link as written in style rendering', () => {
147
+ const html = renderRteToHtml(decoratedDoc('var(--role-text-decoration)'));
148
+
149
+ expect(html).toContain('text-decoration: var(--role-text-decoration)');
150
+ expect(html).not.toContain('undefined');
151
+ });
152
+
153
+ it('composes a literal text-decoration in style rendering', () => {
154
+ const html = renderRteToHtml(decoratedDoc('none underline'));
155
+
156
+ expect(html).toContain('text-decoration: underline');
157
+ expect(html).not.toContain('none underline');
158
+ });
159
+
64
160
  it('rgb colour is preserved', () => {
65
161
  expect(
66
162
  pipe('<p><span style="color: rgb(255, 0, 0)">x</span></p>'),
@@ -5,7 +5,7 @@ import {
5
5
  renderRteToHtml,
6
6
  toRteJson,
7
7
  getRteJsonPlainText,
8
- } from './rte-render.util';
8
+ } from '@shared/rte-render.util';
9
9
  import {
10
10
  COMPLEX_RTE_HTML,
11
11
  THEME_TOKEN_REF,