@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,4 @@
1
+ import type { JSONContent } from '@tiptap/vue-3';
2
+ import type { Content, TextStyleOptions } from '@brand-page';
3
+ export declare const docHasTextRun: (doc: JSONContent) => boolean;
4
+ export declare const authorContentRteFields: (content: Content, textStyleOptions?: TextStyleOptions) => void;
@@ -0,0 +1,101 @@
1
+ import { rteStyleFieldsFor, pairedRteTextField, } from '@shared/color-strategies/rte-field-pairs';
2
+ import { setRteTextColor } from '@shared/color-strategies/rte-color';
3
+ import { plainTextToRteJson, isTiptapDocument, } from '@shared/rte-render.util';
4
+ import { isCanonicalLinked } from './rich-text-editor.util';
5
+ import { roleVarRef, ROLE_VAR_ATTRS } from '@shared/text-role-typography.util';
6
+ /** The linked role's style for a field's `textStyleType`, for the defined-attr check below. */
7
+ const roleStyleFor = (options, textStyleType) => textStyleType && options
8
+ ? options[textStyleType]?.style
9
+ : undefined;
10
+ /**
11
+ * BP-5969 — reference the role's typography on every run of a canonical-linked authored doc, so
12
+ * new content matches migration output: the mark names the reference (self-describing, and the
13
+ * editor reads it without reaching into the store), and it follows role edits via the cascade.
14
+ * A ref is emitted ONLY for an attr the role actually defines — mirroring `buildInitialMarks` and
15
+ * migration `stripLiftRteDoc`, so authored and migrated runs share one shape (no reference to a
16
+ * `--role-*` var the role class never emits). No role style (options absent) → no refs.
17
+ */
18
+ const applyRoleTypographyVars = (doc, roleStyle) => {
19
+ const refs = ROLE_VAR_ATTRS.flatMap(({ markAttr }) => {
20
+ const ref = roleVarRef(markAttr);
21
+ return ref && roleStyle?.[markAttr]
22
+ ? [[markAttr, ref]]
23
+ : [];
24
+ });
25
+ if (!refs.length)
26
+ return;
27
+ const walk = (node) => {
28
+ if (node.type === 'text') {
29
+ const marks = (node.marks ??= []);
30
+ let textStyle = marks.find((mark) => mark.type === 'textStyle');
31
+ if (!textStyle) {
32
+ textStyle = { type: 'textStyle', attrs: {} };
33
+ marks.push(textStyle);
34
+ }
35
+ textStyle.attrs = { ...(textStyle.attrs ?? {}) };
36
+ for (const [attr, ref] of refs)
37
+ textStyle.attrs[attr] = ref;
38
+ }
39
+ node.content?.forEach(walk);
40
+ };
41
+ walk(doc);
42
+ };
43
+ // True when the doc has at least one text run — i.e. somewhere for a run mark (colour) to live.
44
+ export const docHasTextRun = (doc) => {
45
+ const walk = (node) => node.type === 'text' ? true : (node.content ?? []).some(walk);
46
+ return walk(doc);
47
+ };
48
+ /**
49
+ * Author (or enrich) one RTE field into its final doc: bake the resolved element colour into the run
50
+ * mark and reference the role's typography on every run, matching migration output.
51
+ *
52
+ * The field's value is either an already-authored doc — the BP-5969 factory source (`rteDoc`) — or a
53
+ * plain string (legacy / AI callers); both normalise to a doc here. `undefined` for empty/absent
54
+ * input so callers can leave the field alone.
55
+ */
56
+ const authorRteDoc = (value, style, roleStyle) => {
57
+ let doc = isTiptapDocument(value)
58
+ ? value
59
+ : plainTextToRteJson(value);
60
+ if (!doc)
61
+ return undefined;
62
+ // Colour rides the run mark — but ONLY when there is a run. An empty doc (empty field) has no text
63
+ // node to hold a mark, so its colour stays on `style.color` until the user types (the editor's
64
+ // `buildInitialMarks` seeds the first run from it); stripping it here would strand it.
65
+ if (style?.color && docHasTextRun(doc)) {
66
+ doc = setRteTextColor(doc, style.color) ?? doc;
67
+ delete style.color; // colour now lives in the mark (matches migration step G)
68
+ }
69
+ if (style?.textAlign) {
70
+ for (const block of doc.content ?? []) {
71
+ block.attrs = { ...(block.attrs ?? {}), textAlign: style.textAlign };
72
+ }
73
+ }
74
+ // Canonical-linked: reference the role's (defined) typography on every run.
75
+ if (isCanonicalLinked(style))
76
+ applyRoleTypographyVars(doc, roleStyle);
77
+ return doc;
78
+ };
79
+ export const authorContentRteFields = (content,
80
+ // Role definitions, so a run references only the attrs its role actually defines (matches
81
+ // migration output). Absent → no typography refs (colour/textAlign still authored).
82
+ textStyleOptions) => {
83
+ const fields = content;
84
+ for (const styleField of rteStyleFieldsFor(content.type)) {
85
+ const textField = pairedRteTextField(content.type, styleField);
86
+ if (!textField)
87
+ continue;
88
+ const style = fields[styleField];
89
+ const doc = authorRteDoc(fields[textField], style, roleStyleFor(textStyleOptions, style?.textStyleType));
90
+ if (doc)
91
+ fields[textField] = doc;
92
+ }
93
+ const textItems = fields.textItems;
94
+ if (Array.isArray(textItems)) {
95
+ for (const item of textItems) {
96
+ const doc = authorRteDoc(item.text, item.textStyle, roleStyleFor(textStyleOptions, item.textStyle?.textStyleType));
97
+ if (doc)
98
+ item.text = doc;
99
+ }
100
+ }
101
+ };
@@ -0,0 +1,126 @@
1
+ import type { JSONContent } from '@tiptap/vue-3';
2
+ import type { ColorItem, GlobalTextStyleDeclaration, TextStyleDeclaration } from '@brand-page';
3
+ import { type RoleVarMarkAttr } from '@shared/text-role-typography.util';
4
+ /**
5
+ * Pure transforms for the maker RTE's copy, cut and paste. No editor, no DOM: every
6
+ * function here takes and returns Tiptap JSON (or a bare value), so `RteClipboard.ts`
7
+ * can call them from real clipboard events without this module knowing ProseMirror's
8
+ * live `Node`/`Mark` instances exist. Kept off the `brand-page-maker/utils` barrel
9
+ * (imported by path) — see `rich-text-editor.md` *Entry points* for why it stays out
10
+ * of `getRteExtensions`.
11
+ */
12
+ export declare const RTE_CLIPBOARD_MIME_TYPE = "application/x-rte-slice";
13
+ export declare const RTE_CLIPBOARD_VERSION: 1;
14
+ export interface RteClipboardContext {
15
+ /** The field's canonical role style, or undefined for a legacy/unlinked field. */
16
+ role: GlobalTextStyleDeclaration | undefined;
17
+ /** The field's own style object (whole-field overrides, colour, alignment). */
18
+ block: TextStyleDeclaration | undefined;
19
+ /** The site palette, for resolving and relinking colour references. */
20
+ colors: ColorItem[];
21
+ }
22
+ export type ResolvedRunStyle = Partial<Record<RoleVarMarkAttr, string>> & {
23
+ color?: string;
24
+ };
25
+ export interface RteClipboardSliceJSON {
26
+ content: JSONContent[];
27
+ openStart?: number;
28
+ openEnd?: number;
29
+ }
30
+ export interface RteClipboardPayload {
31
+ v: typeof RTE_CLIPBOARD_VERSION;
32
+ slice: RteClipboardSliceJSON;
33
+ }
34
+ type RteRunMark = {
35
+ type: string;
36
+ attrs?: Record<string, unknown>;
37
+ };
38
+ type RteRunNode = {
39
+ marks?: RteRunMark[];
40
+ };
41
+ /**
42
+ * Resolve a colour value (text or highlight) to what the canvas shows, in one
43
+ * normalised form: a legacy `logo-*` token maps to its palette role first; a
44
+ * `var(--id)` reference resolves against `colors` (a blank role reads as its default);
45
+ * a resolvable solid canonicalises to lowercase `#rrggbb`/`#rrggbbaa`. A reference the
46
+ * palette doesn't hold stays exactly as written (D3) — copy never invents a look the
47
+ * canvas doesn't have.
48
+ */
49
+ export declare const resolveRunColorForCopy: (value: string | undefined, colors: ColorItem[]) => string | undefined;
50
+ /**
51
+ * A run's typography and colour, resolved to what the canvas shows (A5): every role
52
+ * reference becomes a literal value, so the slice carries "what it looks like" rather
53
+ * than "what it's linked to" — the destination decides what re-links (see
54
+ * `relinkRunTypographyToRole`). An uncoloured run stays uncoloured (ADR-0020: no base
55
+ * coat) — colour has no whole-field fallback, unlike typography.
56
+ */
57
+ export declare const resolveRunStyleForCopy: (node: RteRunNode, context: RteClipboardContext) => ResolvedRunStyle;
58
+ /**
59
+ * The external (`text/html`, other apps) reading of a run: the same resolved look, with
60
+ * `fontSize` converted from em to px at the 16px root (the toolbar's own readout) so an
61
+ * app with no `--role-*`/em context still shows the right size, and the run's link href
62
+ * (if any) carried through untouched.
63
+ */
64
+ export declare const resolveRunStyleForExternal: (node: RteRunNode, context: RteClipboardContext) => ResolvedRunStyle & {
65
+ href?: string;
66
+ };
67
+ /**
68
+ * "Same value written differently" (A6): family ignores quoting, weight/style/
69
+ * decoration/spacing treat their CSS-neutral keyword as equal to unset, and — local to
70
+ * this comparator, so the asterisk and relink paths don't widen — `fontSize` compares
71
+ * as px at the 16px root, so `1.375em` and `22px` are one size.
72
+ */
73
+ export declare const isSameTypographyValue: (attr: RoleVarMarkAttr, a: string | undefined, b: string | undefined) => boolean;
74
+ /**
75
+ * Relink a resolved run to the destination role (A5 step 2, R2): a value equal to the
76
+ * destination's (or its neutral) becomes the role var, so it keeps following that role;
77
+ * any other value stays the run's own literal. With no canonical role at the
78
+ * destination, every value stays literal — `roleVarOrLiteral`'s rule, applied per run
79
+ * instead of at the mutation point. An attr the copy left absent stays absent.
80
+ */
81
+ export declare const relinkRunTypographyToRole: (resolved: ResolvedRunStyle, destinationRole: GlobalTextStyleDeclaration | undefined) => ResolvedRunStyle;
82
+ /**
83
+ * Relink a resolved colour to the destination palette (A5 step 3, R3, D3). On a link
84
+ * run, the fixed link colour is never remapped, so a coincidental match doesn't mint a
85
+ * spurious reference. Otherwise (including a non-link run that happens to equal the
86
+ * fixed link colour): a destination palette ROLE holding the same canonical value wins
87
+ * first (lowest index — `roleIdsByCanonicalValue`'s tie-break), then a custom in stored
88
+ * order (blanks skipped); with no match, the canonical hex stays fixed and nothing is
89
+ * added to the palette.
90
+ */
91
+ export declare const relinkColorToPalette: (canonicalHex: string, colors: ColorItem[], isLinkColor?: boolean) => string;
92
+ /**
93
+ * Every paragraph/heading a paste touches takes the destination's alignment (Reading
94
+ * 14) — overriding whatever the source paragraphs carried. With no destination
95
+ * alignment resolved, the source's own alignment is cleared rather than left in place:
96
+ * an open-ended LAST paragraph merges into the following text using the SLICE's own
97
+ * attrs, so a leftover source alignment would repaint the destination's own trailing
98
+ * text — the open-ended FIRST paragraph merges the other way, keeping the destination
99
+ * paragraph's own attrs untouched.
100
+ */
101
+ export declare const alignPastedParagraphs: (content: JSONContent[], destinationAlign: string | undefined) => JSONContent[];
102
+ /**
103
+ * A plain-text (no valid own-editor form) paste's paragraphs (Approach step 4): split on
104
+ * runs of line breaks — prosemirror-view's own rule — dropping empty pieces, each line
105
+ * becomes a paragraph carrying the caller's marks (the seed a first type, or the
106
+ * paste-point's marks, would take) and the destination's alignment. Open at both ends,
107
+ * so the first and last line join the surrounding text. `null` for text with no visible
108
+ * line (nothing to insert).
109
+ */
110
+ export declare const plainTextToParagraphSlice: (text: string, marks: RteRunMark[], textAlign: string | undefined) => RteClipboardSliceJSON | null;
111
+ /**
112
+ * Validate a clipboard string as our own, un-tampered `x-rte-slice` payload (R13): it
113
+ * parses, its version is ours, and it is byte-for-byte its own `sanitizeRteJson` form —
114
+ * an unsafe link or CSS value, an unknown mark, or even a key reordered from the
115
+ * sanitised form changes it and fails this. It must also build against the live editor
116
+ * schema — catching a node/mark `sanitizeRteJson`'s broader allowlist accepts but this
117
+ * editor's restricted schema doesn't (lists, code). `Slice.fromJSON` alone only checks
118
+ * that node/mark types exist; it neither validates a node's content against its type's
119
+ * content expression nor its mark set, and it accepts any `openStart`/`openEnd` number —
120
+ * fractional included — regardless of the content's actual depth — so every top-level node
121
+ * is also `check()`ed, and the open depths must be integers bounded by `Slice.maxOpen`. Any
122
+ * failure returns `null`, so the caller falls back to the text-only path instead of
123
+ * inserting a malformed slice.
124
+ */
125
+ export declare const parseOwnRteClipboardPayload: (raw: string) => RteClipboardPayload | null;
126
+ export {};
@@ -0,0 +1,307 @@
1
+ import { getSchema } from '@tiptap/core';
2
+ import { Slice } from 'prosemirror-model';
3
+ import { canonicalSolidHex, isBlankColorValue, isPaletteRoleId, paletteRoleIdForToken, resolveColorReference, roleIdsByCanonicalValue, toColorVarReference, } from '@brand-page/utils/color-palette.util';
4
+ import { ROLE_VAR_ATTRS, roleVarRef, runTypographyFillValue, NEUTRAL_TYPOGRAPHY_VALUE, } from '@shared/text-role-typography.util';
5
+ import { DEFAULT_LINK_COLOR } from '@src/constants/rich-text-editor.constants';
6
+ import { isRoleVarRef, normTypographyValue } from './rich-text-editor.util';
7
+ import { sanitizeRteJson } from './rte-sanitize.util';
8
+ import { emToPx } from './text.util';
9
+ import { getRteExtensions } from '@shared/rte-extensions.util';
10
+ /**
11
+ * Pure transforms for the maker RTE's copy, cut and paste. No editor, no DOM: every
12
+ * function here takes and returns Tiptap JSON (or a bare value), so `RteClipboard.ts`
13
+ * can call them from real clipboard events without this module knowing ProseMirror's
14
+ * live `Node`/`Mark` instances exist. Kept off the `brand-page-maker/utils` barrel
15
+ * (imported by path) — see `rich-text-editor.md` *Entry points* for why it stays out
16
+ * of `getRteExtensions`.
17
+ */
18
+ export const RTE_CLIPBOARD_MIME_TYPE = 'application/x-rte-slice';
19
+ export const RTE_CLIPBOARD_VERSION = 1;
20
+ /**
21
+ * The JSON-node twin of `runTypography` (`rich-text-editor.util.ts`): a run's own
22
+ * typography, falling back to a legacy semantic mark for un-migrated/pasted runs. Works
23
+ * on a Tiptap JSON node directly (no schema needed), because a copy/paste payload is
24
+ * JSON — never a live ProseMirror `Node` — end to end.
25
+ */
26
+ const runTypographyFromJson = (node) => {
27
+ const marks = node.marks ?? [];
28
+ const textStyle = marks.find((mark) => mark.type === 'textStyle');
29
+ const attrOf = (attr) => {
30
+ const value = textStyle?.attrs?.[attr];
31
+ return typeof value === 'string' && value !== '' ? value : undefined;
32
+ };
33
+ const has = (markType) => marks.some((mark) => mark.type === markType);
34
+ const legacyDecoration = [has('underline') && 'underline', has('strike') && 'line-through']
35
+ .filter(Boolean)
36
+ .join(' ') || undefined;
37
+ return {
38
+ fontFamily: attrOf('fontFamily'),
39
+ fontSize: attrOf('fontSize'),
40
+ lineHeight: attrOf('lineHeight'),
41
+ letterSpacing: attrOf('letterSpacing'),
42
+ fontWeight: attrOf('fontWeight') ?? (has('bold') ? 'bold' : undefined),
43
+ fontStyle: attrOf('fontStyle') ?? (has('italic') ? 'italic' : undefined),
44
+ textDecoration: attrOf('textDecoration') ?? legacyDecoration,
45
+ };
46
+ };
47
+ /**
48
+ * Resolve one typography attr the way the canvas renders it: the run's own value
49
+ * (a role ref resolved to the source role's value, or its neutral; a literal — including
50
+ * a legacy bold/italic/underline/strike mark — kept as written), else, for an attr the
51
+ * run doesn't carry, `runTypographyFillValue`'s whole-field fill, resolved the same way.
52
+ * Never invents a value the canvas wouldn't show (D2).
53
+ */
54
+ const resolveTypographyAttrForCopy = (attr, own, role, block) => {
55
+ const value = own !== undefined
56
+ ? own
57
+ : runTypographyFillValue(attr, role, block);
58
+ if (value === undefined)
59
+ return undefined;
60
+ const resolved = isRoleVarRef(value)
61
+ ? (role?.[attr] ?? NEUTRAL_TYPOGRAPHY_VALUE[attr])
62
+ : value;
63
+ // A quoted family (`"Playfair Display"`, or a stack like `"Playfair Display", serif`)
64
+ // fails sanitizeRteJson's safe-CSS-value check and is dropped outright, not kept
65
+ // quoted — so strip every quote, not just an outer pair, rather than lose it.
66
+ return attr === 'fontFamily' ? resolved?.replace(/['"]+/g, '') : resolved;
67
+ };
68
+ /**
69
+ * Resolve a colour value (text or highlight) to what the canvas shows, in one
70
+ * normalised form: a legacy `logo-*` token maps to its palette role first; a
71
+ * `var(--id)` reference resolves against `colors` (a blank role reads as its default);
72
+ * a resolvable solid canonicalises to lowercase `#rrggbb`/`#rrggbbaa`. A reference the
73
+ * palette doesn't hold stays exactly as written (D3) — copy never invents a look the
74
+ * canvas doesn't have.
75
+ */
76
+ export const resolveRunColorForCopy = (value, colors) => {
77
+ if (!value)
78
+ return undefined;
79
+ const roleId = paletteRoleIdForToken(value);
80
+ const ref = roleId ? toColorVarReference(roleId) : value;
81
+ const resolved = resolveColorReference(ref, colors, {
82
+ withRoleDefaults: true,
83
+ });
84
+ return canonicalSolidHex(resolved) ?? resolved;
85
+ };
86
+ /**
87
+ * A run's typography and colour, resolved to what the canvas shows (A5): every role
88
+ * reference becomes a literal value, so the slice carries "what it looks like" rather
89
+ * than "what it's linked to" — the destination decides what re-links (see
90
+ * `relinkRunTypographyToRole`). An uncoloured run stays uncoloured (ADR-0020: no base
91
+ * coat) — colour has no whole-field fallback, unlike typography.
92
+ */
93
+ export const resolveRunStyleForCopy = (node, context) => {
94
+ const own = runTypographyFromJson(node);
95
+ const style = {};
96
+ for (const { markAttr } of ROLE_VAR_ATTRS) {
97
+ const value = resolveTypographyAttrForCopy(markAttr, own[markAttr], context.role, context.block);
98
+ if (value !== undefined)
99
+ style[markAttr] = value;
100
+ }
101
+ const textStyle = node.marks?.find((mark) => mark.type === 'textStyle');
102
+ const color = resolveRunColorForCopy(textStyle?.attrs?.color, context.colors);
103
+ if (color !== undefined)
104
+ style.color = color;
105
+ return style;
106
+ };
107
+ /**
108
+ * The external (`text/html`, other apps) reading of a run: the same resolved look, with
109
+ * `fontSize` converted from em to px at the 16px root (the toolbar's own readout) so an
110
+ * app with no `--role-*`/em context still shows the right size, and the run's link href
111
+ * (if any) carried through untouched.
112
+ */
113
+ export const resolveRunStyleForExternal = (node, context) => {
114
+ const style = resolveRunStyleForCopy(node, context);
115
+ const link = (node.marks ?? []).find((mark) => mark.type === 'link');
116
+ const href = link?.attrs?.href;
117
+ const fontSizePx = sizeToPx(style.fontSize);
118
+ return {
119
+ ...style,
120
+ ...(fontSizePx !== undefined ? { fontSize: `${fontSizePx}px` } : {}),
121
+ ...(href ? { href } : {}),
122
+ };
123
+ };
124
+ const SIZE_UNIT = /^(-?[\d.]+)(px|em)$/;
125
+ /** A typography value's px size at the 16px root, or undefined for anything else. */
126
+ const sizeToPx = (value) => {
127
+ const match = value?.trim().match(SIZE_UNIT);
128
+ if (!match)
129
+ return undefined;
130
+ const [, amount, unit] = match;
131
+ return unit === 'px' ? parseFloat(amount) : parseFloat(emToPx(`${amount}em`));
132
+ };
133
+ /**
134
+ * "Same value written differently" (A6): family ignores quoting, weight/style/
135
+ * decoration/spacing treat their CSS-neutral keyword as equal to unset, and — local to
136
+ * this comparator, so the asterisk and relink paths don't widen — `fontSize` compares
137
+ * as px at the 16px root, so `1.375em` and `22px` are one size.
138
+ */
139
+ export const isSameTypographyValue = (attr, a, b) => {
140
+ if (attr === 'fontSize') {
141
+ const pxA = sizeToPx(a);
142
+ return pxA !== undefined && pxA === sizeToPx(b);
143
+ }
144
+ return normTypographyValue(attr, a) === normTypographyValue(attr, b);
145
+ };
146
+ /**
147
+ * Relink a resolved run to the destination role (A5 step 2, R2): a value equal to the
148
+ * destination's (or its neutral) becomes the role var, so it keeps following that role;
149
+ * any other value stays the run's own literal. With no canonical role at the
150
+ * destination, every value stays literal — `roleVarOrLiteral`'s rule, applied per run
151
+ * instead of at the mutation point. An attr the copy left absent stays absent.
152
+ */
153
+ export const relinkRunTypographyToRole = (resolved, destinationRole) => {
154
+ const relinked = { ...resolved };
155
+ if (!destinationRole)
156
+ return relinked;
157
+ for (const { markAttr } of ROLE_VAR_ATTRS) {
158
+ const value = resolved[markAttr];
159
+ if (value === undefined)
160
+ continue;
161
+ relinked[markAttr] = isSameTypographyValue(markAttr, value, destinationRole[markAttr])
162
+ ? roleVarRef(markAttr)
163
+ : value;
164
+ }
165
+ return relinked;
166
+ };
167
+ /**
168
+ * Relink a resolved colour to the destination palette (A5 step 3, R3, D3). On a link
169
+ * run, the fixed link colour is never remapped, so a coincidental match doesn't mint a
170
+ * spurious reference. Otherwise (including a non-link run that happens to equal the
171
+ * fixed link colour): a destination palette ROLE holding the same canonical value wins
172
+ * first (lowest index — `roleIdsByCanonicalValue`'s tie-break), then a custom in stored
173
+ * order (blanks skipped); with no match, the canonical hex stays fixed and nothing is
174
+ * added to the palette.
175
+ */
176
+ export const relinkColorToPalette = (canonicalHex, colors, isLinkColor = false) => {
177
+ if (isLinkColor && canonicalHex === DEFAULT_LINK_COLOR)
178
+ return canonicalHex;
179
+ const roleId = roleIdsByCanonicalValue(colors).get(canonicalHex);
180
+ if (roleId)
181
+ return toColorVarReference(roleId);
182
+ const custom = colors.find((color) => !isPaletteRoleId(color.id) &&
183
+ !isBlankColorValue(color.value) &&
184
+ canonicalSolidHex(color.value) === canonicalHex);
185
+ return custom ? toColorVarReference(custom.id) : canonicalHex;
186
+ };
187
+ /**
188
+ * Every paragraph/heading a paste touches takes the destination's alignment (Reading
189
+ * 14) — overriding whatever the source paragraphs carried. With no destination
190
+ * alignment resolved, the source's own alignment is cleared rather than left in place:
191
+ * an open-ended LAST paragraph merges into the following text using the SLICE's own
192
+ * attrs, so a leftover source alignment would repaint the destination's own trailing
193
+ * text — the open-ended FIRST paragraph merges the other way, keeping the destination
194
+ * paragraph's own attrs untouched.
195
+ */
196
+ export const alignPastedParagraphs = (content, destinationAlign) => content.map((node) => {
197
+ if (node.type !== 'paragraph' && node.type !== 'heading')
198
+ return node;
199
+ const { textAlign: _sourceAlign, ...attrs } = (node.attrs ?? {});
200
+ return {
201
+ ...node,
202
+ attrs: destinationAlign
203
+ ? { ...attrs, textAlign: destinationAlign }
204
+ : attrs,
205
+ };
206
+ });
207
+ const LINE_BREAK_RUN = /(?:\r\n?|\n)+/;
208
+ /**
209
+ * A plain-text (no valid own-editor form) paste's paragraphs (Approach step 4): split on
210
+ * runs of line breaks — prosemirror-view's own rule — dropping empty pieces, each line
211
+ * becomes a paragraph carrying the caller's marks (the seed a first type, or the
212
+ * paste-point's marks, would take) and the destination's alignment. Open at both ends,
213
+ * so the first and last line join the surrounding text. `null` for text with no visible
214
+ * line (nothing to insert).
215
+ */
216
+ export const plainTextToParagraphSlice = (text, marks, textAlign) => {
217
+ const lines = text.split(LINE_BREAK_RUN).filter((line) => line !== '');
218
+ if (!lines.length)
219
+ return null;
220
+ return {
221
+ content: lines.map((line) => ({
222
+ type: 'paragraph',
223
+ ...(textAlign ? { attrs: { textAlign } } : {}),
224
+ content: [
225
+ {
226
+ type: 'text',
227
+ text: line,
228
+ ...(marks.length ? { marks } : {}),
229
+ },
230
+ ],
231
+ })),
232
+ openStart: 1,
233
+ openEnd: 1,
234
+ };
235
+ };
236
+ // The ProseMirror schema a paste is validated against: the SAME extension set the live
237
+ // maker editor mounts (`restrictStarterKit`), so a node/mark the editor lacks — lists,
238
+ // code — fails here exactly as it would fail reaching the real editor. `getSchema` is
239
+ // DOM-less (mirrors `rte-schema-check.ts`), so this stays a pure check; built once and
240
+ // cached.
241
+ let cachedRteClipboardSchema;
242
+ const getRteClipboardSchema = () => (cachedRteClipboardSchema ??= getSchema(getRteExtensions({ restrictStarterKit: true })));
243
+ const canonicalSliceJSON = (sliceJson) => {
244
+ const sanitized = sanitizeRteJson({
245
+ type: 'doc',
246
+ content: sliceJson.content,
247
+ });
248
+ return {
249
+ content: sanitized.content ?? [],
250
+ ...(sliceJson.openStart ? { openStart: sliceJson.openStart } : {}),
251
+ ...(sliceJson.openEnd ? { openEnd: sliceJson.openEnd } : {}),
252
+ };
253
+ };
254
+ /**
255
+ * Validate a clipboard string as our own, un-tampered `x-rte-slice` payload (R13): it
256
+ * parses, its version is ours, and it is byte-for-byte its own `sanitizeRteJson` form —
257
+ * an unsafe link or CSS value, an unknown mark, or even a key reordered from the
258
+ * sanitised form changes it and fails this. It must also build against the live editor
259
+ * schema — catching a node/mark `sanitizeRteJson`'s broader allowlist accepts but this
260
+ * editor's restricted schema doesn't (lists, code). `Slice.fromJSON` alone only checks
261
+ * that node/mark types exist; it neither validates a node's content against its type's
262
+ * content expression nor its mark set, and it accepts any `openStart`/`openEnd` number —
263
+ * fractional included — regardless of the content's actual depth — so every top-level node
264
+ * is also `check()`ed, and the open depths must be integers bounded by `Slice.maxOpen`. Any
265
+ * failure returns `null`, so the caller falls back to the text-only path instead of
266
+ * inserting a malformed slice.
267
+ */
268
+ export const parseOwnRteClipboardPayload = (raw) => {
269
+ let candidate;
270
+ try {
271
+ candidate = JSON.parse(raw);
272
+ }
273
+ catch {
274
+ return null;
275
+ }
276
+ if (!candidate ||
277
+ typeof candidate !== 'object' ||
278
+ candidate.v !== RTE_CLIPBOARD_VERSION) {
279
+ return null;
280
+ }
281
+ const slice = candidate.slice;
282
+ if (!slice || typeof slice !== 'object')
283
+ return null;
284
+ const canonical = {
285
+ v: RTE_CLIPBOARD_VERSION,
286
+ slice: canonicalSliceJSON(slice),
287
+ };
288
+ if (JSON.stringify(candidate) !== JSON.stringify(canonical))
289
+ return null;
290
+ try {
291
+ const parsed = Slice.fromJSON(getRteClipboardSchema(), slice);
292
+ parsed.content.forEach((node) => node.check());
293
+ const maxOpen = Slice.maxOpen(parsed.content);
294
+ if (!Number.isInteger(parsed.openStart) ||
295
+ !Number.isInteger(parsed.openEnd) ||
296
+ parsed.openStart < 0 ||
297
+ parsed.openEnd < 0 ||
298
+ parsed.openStart > maxOpen.openStart ||
299
+ parsed.openEnd > maxOpen.openEnd) {
300
+ return null;
301
+ }
302
+ }
303
+ catch {
304
+ return null;
305
+ }
306
+ return canonical;
307
+ };
@@ -42,15 +42,20 @@ const ALLOWED_MARK_TYPES = new Set([
42
42
  'highlight',
43
43
  'link',
44
44
  ]);
45
- // textStyle attrs map to the allow-listed CSS properties (font-weight →
46
- // bold mark, text-decoration → underline/strike, text-align → node attr,
47
- // background-color → highlight, so they are intentionally not here).
45
+ // textStyle attrs map to the allow-listed CSS properties. BP-5969: font-weight / font-style /
46
+ // text-decoration are now textStyle attrs (role var or literal), NOT semantic <strong>/<u>/<s>
47
+ // marks, so a role edit propagates via the cascade. text-align → node attr and background-color →
48
+ // highlight are still intentionally not here.
48
49
  const ALLOWED_TEXT_STYLE_ATTRS = new Set([
49
50
  'color',
50
51
  'fontFamily',
51
52
  'fontSize',
52
53
  'letterSpacing',
53
54
  'lineHeight',
55
+ 'fontWeight',
56
+ 'fontStyle',
57
+ 'textDecoration',
58
+ 'textDecorationReset',
54
59
  ]);
55
60
  /**
56
61
  * A safe CSS value is a short string free of characters that could inject an
@@ -70,6 +75,11 @@ const sanitizeTextStyleAttrs = (attrs) => {
70
75
  if (!ALLOWED_TEXT_STYLE_ATTRS.has(key))
71
76
  continue;
72
77
  const value = attrs[key];
78
+ if (key === 'textDecorationReset') {
79
+ if (value === true)
80
+ clean[key] = true;
81
+ continue;
82
+ }
73
83
  // Tiptap emits '' for unset textStyle slots — preserve them.
74
84
  if (value === '' || value == null) {
75
85
  clean[key] = '';