@designcrowd/library.brand-page 6.0.26-json-prereq-2 → 6.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/src/{CreatedOnBrandCrowd-de-de-CKBqjDH3.js → CreatedOnBrandCrowd-de-de-DU6YEVcW.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-CRXiimvT.js → CreatedOnBrandCrowd-en-us-DNWWK6Tj.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-DCYdY6sj.js → CreatedOnBrandCrowd-es-es-DVFvV9Qp.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-Dk7LOhxE.js → CreatedOnBrandCrowd-fr-ca-B4ZkjNdw.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-Dk7LOhxE.js → CreatedOnBrandCrowd-fr-fr-B4ZkjNdw.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-Cp4ufHJP.js → CreatedOnBrandCrowd-pt-br-DP7AQGgW.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-Cp4ufHJP.js → CreatedOnBrandCrowd-pt-pt-DP7AQGgW.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-ZSLkWMwM.js → CreatedOnDcom-de-de-CaC3GtG9.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-BgdIGfT3.js → CreatedOnDcom-en-us-D16yT0-P.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-D0KemkCZ.js → CreatedOnDcom-es-es-DA5sHgD_.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-BuwNjNbC.js → CreatedOnDcom-fr-ca-CDv2SG1-.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-DCQcsFPf.js → CreatedOnDcom-fr-fr-Cygc7c5d.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-DD-oLAS1.js → CreatedOnDcom-pt-br-B_3RIzgF.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-D8qLq2wW.js → CreatedOnDcom-pt-pt-Bz5w-rrD.js} +1 -1
- package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +2 -5
- package/lib/src/brand-page/models/index.d.ts +26 -34
- package/lib/src/brand-page/utils/migration.util.js +0 -11
- package/lib/src/brand-page/utils/text.util.d.ts +1 -1
- package/lib/src/brand-page/utils/text.util.js +0 -32
- package/lib/src/brand-page/utils/vcard.util.js +4 -4
- package/lib/src/brand-page/utils/view-model.util.d.ts +0 -1
- package/lib/src/brand-page/utils/view-model.util.js +20 -68
- package/lib/src/brand-page/view-models.d.ts +3 -3
- package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.d.ts +9 -2
- package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.js +10 -6
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.d.ts +20 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.js +44 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.d.ts +27 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.js +44 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +103 -24
- package/lib/src/brand-page-maker/utils/index.d.ts +0 -2
- package/lib/src/brand-page-maker/utils/index.js +0 -2
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +5 -28
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +5 -48
- package/lib/src/brand-page-maker/validators/field.validator.js +2 -10
- package/lib/src/css/library.brand-page-brandCrowd.min.css +39 -39
- package/lib/src/css/library.brand-page-brandPage.min.css +39 -39
- package/lib/src/css/library.brand-page-designCom.min.css +39 -39
- package/lib/src/css/library.brand-page-preview.min.css +39 -39
- package/lib/src/index.d.ts +0 -1
- package/lib/src/index.mjs +138 -143
- package/lib/src/{lib-Db6j9fQZ.js → lib-6_P6kXPu.js} +51709 -55194
- package/lib/src/lib.js +0 -2
- package/lib/src/metadata-builder/ai-metadata-executor.d.ts +1 -0
- package/lib/src/metadata-builder/ai-metadata-executor.js +19 -0
- package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +4 -3
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +2 -1
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +2 -1
- package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +4 -3
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +2 -1
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +11 -15
- package/lib/src/metadata-builder/builders/update-content-text-builder.d.ts +17 -0
- package/lib/src/metadata-builder/builders/update-content-text-builder.js +103 -0
- package/lib/src/metadata-builder/builders/update-content-text-style-builder.d.ts +16 -0
- package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +216 -0
- package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +13 -11
- package/lib/src/metadata-builder/helpers/rte.helpers.js +73 -14
- package/lib/src/metadata-builder/metadata-executor.js +4 -0
- package/lib/src/metadata-builder/models.d.ts +2 -0
- package/lib/src/metadata-builder/models.js +2 -0
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +19 -0
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +4 -0
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +8 -7
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +52 -21
- package/lib/src/shared/content-settings/components/GenericTextInput.mixin.js +1 -14
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +3 -12
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +2 -3
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.js +3 -10
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +1 -2
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +1 -4
- package/lib/src/utils/minify-brand-page-metadata.js +1 -4
- package/package.json +15 -17
- package/src/brand-page/components/contact-form/ContactForm.mixin.ts +2 -5
- package/src/brand-page/components/text-wrapper/TextWrapper.vue +6 -17
- package/src/brand-page/models/index.ts +26 -35
- package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -3
- package/src/brand-page/utils/migration.util.ts +0 -12
- package/src/brand-page/utils/style.util.test.ts +0 -51
- package/src/brand-page/utils/text.util.ts +4 -43
- package/src/brand-page/utils/vcard.util.ts +4 -6
- package/src/brand-page/utils/view-model.util.ts +26 -94
- package/src/brand-page/view-models.ts +2 -3
- package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +3 -4
- package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +1 -0
- package/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.ts +10 -6
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.ts +73 -0
- package/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.ts +85 -0
- package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +111 -27
- package/src/brand-page-maker/utils/index.ts +0 -2
- package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +3 -37
- package/src/brand-page-maker/utils/rich-text-editor.util.ts +11 -66
- package/src/brand-page-maker/validators/field.validator.ts +2 -10
- package/src/lib.ts +0 -9
- package/src/metadata-builder/ai-metadata-executor.ts +26 -0
- package/src/metadata-builder/builders/section-builders/about-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +5 -2
- package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +4 -3
- package/src/metadata-builder/builders/section-builders/images-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +2 -1
- package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +2 -1
- package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +6 -3
- package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +2 -1
- package/src/metadata-builder/builders/section-builders/text-section-builder.ts +13 -19
- package/src/metadata-builder/builders/update-content-text-builder.ts +148 -0
- package/src/metadata-builder/builders/update-content-text-style-builder.ts +352 -0
- package/src/metadata-builder/helpers/rte.helpers.ts +101 -15
- package/src/metadata-builder/metadata-executor.ts +5 -0
- package/src/metadata-builder/models.ts +3 -0
- package/src/metadata-builder/parsers/ai-toolcall-parser.ts +27 -0
- package/src/metadata-builder/sanitizers/rte-schema-check.ts +53 -24
- package/src/shared/content-settings/components/GenericTextInput.mixin.ts +1 -17
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +3 -16
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.ts +4 -13
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +4 -6
- package/src/shared/content-settings/components/text-image-field/TextImageField.vue +3 -6
- package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +1 -6
- package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +1 -1
- package/src/utils/minify-brand-page-metadata.ts +1 -4
- package/lib/src/brand-page/utils/migration/migration-20.d.ts +0 -2
- package/lib/src/brand-page/utils/migration/migration-20.js +0 -66
- package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.d.ts +0 -22
- package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.js +0 -22
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.d.ts +0 -14
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.js +0 -39
- package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
- package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.js +0 -90
- package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -63
- package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -95
- package/lib/src/brand-page-maker/utils/rte-sanitize.util.d.ts +0 -6
- package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +0 -158
- package/src/brand-page/utils/migration/migration-20.server.test.ts +0 -125
- package/src/brand-page/utils/migration/migration-20.test.ts +0 -72
- package/src/brand-page/utils/migration/migration-20.ts +0 -87
- package/src/brand-page/utils/text.util.test.ts +0 -47
- package/src/brand-page/utils/view-model.pageid-rte.test.ts +0 -104
- package/src/brand-page-maker/__fixtures__/complex-rte.fixture.ts +0 -23
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +0 -52
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.ts +0 -42
- package/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.ts +0 -137
- package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +0 -202
- package/src/brand-page-maker/utils/rte-features.test.ts +0 -351
- package/src/brand-page-maker/utils/rte-render-parity.test.ts +0 -157
- package/src/brand-page-maker/utils/rte-render.util.ts +0 -165
- package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +0 -158
- package/src/brand-page-maker/utils/rte-sanitize.util.ts +0 -195
- package/src/brand-page-maker/validators/field.validator.test.ts +0 -55
|
@@ -119,7 +119,7 @@ import {
|
|
|
119
119
|
getRouteNameByPageIndex,
|
|
120
120
|
getRouteParamsByPage,
|
|
121
121
|
} from './route.util';
|
|
122
|
-
import { hasRTEContent
|
|
122
|
+
import { hasRTEContent } from '../../brand-page-maker/utils';
|
|
123
123
|
import {
|
|
124
124
|
getPageIdFromHref,
|
|
125
125
|
isHrefPageId,
|
|
@@ -1519,86 +1519,6 @@ const mapPageIdReferencesToRelativePaths = (
|
|
|
1519
1519
|
});
|
|
1520
1520
|
};
|
|
1521
1521
|
|
|
1522
|
-
// Resolve a `pageid:<id>` internal-link href to the published relative path.
|
|
1523
|
-
// Returns the resolved href, or null when `href` is not an internal pageid link
|
|
1524
|
-
// (external/absolute links are left untouched). Falls back to the site root when
|
|
1525
|
-
// the pageid can't be matched to a nav route.
|
|
1526
|
-
const resolvePageIdHref = (
|
|
1527
|
-
href: string,
|
|
1528
|
-
nav: NavViewModel,
|
|
1529
|
-
options: ViewModelMappingOptions,
|
|
1530
|
-
): string | null => {
|
|
1531
|
-
// Only process internal links (no protocol, doesn't start with /)
|
|
1532
|
-
if (!href || href.match(/^(https?:\/\/|\/)/) || !isHrefPageId(href)) {
|
|
1533
|
-
return null;
|
|
1534
|
-
}
|
|
1535
|
-
|
|
1536
|
-
const pageId = getPageIdFromHref(href);
|
|
1537
|
-
const route = findNavItemByPageId(nav.navItems, pageId);
|
|
1538
|
-
const brandPageSlugRoute = options.brandPageSlug
|
|
1539
|
-
? `/${options.brandPageSlug}`
|
|
1540
|
-
: '/';
|
|
1541
|
-
|
|
1542
|
-
if (route) {
|
|
1543
|
-
if (route.isRoot) {
|
|
1544
|
-
return brandPageSlugRoute;
|
|
1545
|
-
}
|
|
1546
|
-
|
|
1547
|
-
return `${brandPageSlugRoute}${brandPageSlugRoute === '/' ? '' : '/'}${route.relativePath}`;
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
// fallback to root if pageid cannot be resolved.
|
|
1551
|
-
return brandPageSlugRoute;
|
|
1552
|
-
};
|
|
1553
|
-
|
|
1554
|
-
// BP-5847: walk a Tiptap JSON doc and rewrite every link mark whose href is a
|
|
1555
|
-
// `pageid:` reference into its published relative path. Returns a NEW doc when
|
|
1556
|
-
// something changed (so the shared model doc is never mutated), else the same
|
|
1557
|
-
// reference.
|
|
1558
|
-
export const resolvePageIdsInRteJson = (
|
|
1559
|
-
doc: unknown,
|
|
1560
|
-
nav: NavViewModel,
|
|
1561
|
-
options: ViewModelMappingOptions,
|
|
1562
|
-
): unknown => {
|
|
1563
|
-
let changed = false;
|
|
1564
|
-
|
|
1565
|
-
const walk = (node: any): any => {
|
|
1566
|
-
if (!node || typeof node !== 'object') {
|
|
1567
|
-
return node;
|
|
1568
|
-
}
|
|
1569
|
-
|
|
1570
|
-
let next = node;
|
|
1571
|
-
|
|
1572
|
-
if (Array.isArray(node.marks)) {
|
|
1573
|
-
const marks = node.marks.map((mark: any) => {
|
|
1574
|
-
if (mark?.type === 'link' && typeof mark.attrs?.href === 'string') {
|
|
1575
|
-
const resolved = resolvePageIdHref(mark.attrs.href, nav, options);
|
|
1576
|
-
|
|
1577
|
-
if (resolved !== null) {
|
|
1578
|
-
changed = true;
|
|
1579
|
-
|
|
1580
|
-
return { ...mark, attrs: { ...mark.attrs, href: resolved } };
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
return mark;
|
|
1585
|
-
});
|
|
1586
|
-
|
|
1587
|
-
next = { ...next, marks };
|
|
1588
|
-
}
|
|
1589
|
-
|
|
1590
|
-
if (Array.isArray(node.content)) {
|
|
1591
|
-
next = { ...next, content: node.content.map(walk) };
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
return next;
|
|
1595
|
-
};
|
|
1596
|
-
|
|
1597
|
-
const result = walk(doc);
|
|
1598
|
-
|
|
1599
|
-
return changed ? result : doc;
|
|
1600
|
-
};
|
|
1601
|
-
|
|
1602
1522
|
const dynamicallyMapPageIdInHyperlinksToRelativePaths = (
|
|
1603
1523
|
content: any,
|
|
1604
1524
|
nav: NavViewModel,
|
|
@@ -1611,15 +1531,7 @@ const dynamicallyMapPageIdInHyperlinksToRelativePaths = (
|
|
|
1611
1531
|
return;
|
|
1612
1532
|
}
|
|
1613
1533
|
|
|
1614
|
-
if (
|
|
1615
|
-
// BP-5847: RTE fields may now be Tiptap JSON. Resolve pageid link marks
|
|
1616
|
-
// here too, or internal links render as raw `pageid:` and don't navigate.
|
|
1617
|
-
(content as unknown as Record<string, unknown>)[key] =
|
|
1618
|
-
resolvePageIdsInRteJson(value, nav, options);
|
|
1619
|
-
} else if (
|
|
1620
|
-
typeof value === 'object' &&
|
|
1621
|
-
(key === 'items' || key === 'textItems')
|
|
1622
|
-
) {
|
|
1534
|
+
if (typeof value === 'object' && (key === 'items' || key === 'textItems')) {
|
|
1623
1535
|
if (Array.isArray(value)) {
|
|
1624
1536
|
value.forEach((item) => {
|
|
1625
1537
|
dynamicallyMapPageIdInHyperlinksToRelativePaths(item, nav, options);
|
|
@@ -1631,11 +1543,31 @@ const dynamicallyMapPageIdInHyperlinksToRelativePaths = (
|
|
|
1631
1543
|
(content as unknown as Record<string, unknown>)[key] = value.replace(
|
|
1632
1544
|
/<a\s+([^>]*?)href="([^"]*?)"([^>]*?)>/gi,
|
|
1633
1545
|
(match, existingAttrsStart, href, existingAttrsEnd) => {
|
|
1634
|
-
|
|
1546
|
+
// Only process internal links (no protocol, doesn't start with /)
|
|
1547
|
+
if (href && !href.match(/^(https?:\/\/|\/)/) && isHrefPageId(href)) {
|
|
1548
|
+
const pageId = getPageIdFromHref(href);
|
|
1549
|
+
|
|
1550
|
+
const route = findNavItemByPageId(nav.navItems, pageId);
|
|
1551
|
+
|
|
1552
|
+
const brandPageSlugRoute = options.brandPageSlug
|
|
1553
|
+
? `/${options.brandPageSlug}`
|
|
1554
|
+
: '/';
|
|
1555
|
+
|
|
1556
|
+
if (route) {
|
|
1557
|
+
let href = `${brandPageSlugRoute}`;
|
|
1558
|
+
|
|
1559
|
+
if (!route.isRoot) {
|
|
1560
|
+
href = `${brandPageSlugRoute}${brandPageSlugRoute === '/' ? '' : '/'}${route.relativePath}`;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
return `<a ${existingAttrsStart}href="${href}"${existingAttrsEnd}>`;
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
// fallback to root if pageid cannot be resolved.
|
|
1567
|
+
return `<a ${existingAttrsStart}href="${brandPageSlugRoute}"${existingAttrsEnd}>`;
|
|
1568
|
+
}
|
|
1635
1569
|
|
|
1636
|
-
return
|
|
1637
|
-
? match
|
|
1638
|
-
: `<a ${existingAttrsStart}href="${resolved}"${existingAttrsEnd}>`;
|
|
1570
|
+
return match;
|
|
1639
1571
|
},
|
|
1640
1572
|
);
|
|
1641
1573
|
}
|
|
@@ -41,7 +41,6 @@ import type {
|
|
|
41
41
|
BackgroundShape,
|
|
42
42
|
PersonalisationRole,
|
|
43
43
|
SaveContactOptions,
|
|
44
|
-
RichTextValue,
|
|
45
44
|
} from './models';
|
|
46
45
|
import type { ImagesSectionContentDisplayStyle } from './constants';
|
|
47
46
|
|
|
@@ -197,8 +196,8 @@ export interface TextImageSectionViewModel {
|
|
|
197
196
|
id: string;
|
|
198
197
|
type: 'images-section';
|
|
199
198
|
role: ContentType;
|
|
200
|
-
title:
|
|
201
|
-
description:
|
|
199
|
+
title: string;
|
|
200
|
+
description: string;
|
|
202
201
|
displayStyle: ImagesSectionContentDisplayStyle;
|
|
203
202
|
aspectRatio: AspectRatio;
|
|
204
203
|
areImagesFullWidth: boolean;
|
|
@@ -384,7 +384,7 @@
|
|
|
384
384
|
<div class="tw-relative" :class="{ 'editor-compact': isCompact }">
|
|
385
385
|
<BubbleMenu
|
|
386
386
|
:editor="editor"
|
|
387
|
-
:options="
|
|
387
|
+
:tippy-options="tippyOptions"
|
|
388
388
|
:update-delay="0"
|
|
389
389
|
:should-show="shouldShow"
|
|
390
390
|
class="tw-w-fit"
|
|
@@ -453,8 +453,7 @@ import {
|
|
|
453
453
|
ButtonGroup,
|
|
454
454
|
TextInput,
|
|
455
455
|
} from '@designcrowd/fe-shared-lib';
|
|
456
|
-
import { EditorContent } from '@tiptap/vue-3';
|
|
457
|
-
import { BubbleMenu } from '@tiptap/vue-3/menus';
|
|
456
|
+
import { EditorContent, BubbleMenu } from '@tiptap/vue-3';
|
|
458
457
|
import { useRichTextEditor } from '../../composables/rich-text-editor/useRichTextEditor';
|
|
459
458
|
import FontPicker from '@shared/font-family-selector/FontPicker.vue';
|
|
460
459
|
import ColorField from '@shared/content-settings/components/color-field/ColorField.vue';
|
|
@@ -952,7 +951,7 @@ const {
|
|
|
952
951
|
hyperlinkValue,
|
|
953
952
|
setHyperlinkUrlValue,
|
|
954
953
|
shouldShow,
|
|
955
|
-
|
|
954
|
+
tippyOptions,
|
|
956
955
|
handleAdminColorChange,
|
|
957
956
|
} = useRichTextEditor(
|
|
958
957
|
model,
|
|
@@ -33,6 +33,7 @@ export function useAiMetadataBuilder(logger: Logger) {
|
|
|
33
33
|
model: BrandPageModel,
|
|
34
34
|
aiAssistantToolCall: AiAssistantToolCall[],
|
|
35
35
|
options: {
|
|
36
|
+
maxCharacters?: number;
|
|
36
37
|
/**
|
|
37
38
|
* Invoked by the UndoBuilder to resolve the pre-prompt snapshot.
|
|
38
39
|
* Required when the response includes an `undo` tool call.
|
|
@@ -23,16 +23,20 @@ export const useBubbleMenu = (
|
|
|
23
23
|
return false;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// zIndex) is either the v3 default or handled in CSS.
|
|
29
|
-
const bubbleMenuOptions = {
|
|
26
|
+
const tippyOptions = {
|
|
27
|
+
duration: 100,
|
|
30
28
|
placement: 'bottom' as const,
|
|
31
|
-
|
|
29
|
+
interactive: true,
|
|
30
|
+
appendTo: 'parent' as const,
|
|
31
|
+
hideOnClick: false,
|
|
32
|
+
arrow: false,
|
|
33
|
+
offset: [0, 10] as [number, number],
|
|
34
|
+
trigger: 'manual' as const,
|
|
35
|
+
zIndex: 10,
|
|
32
36
|
};
|
|
33
37
|
|
|
34
38
|
return {
|
|
35
39
|
shouldShow,
|
|
36
|
-
|
|
40
|
+
tippyOptions,
|
|
37
41
|
};
|
|
38
42
|
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
import '@tiptap/extension-text-style';
|
|
3
|
+
|
|
4
|
+
export type FontSizeOptions = {
|
|
5
|
+
types: string[];
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
declare module '@tiptap/core' {
|
|
9
|
+
interface Commands<ReturnType> {
|
|
10
|
+
fontSize: {
|
|
11
|
+
/**
|
|
12
|
+
* Set the font size
|
|
13
|
+
*/
|
|
14
|
+
setFontSize: (fontSize: string) => ReturnType;
|
|
15
|
+
/**
|
|
16
|
+
* Unset the font size
|
|
17
|
+
*/
|
|
18
|
+
unsetFontSize: () => ReturnType;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const FontSize = Extension.create<FontSizeOptions>({
|
|
24
|
+
name: 'fontSize',
|
|
25
|
+
|
|
26
|
+
addOptions() {
|
|
27
|
+
return {
|
|
28
|
+
types: ['textStyle'],
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
addGlobalAttributes() {
|
|
33
|
+
return [
|
|
34
|
+
{
|
|
35
|
+
types: this.options.types,
|
|
36
|
+
attributes: {
|
|
37
|
+
fontSize: {
|
|
38
|
+
default: null,
|
|
39
|
+
parseHTML: (element) =>
|
|
40
|
+
element.style.fontSize.replace(/['"]+/g, ''),
|
|
41
|
+
renderHTML: (attributes) => {
|
|
42
|
+
if (!attributes.fontSize) {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
style: `font-size: ${attributes.fontSize}`,
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
addCommands() {
|
|
57
|
+
return {
|
|
58
|
+
setFontSize:
|
|
59
|
+
(fontSize) =>
|
|
60
|
+
({ chain }) => {
|
|
61
|
+
return chain().setMark('textStyle', { fontSize }).run();
|
|
62
|
+
},
|
|
63
|
+
unsetFontSize:
|
|
64
|
+
() =>
|
|
65
|
+
({ chain }) => {
|
|
66
|
+
return chain()
|
|
67
|
+
.setMark('textStyle', { fontSize: null })
|
|
68
|
+
.removeEmptyTextStyle()
|
|
69
|
+
.run();
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
|
|
3
|
+
export type LineHeightOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* Node / mark types that should carry the `lineHeight` attribute.
|
|
6
|
+
* Defaults to `['textStyle']` to piggy‑back on TipTap’s built‑in mark.
|
|
7
|
+
*/
|
|
8
|
+
types: string[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
declare module '@tiptap/core' {
|
|
12
|
+
interface Commands<ReturnType> {
|
|
13
|
+
lineHeight: {
|
|
14
|
+
/**
|
|
15
|
+
* Apply a line‑height to the current selection (or stored marks).
|
|
16
|
+
*/
|
|
17
|
+
setLineHeight: (heightValue: string) => ReturnType;
|
|
18
|
+
/**
|
|
19
|
+
* Remove any line‑height attribute.
|
|
20
|
+
*/
|
|
21
|
+
unsetLineHeight: () => ReturnType;
|
|
22
|
+
/**
|
|
23
|
+
* Read the current line‑height from the selection / stored marks.
|
|
24
|
+
*/
|
|
25
|
+
getLineHeight: () => ReturnType;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const LineHeight = Extension.create<LineHeightOptions>({
|
|
31
|
+
name: 'lineHeight',
|
|
32
|
+
|
|
33
|
+
addOptions() {
|
|
34
|
+
return {
|
|
35
|
+
types: ['textStyle'],
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
addGlobalAttributes() {
|
|
40
|
+
return [
|
|
41
|
+
{
|
|
42
|
+
types: this.options.types,
|
|
43
|
+
attributes: {
|
|
44
|
+
lineHeight: {
|
|
45
|
+
default: null,
|
|
46
|
+
parseHTML: (element) =>
|
|
47
|
+
(element.style.lineHeight || '').replace(/['"]+/g, ''),
|
|
48
|
+
renderHTML: (attributes) => {
|
|
49
|
+
if (!attributes.lineHeight) {
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return { style: `line-height: ${attributes.lineHeight}` };
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
addCommands() {
|
|
62
|
+
return {
|
|
63
|
+
setLineHeight:
|
|
64
|
+
(lineHeight) =>
|
|
65
|
+
({ chain }) => {
|
|
66
|
+
return chain().setMark('textStyle', { lineHeight }).run();
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
unsetLineHeight:
|
|
70
|
+
() =>
|
|
71
|
+
({ chain }) => {
|
|
72
|
+
return chain()
|
|
73
|
+
.setMark('textStyle', { lineHeight: null })
|
|
74
|
+
.removeEmptyTextStyle()
|
|
75
|
+
.run();
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
getLineHeight:
|
|
79
|
+
() =>
|
|
80
|
+
({ editor }) => {
|
|
81
|
+
return editor.getAttributes('textStyle').lineHeight;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
});
|
|
@@ -8,7 +8,18 @@ import {
|
|
|
8
8
|
watch,
|
|
9
9
|
} from 'vue';
|
|
10
10
|
import { Editor } from '@tiptap/vue-3';
|
|
11
|
-
import
|
|
11
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
12
|
+
import Underline from '@tiptap/extension-underline';
|
|
13
|
+
import TextStyle from '@tiptap/extension-text-style';
|
|
14
|
+
import TextAlign from '@tiptap/extension-text-align';
|
|
15
|
+
import FontFamily from '@tiptap/extension-font-family';
|
|
16
|
+
import ColorExtension from '@tiptap/extension-color';
|
|
17
|
+
import { FontSize } from './extensions/FontSize';
|
|
18
|
+
import { LetterSpacing } from './extensions/LetterSpacing';
|
|
19
|
+
import { LineHeight } from './extensions/LineHeight';
|
|
20
|
+
import Highlight from '@tiptap/extension-highlight';
|
|
21
|
+
import Placeholder from '@tiptap/extension-placeholder';
|
|
22
|
+
import Link from '@tiptap/extension-link';
|
|
12
23
|
import type { StyleTextFontFamilyOption } from '@shared/style-settings/models';
|
|
13
24
|
import { createFormattingActions } from './formatting';
|
|
14
25
|
import { useTextAlign } from './textAlign';
|
|
@@ -20,7 +31,7 @@ import {
|
|
|
20
31
|
emToPx,
|
|
21
32
|
isStyleChanged,
|
|
22
33
|
pxToEm,
|
|
23
|
-
|
|
34
|
+
sanitiseClientSideRTE,
|
|
24
35
|
skipStyleDetection,
|
|
25
36
|
} from '@brand-page-maker/utils';
|
|
26
37
|
import type { HyperlinkType, TextStyles } from '@brand-page';
|
|
@@ -38,7 +49,9 @@ import {
|
|
|
38
49
|
import { useUiContentSettingsStore } from '@shared/content-settings/store';
|
|
39
50
|
import { useHistoryStore } from '@brand-page-maker/stores/history/history-store';
|
|
40
51
|
import { AllSelection } from 'prosemirror-state';
|
|
41
|
-
import {
|
|
52
|
+
import { MaxLength } from './extensions/MaxLength';
|
|
53
|
+
import { AutoLink } from './extensions/AutoLink';
|
|
54
|
+
import { isHrefPageId, useHyperlink } from './hyperlink';
|
|
42
55
|
import { useBubbleMenu } from './bubbleMenu';
|
|
43
56
|
import {
|
|
44
57
|
hasLogoColorVar,
|
|
@@ -79,7 +92,7 @@ interface UseRichTextEditorReturn {
|
|
|
79
92
|
hyperlinkValue: ComputedRef<{ id: string; name: string; value: string }>;
|
|
80
93
|
setHyperlinkUrlValue: (url: string) => void;
|
|
81
94
|
shouldShow: ({ editor, state }: { editor: any; state: any }) => boolean;
|
|
82
|
-
|
|
95
|
+
tippyOptions: Record<string, any>;
|
|
83
96
|
handleAdminColorChange: (
|
|
84
97
|
color: {
|
|
85
98
|
id: string;
|
|
@@ -116,7 +129,44 @@ export const useExternalRichTextEditor = (): {
|
|
|
116
129
|
} => {
|
|
117
130
|
const externalEditor = new Editor({
|
|
118
131
|
editable: false,
|
|
119
|
-
extensions:
|
|
132
|
+
extensions: [
|
|
133
|
+
StarterKit,
|
|
134
|
+
Underline,
|
|
135
|
+
TextStyle.configure({ mergeNestedSpanStyles: true }),
|
|
136
|
+
TextAlign.configure({
|
|
137
|
+
types: ['heading', 'paragraph'],
|
|
138
|
+
}),
|
|
139
|
+
FontFamily.configure({
|
|
140
|
+
types: ['textStyle'],
|
|
141
|
+
}),
|
|
142
|
+
FontSize,
|
|
143
|
+
LetterSpacing,
|
|
144
|
+
LineHeight,
|
|
145
|
+
ColorExtension.configure({
|
|
146
|
+
types: ['textStyle'],
|
|
147
|
+
}),
|
|
148
|
+
Highlight.configure({
|
|
149
|
+
multicolor: true,
|
|
150
|
+
}),
|
|
151
|
+
Link.configure({
|
|
152
|
+
openOnClick: false,
|
|
153
|
+
defaultProtocol: 'https',
|
|
154
|
+
autolink: true,
|
|
155
|
+
HTMLAttributes: (attrs) => {
|
|
156
|
+
const href = attrs.href;
|
|
157
|
+
const isExternal =
|
|
158
|
+
href && (href.startsWith('http://') || href.startsWith('https://'));
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
rel: 'noopener noreferrer',
|
|
162
|
+
target: isExternal ? '_blank' : null,
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
isAllowedUri: (url, ctx) =>
|
|
166
|
+
ctx.defaultValidate(url) || isHrefPageId(url),
|
|
167
|
+
}),
|
|
168
|
+
AutoLink,
|
|
169
|
+
],
|
|
120
170
|
});
|
|
121
171
|
|
|
122
172
|
return {
|
|
@@ -164,13 +214,54 @@ export const useRichTextEditor = (
|
|
|
164
214
|
const editor = new Editor({
|
|
165
215
|
content: model.value ?? '',
|
|
166
216
|
editable: !props.readOnly,
|
|
167
|
-
extensions:
|
|
168
|
-
|
|
169
|
-
|
|
217
|
+
extensions: [
|
|
218
|
+
StarterKit.configure({
|
|
219
|
+
bulletList: false,
|
|
220
|
+
orderedList: false,
|
|
221
|
+
listItem: false,
|
|
222
|
+
horizontalRule: false,
|
|
223
|
+
codeBlock: false,
|
|
224
|
+
code: false,
|
|
225
|
+
}),
|
|
226
|
+
Underline,
|
|
227
|
+
TextStyle.configure({ mergeNestedSpanStyles: true }),
|
|
228
|
+
TextAlign.configure({
|
|
229
|
+
types: ['heading', 'paragraph'],
|
|
230
|
+
}),
|
|
231
|
+
FontFamily.configure({
|
|
232
|
+
types: ['textStyle'],
|
|
233
|
+
}),
|
|
234
|
+
FontSize,
|
|
235
|
+
LetterSpacing,
|
|
236
|
+
LineHeight,
|
|
237
|
+
ColorExtension.configure({
|
|
238
|
+
types: ['textStyle'],
|
|
239
|
+
}),
|
|
240
|
+
Highlight.configure({
|
|
241
|
+
multicolor: true,
|
|
242
|
+
}),
|
|
243
|
+
Placeholder.configure({
|
|
170
244
|
placeholder: props.placeholder,
|
|
171
|
-
|
|
172
|
-
},
|
|
173
|
-
|
|
245
|
+
}),
|
|
246
|
+
MaxLength.configure({ maxLength: props.maxLength }),
|
|
247
|
+
Link.configure({
|
|
248
|
+
openOnClick: false,
|
|
249
|
+
defaultProtocol: 'https',
|
|
250
|
+
autolink: true,
|
|
251
|
+
HTMLAttributes: (attrs) => {
|
|
252
|
+
const href = attrs.href;
|
|
253
|
+
const isExternal =
|
|
254
|
+
href && (href.startsWith('http://') || href.startsWith('https://'));
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
target: isExternal ? '_blank' : null,
|
|
258
|
+
};
|
|
259
|
+
},
|
|
260
|
+
isAllowedUri: (url, ctx) =>
|
|
261
|
+
ctx.defaultValidate(url) || isHrefPageId(url),
|
|
262
|
+
}),
|
|
263
|
+
AutoLink,
|
|
264
|
+
],
|
|
174
265
|
editorProps: {
|
|
175
266
|
handleDOMEvents: {
|
|
176
267
|
drop(view, event: DragEvent) {
|
|
@@ -349,7 +440,7 @@ export const useRichTextEditor = (
|
|
|
349
440
|
applyHyperlinkToEditor,
|
|
350
441
|
} = useHyperlink(editor);
|
|
351
442
|
|
|
352
|
-
const { shouldShow,
|
|
443
|
+
const { shouldShow, tippyOptions } = useBubbleMenu(
|
|
353
444
|
editor,
|
|
354
445
|
isHyperlinkPopupOpen,
|
|
355
446
|
);
|
|
@@ -381,14 +472,8 @@ export const useRichTextEditor = (
|
|
|
381
472
|
|
|
382
473
|
const isExternalMutation = updateRichTextEditor.value || appliedSinceLast;
|
|
383
474
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
// setContent and reset the user's just-applied styles).
|
|
387
|
-
const hasChanged =
|
|
388
|
-
JSON.stringify(editor.getJSON()) !== JSON.stringify(newValue);
|
|
389
|
-
|
|
390
|
-
if (isExternalMutation && hasChanged) {
|
|
391
|
-
editor.commands.setContent(newValue, { emitUpdate: false });
|
|
475
|
+
if (isExternalMutation && editor.getHTML() !== newValue) {
|
|
476
|
+
editor.commands.setContent(newValue, false);
|
|
392
477
|
updateRichTextEditor.value = false;
|
|
393
478
|
//text style type is not switching when reordering
|
|
394
479
|
textStyleTypeOptions.forEach((item) => {
|
|
@@ -418,13 +503,12 @@ export const useRichTextEditor = (
|
|
|
418
503
|
}
|
|
419
504
|
});
|
|
420
505
|
|
|
421
|
-
// Update model when editor content changes
|
|
422
|
-
// JSON (BP-5787). getJSON() is already in hand (the editor holds the doc) and
|
|
423
|
-
// is sanitised natively — no getHTML(), no DOMPurify, no extra editor — so
|
|
424
|
-
// the per-keystroke path allocates nothing heavy.
|
|
506
|
+
// Update model when editor content changes
|
|
425
507
|
editor.on('update', () => {
|
|
508
|
+
const sanitizedData = sanitiseClientSideRTE(editor.getHTML());
|
|
509
|
+
|
|
426
510
|
// An update fired while the editor is unfocused is TipTap rewriting the
|
|
427
|
-
// model back into its canonical
|
|
511
|
+
// model back into its canonical HTML during mount rehydration or a
|
|
428
512
|
// programmatic setContent — not a user edit. Tag the emit so the write
|
|
429
513
|
// folds into the current undo head instead of pushing a phantom entry
|
|
430
514
|
// (BP-5810). The flag travels WITH the value through the debounced
|
|
@@ -438,7 +522,7 @@ export const useRichTextEditor = (
|
|
|
438
522
|
// the RTE only mounts inside an already-open settings drawer and the user
|
|
439
523
|
// focuses it before formatting, so this doesn't occur — revisit if a
|
|
440
524
|
// consumer ever drives toolbar actions on an unfocused editor.
|
|
441
|
-
emit('update:modelValue',
|
|
525
|
+
emit('update:modelValue', sanitizedData.sanitizedHtml, {
|
|
442
526
|
isHydrationWrite: !editor.isFocused,
|
|
443
527
|
});
|
|
444
528
|
});
|
|
@@ -965,7 +1049,7 @@ export const useRichTextEditor = (
|
|
|
965
1049
|
hyperlinkValue,
|
|
966
1050
|
setHyperlinkUrlValue,
|
|
967
1051
|
shouldShow,
|
|
968
|
-
|
|
1052
|
+
tippyOptions,
|
|
969
1053
|
handleAdminColorChange,
|
|
970
1054
|
};
|
|
971
1055
|
};
|
|
@@ -7,8 +7,6 @@ export * from './url.util';
|
|
|
7
7
|
export * from './slug.util';
|
|
8
8
|
export * from './text.util';
|
|
9
9
|
export * from './rich-text-editor.util';
|
|
10
|
-
export * from './rte-render.util';
|
|
11
|
-
export * from './rte-sanitize.util';
|
|
12
10
|
|
|
13
11
|
export const isColorMatched = (color: string | null | undefined): boolean => {
|
|
14
12
|
if (!color) return false;
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
getUpdatedHTMLFromEditor,
|
|
9
9
|
sanitiseClientSideRTE,
|
|
10
10
|
getRTEColor,
|
|
11
|
-
getRteTextLength,
|
|
12
11
|
} from './rich-text-editor.util';
|
|
13
12
|
import type { TextStyleDeclaration } from '@brand-page';
|
|
14
13
|
|
|
@@ -76,40 +75,8 @@ describe('hasHTML', () => {
|
|
|
76
75
|
});
|
|
77
76
|
});
|
|
78
77
|
|
|
79
|
-
describe('getRteTextLength', () => {
|
|
80
|
-
it('returns the raw length for a plain string (unchanged legacy behaviour)', () => {
|
|
81
|
-
expect(getRteTextLength('hello')).toBe(5);
|
|
82
|
-
expect(getRteTextLength('<p>hello</p>')).toBe('<p>hello</p>'.length);
|
|
83
|
-
expect(getRteTextLength('')).toBe(0);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('returns visible-text length for a Tiptap JSON doc (not undefined/throw)', () => {
|
|
87
|
-
const doc = {
|
|
88
|
-
type: 'doc',
|
|
89
|
-
content: [
|
|
90
|
-
{
|
|
91
|
-
type: 'paragraph',
|
|
92
|
-
content: [
|
|
93
|
-
{ type: 'text', text: 'hello ' },
|
|
94
|
-
{ type: 'text', marks: [{ type: 'bold' }], text: 'world' },
|
|
95
|
-
],
|
|
96
|
-
},
|
|
97
|
-
],
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// "hello world" — measured from the text nodes, not the JSON wrapper.
|
|
101
|
-
expect(getRteTextLength(doc)).toBe(11);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('returns 0 for null/undefined and an empty doc', () => {
|
|
105
|
-
expect(getRteTextLength(null)).toBe(0);
|
|
106
|
-
expect(getRteTextLength(undefined)).toBe(0);
|
|
107
|
-
expect(getRteTextLength({ type: 'doc', content: [] })).toBe(0);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
78
|
describe('getUpdatedHTMLFromEditor', () => {
|
|
112
|
-
it('applies style commands and returns updated
|
|
79
|
+
it('applies style commands and returns updated HTML', () => {
|
|
113
80
|
// Mock editor
|
|
114
81
|
const runMock = vi.fn();
|
|
115
82
|
const chain = {
|
|
@@ -152,7 +119,7 @@ describe('getUpdatedHTMLFromEditor', () => {
|
|
|
152
119
|
},
|
|
153
120
|
},
|
|
154
121
|
chain: () => chain as any,
|
|
155
|
-
|
|
122
|
+
getHTML: () => '<div>styled</div>',
|
|
156
123
|
} as unknown as Editor;
|
|
157
124
|
|
|
158
125
|
const newStyle = {
|
|
@@ -170,8 +137,7 @@ describe('getUpdatedHTMLFromEditor', () => {
|
|
|
170
137
|
|
|
171
138
|
expect(externalEditor.commands.setContent).toHaveBeenCalledWith('foo');
|
|
172
139
|
expect(runMock).toHaveBeenCalled();
|
|
173
|
-
|
|
174
|
-
expect(result).toEqual({ type: 'doc', content: [{ type: 'paragraph' }] });
|
|
140
|
+
expect(result).toBe('<div>styled</div>');
|
|
175
141
|
});
|
|
176
142
|
});
|
|
177
143
|
|