@designcrowd/library.brand-page 5.10.20 → 5.10.31
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/brand-page/constants/font.constants.d.ts +4 -4
- package/lib/src/brand-page/models/index.d.ts +5 -0
- package/lib/src/brand-page/models/index.js +4 -0
- package/lib/src/brand-page/models/styles.model.d.ts +5 -5
- package/lib/src/brand-page/utils/style.util.d.ts +8 -1
- package/lib/src/brand-page/utils/style.util.js +58 -5
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.js +2 -2
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +1 -1
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.js +1 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/page-content-items.d.ts +1 -1
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/page-content-items.js +2 -1
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +33 -0
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.js +35 -1
- package/lib/src/brand-page-maker/components/navigation/Navigation.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +3 -3
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +1 -0
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.js +17 -0
- package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.d.ts +19 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.js +31 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.d.ts +2 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.js +161 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.js +3 -3
- package/lib/src/brand-page-maker/composables/rich-text-editor/font.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/font.js +0 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/formatting.js +0 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.d.ts +19 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/hyperlink.js +87 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/spacing.js +0 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/textAlign.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/textAlign.js +0 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +24 -3
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +214 -33
- package/lib/src/brand-page-maker/constants/brandpage-meta-constant.d.ts +5 -5
- package/lib/src/brand-page-maker/constants/index.d.ts +2 -2
- package/lib/src/brand-page-maker/models/button-group.model.d.ts +2 -0
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +19 -2
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +340 -8
- package/lib/src/bundled-translations-BXxQYq2i.js +119 -0
- package/lib/src/bundled-translations.de-DE-BXcluMZ2.js +119 -0
- package/lib/src/{bundled-translations.de-DE-O4sKkzBX.js → bundled-translations.de-DE-DjQFwukR.js} +1 -1
- package/lib/src/{bundled-translations.es-ES-C4lGaf08.js → bundled-translations.es-ES--EbGRI7e.js} +1 -1
- package/lib/src/bundled-translations.es-ES-DSd-wV16.js +119 -0
- package/lib/src/{bundled-translations.fr-FR-CIy8KjAV.js → bundled-translations.fr-FR-VtC2JYUC.js} +1 -1
- package/lib/src/bundled-translations.fr-FR-jKR_dxWR.js +119 -0
- package/lib/src/bundled-translations.pt-PT-CwvYqXXo.js +119 -0
- package/lib/src/{bundled-translations.pt-PT-C8EcSdyX.js → bundled-translations.pt-PT-l9cEldEo.js} +1 -1
- package/lib/src/bundles/bundled-translations.de-DE.json +11 -0
- package/lib/src/bundles/bundled-translations.es-ES.json +11 -0
- package/lib/src/bundles/bundled-translations.fr-FR.json +13 -2
- package/lib/src/bundles/bundled-translations.json +11 -0
- package/lib/src/bundles/bundled-translations.pt-PT.json +11 -0
- package/lib/src/composables/useTranslate.d.ts +64 -62
- package/lib/src/composables/useTranslate.js +18 -7
- package/lib/src/css/library.brand-page-brandCrowd.min.css +101 -75
- package/lib/src/css/library.brand-page-brandPage.min.css +101 -75
- package/lib/src/css/library.brand-page-designCom.min.css +101 -75
- package/lib/src/css/library.brand-page-preview.min.css +101 -75
- package/lib/src/index.d.ts +3 -1
- package/lib/src/index.mjs +30209 -27738
- package/lib/src/lib.js +2 -1
- package/lib/src/mockServiceWorker.js +91 -54
- package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/color-field/ColorField.mixin.d.ts +11 -0
- package/lib/src/shared/content-settings/components/color-field/ColorField.mixin.js +5 -0
- package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.mixin.d.ts +11 -1
- package/lib/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.mixin.js +4 -0
- package/lib/src/shared/content-settings/components/shape-field/ShapeField.mixin.d.ts +1 -1
- package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/text-image-field/TextImageField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +4 -2
- package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.js +12 -7
- package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +2 -2
- package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +3 -3
- package/lib/src/shared/my-uploads/MyUploads.mixin.d.ts +1 -1
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +1 -1
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +4 -2
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +4 -4
- package/lib/src/shared/shape-library/ShapeLibrary.mixin.d.ts +1 -1
- package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +2 -2
- package/lib/src/shared/template-settings/models.d.ts +3 -3
- package/package.json +6 -3
- package/src/brand-page/components/banner-section/BannerSection.vue +6 -0
- package/src/brand-page/components/sensitive-content/SensitiveContentModal.vue +28 -11
- package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.de-DE.json +13 -0
- package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.es-ES.json +13 -0
- package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.fr-FR.json +13 -0
- package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.json +13 -0
- package/src/brand-page/components/sensitive-content/i18n/sensitive-content-modal.pt-PT.json +13 -0
- package/src/brand-page/components/text/Text.vue +2 -0
- package/src/brand-page/components/text-wrapper/TextWrapper.vue +31 -11
- package/src/brand-page/models/index.ts +6 -0
- package/src/brand-page/utils/style.util.ts +105 -5
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.ts +2 -2
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +1 -1
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/content-settings-items.fixture.ts +1 -0
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/page-content-items.ts +2 -0
- package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.ts +44 -1
- package/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.vue +1 -0
- package/src/brand-page-maker/components/brandpage-settings/i18n/brand-page-settings.fr-FR.json +1 -1
- package/src/brand-page-maker/components/google-analytics/i18n/google-analytics.fr-FR.json +1 -1
- package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +539 -50
- package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.ts +22 -0
- package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +1 -1
- package/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.ts +42 -0
- package/src/brand-page-maker/composables/rich-text-editor/extensions/AutoLink.ts +227 -0
- package/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.test.ts +1 -1
- package/src/brand-page-maker/composables/rich-text-editor/extensions/MaxLength.ts +4 -15
- package/src/brand-page-maker/composables/rich-text-editor/font.ts +1 -1
- package/src/brand-page-maker/composables/rich-text-editor/formatting.ts +1 -1
- package/src/brand-page-maker/composables/rich-text-editor/hyperlink.ts +114 -0
- package/src/brand-page-maker/composables/rich-text-editor/spacing.ts +1 -1
- package/src/brand-page-maker/composables/rich-text-editor/textAlign.ts +1 -1
- package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +299 -41
- package/src/brand-page-maker/models/button-group.model.ts +2 -0
- package/src/brand-page-maker/stores/brandpage-maker/__snapshots__/brandpage-maker-store.test.ts.snap +1 -0
- package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +418 -0
- package/src/brand-page-maker/utils/rich-text-editor.util.ts +470 -25
- package/src/bundles/bundled-translations.de-DE.json +11 -0
- package/src/bundles/bundled-translations.es-ES.json +11 -0
- package/src/bundles/bundled-translations.fr-FR.json +13 -2
- package/src/bundles/bundled-translations.json +11 -0
- package/src/bundles/bundled-translations.pt-PT.json +11 -0
- package/src/composables/useTranslate.ts +25 -8
- package/src/lib.ts +7 -1
- package/src/shared/content-settings/components/color-field/ColorField.mixin.ts +5 -0
- package/src/shared/content-settings/components/color-field/ColorField.vue +1 -1
- package/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.mixin.ts +4 -0
- package/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.vue +2 -2
- package/src/shared/content-settings/components/text-field/TextField.vue +1 -1
- package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +2 -2
- package/src/shared/content-settings/components/textarea-field/TextareaField.vue +3 -3
- package/src/shared/content-settings/components/url-field/UrlField.mixin.ts +15 -10
- package/src/shared/content-settings/components/url-field/UrlField.vue +1 -0
- package/lib/src/bundled-translations-DaK60m67.js +0 -117
- package/lib/src/bundled-translations.de-DE-848cpWPB.js +0 -117
- package/lib/src/bundled-translations.es-ES-CtPI5G7I.js +0 -117
- package/lib/src/bundled-translations.fr-FR-CTnDppmf.js +0 -117
- package/lib/src/bundled-translations.pt-PT-Balnne-7.js +0 -117
|
@@ -19,6 +19,7 @@ import { LetterSpacing } from './extensions/LetterSpacing';
|
|
|
19
19
|
import { LineHeight } from './extensions/LineHeight';
|
|
20
20
|
import Highlight from '@tiptap/extension-highlight';
|
|
21
21
|
import Placeholder from '@tiptap/extension-placeholder';
|
|
22
|
+
import Link from '@tiptap/extension-link';
|
|
22
23
|
import type { StyleTextFontFamilyOption } from '../../../shared/style-settings/models';
|
|
23
24
|
import { createFormattingActions } from './formatting';
|
|
24
25
|
import { useTextAlign } from './textAlign';
|
|
@@ -30,19 +31,28 @@ import {
|
|
|
30
31
|
emToPx,
|
|
31
32
|
isStyleChanged,
|
|
32
33
|
pxToEm,
|
|
34
|
+
sanitiseClientSideRTE,
|
|
33
35
|
skipStyleDetection,
|
|
34
36
|
} from '../../../brand-page-maker/utils';
|
|
35
|
-
import {
|
|
36
|
-
|
|
37
|
-
type TextItem,
|
|
38
|
-
type TextStyleDeclaration,
|
|
39
|
-
} from '../../../brand-page';
|
|
37
|
+
import type { TextStyles } from '../../../brand-page';
|
|
38
|
+
import { type TextItem, type TextStyleDeclaration } from '../../../brand-page';
|
|
40
39
|
import type { ButtonGroupOption } from '../../../brand-page-maker/models/button-group.model';
|
|
41
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
letterSpacingValueConvertor,
|
|
42
|
+
colorConvertor,
|
|
43
|
+
backgroundColorConvertor,
|
|
44
|
+
} from '../../../brand-page-maker/convertors';
|
|
42
45
|
import { useUiContentSettingsStore } from '../../../shared/content-settings/store';
|
|
43
|
-
import { DOMSerializer } from 'prosemirror-model';
|
|
44
46
|
import { AllSelection } from 'prosemirror-state';
|
|
45
47
|
import { MaxLength } from './extensions/MaxLength';
|
|
48
|
+
import { AutoLink } from './extensions/AutoLink';
|
|
49
|
+
import { useHyperlink } from './hyperlink';
|
|
50
|
+
import { useBubbleMenu } from './bubbleMenu';
|
|
51
|
+
import {
|
|
52
|
+
hasLogoColorVar,
|
|
53
|
+
isLogoColor,
|
|
54
|
+
getRTEColor,
|
|
55
|
+
} from '../../utils/rich-text-editor.util';
|
|
46
56
|
|
|
47
57
|
interface UseRichTextEditorReturn {
|
|
48
58
|
editor: Editor;
|
|
@@ -69,6 +79,22 @@ interface UseRichTextEditorReturn {
|
|
|
69
79
|
setInitialStyleSettings: (selectedTextStyle?: BrandPageCssStyle) => void;
|
|
70
80
|
copyGlobalStyleSettings: (selectedTextStyle?: BrandPageCssStyle) => void;
|
|
71
81
|
unsetAllMarks: () => void;
|
|
82
|
+
handleHyperlink: (
|
|
83
|
+
action: 'toggle' | 'apply' | 'remove',
|
|
84
|
+
data?: { href?: string; text?: string },
|
|
85
|
+
) => void;
|
|
86
|
+
hyperlinkValue: ComputedRef<{ id: string; name: string; value: string }>;
|
|
87
|
+
setHyperlinkUrlValue: (url: string) => void;
|
|
88
|
+
shouldShow: ({ editor, state }: { editor: any; state: any }) => boolean;
|
|
89
|
+
tippyOptions: Record<string, any>;
|
|
90
|
+
handleAdminColorChange: (
|
|
91
|
+
color: {
|
|
92
|
+
id: string;
|
|
93
|
+
name: string;
|
|
94
|
+
value: string;
|
|
95
|
+
},
|
|
96
|
+
type: 'textColor' | 'backgroundColor',
|
|
97
|
+
) => void;
|
|
72
98
|
}
|
|
73
99
|
|
|
74
100
|
interface DropdownInstance {
|
|
@@ -77,6 +103,7 @@ interface DropdownInstance {
|
|
|
77
103
|
|
|
78
104
|
interface EditorOptionType {
|
|
79
105
|
type:
|
|
106
|
+
| 'hyperlink'
|
|
80
107
|
| 'fontFamily'
|
|
81
108
|
| 'fontSize'
|
|
82
109
|
| 'fontWeight'
|
|
@@ -115,6 +142,22 @@ export const useExternalRichTextEditor = (): {
|
|
|
115
142
|
Highlight.configure({
|
|
116
143
|
multicolor: true,
|
|
117
144
|
}),
|
|
145
|
+
Link.configure({
|
|
146
|
+
openOnClick: false,
|
|
147
|
+
defaultProtocol: 'https',
|
|
148
|
+
autolink: true,
|
|
149
|
+
HTMLAttributes: (attrs) => {
|
|
150
|
+
const href = attrs.href;
|
|
151
|
+
const isExternal =
|
|
152
|
+
href && (href.startsWith('http://') || href.startsWith('https://'));
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
rel: 'noopener noreferrer',
|
|
156
|
+
target: isExternal ? '_blank' : null,
|
|
157
|
+
};
|
|
158
|
+
},
|
|
159
|
+
}),
|
|
160
|
+
AutoLink,
|
|
118
161
|
],
|
|
119
162
|
});
|
|
120
163
|
|
|
@@ -153,6 +196,8 @@ export const useRichTextEditor = (
|
|
|
153
196
|
onSelectTextStyleType: (option: ButtonGroupOption) => void,
|
|
154
197
|
updateRichTextEditor: Ref<boolean>,
|
|
155
198
|
textStyleTypeOptions: ButtonGroupOption[],
|
|
199
|
+
markedText: Ref<string>,
|
|
200
|
+
isHyperlinkPopupOpen: Ref<boolean>,
|
|
156
201
|
): UseRichTextEditorReturn => {
|
|
157
202
|
const editor = new Editor({
|
|
158
203
|
content: model.value ?? '',
|
|
@@ -180,6 +225,21 @@ export const useRichTextEditor = (
|
|
|
180
225
|
placeholder: props.placeholder,
|
|
181
226
|
}),
|
|
182
227
|
MaxLength.configure({ maxLength: props.maxLength }),
|
|
228
|
+
Link.configure({
|
|
229
|
+
openOnClick: false,
|
|
230
|
+
defaultProtocol: 'https',
|
|
231
|
+
autolink: true,
|
|
232
|
+
HTMLAttributes: (attrs) => {
|
|
233
|
+
const href = attrs.href;
|
|
234
|
+
const isExternal =
|
|
235
|
+
href && (href.startsWith('http://') || href.startsWith('https://'));
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
target: isExternal ? '_blank' : null,
|
|
239
|
+
};
|
|
240
|
+
},
|
|
241
|
+
}),
|
|
242
|
+
AutoLink,
|
|
183
243
|
],
|
|
184
244
|
editorProps: {
|
|
185
245
|
handleDOMEvents: {
|
|
@@ -212,33 +272,25 @@ export const useRichTextEditor = (
|
|
|
212
272
|
return false;
|
|
213
273
|
},
|
|
214
274
|
copy(view, event: ClipboardEvent) {
|
|
215
|
-
|
|
216
|
-
event.preventDefault();
|
|
275
|
+
const selection = view.state.selection;
|
|
217
276
|
|
|
218
|
-
|
|
219
|
-
const selectedText = view.state.doc.textBetween(
|
|
220
|
-
view.state.selection.from,
|
|
221
|
-
view.state.selection.to,
|
|
222
|
-
'\n',
|
|
223
|
-
);
|
|
277
|
+
if (selection.empty) return;
|
|
224
278
|
|
|
225
|
-
event.clipboardData
|
|
279
|
+
const data = event.clipboardData;
|
|
226
280
|
|
|
227
|
-
// 2) custom style blob to add
|
|
228
281
|
const styleData = JSON.stringify(props.styles);
|
|
229
282
|
|
|
230
|
-
|
|
283
|
+
const slice = selection.content(),
|
|
284
|
+
{ dom, text } = view.serializeForClipboard(slice);
|
|
231
285
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
// Wrap in a container DIV so we can grab `innerHTML`
|
|
238
|
-
const wrapper = document.createElement('div');
|
|
286
|
+
if (data) {
|
|
287
|
+
event.preventDefault();
|
|
288
|
+
data.clearData();
|
|
289
|
+
data.setData('text/html', dom.innerHTML);
|
|
290
|
+
data.setData('text/plain', text);
|
|
239
291
|
|
|
240
|
-
|
|
241
|
-
|
|
292
|
+
if (styleData) data.setData('application/x-rte-styles', styleData);
|
|
293
|
+
}
|
|
242
294
|
|
|
243
295
|
return true;
|
|
244
296
|
},
|
|
@@ -292,6 +344,27 @@ export const useRichTextEditor = (
|
|
|
292
344
|
|
|
293
345
|
return true;
|
|
294
346
|
},
|
|
347
|
+
click(view, event) {
|
|
348
|
+
if (isHyperlinkPopupOpen?.value) return false;
|
|
349
|
+
|
|
350
|
+
const target = event.target as HTMLElement;
|
|
351
|
+
|
|
352
|
+
const linkElement = target.closest('a');
|
|
353
|
+
|
|
354
|
+
if (linkElement) {
|
|
355
|
+
const pos = view.posAtDOM(linkElement, 0);
|
|
356
|
+
|
|
357
|
+
if (pos !== null) {
|
|
358
|
+
editor.commands.setTextSelection(pos);
|
|
359
|
+
|
|
360
|
+
editor.commands.extendMarkRange('link');
|
|
361
|
+
|
|
362
|
+
return true; // Prevent default
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return false;
|
|
367
|
+
},
|
|
295
368
|
},
|
|
296
369
|
},
|
|
297
370
|
});
|
|
@@ -337,6 +410,19 @@ export const useRichTextEditor = (
|
|
|
337
410
|
setLineHeightAll,
|
|
338
411
|
} = useSpacing(editor);
|
|
339
412
|
|
|
413
|
+
const {
|
|
414
|
+
hyperlinkValue,
|
|
415
|
+
setHyperlinkUrl,
|
|
416
|
+
setHyperlinkUrlValue,
|
|
417
|
+
removeHyperlink: removeHyperlinkFromComposable,
|
|
418
|
+
applyHyperlinkToEditor,
|
|
419
|
+
} = useHyperlink(editor);
|
|
420
|
+
|
|
421
|
+
const { shouldShow, tippyOptions } = useBubbleMenu(
|
|
422
|
+
editor,
|
|
423
|
+
isHyperlinkPopupOpen,
|
|
424
|
+
);
|
|
425
|
+
|
|
340
426
|
watch(
|
|
341
427
|
() => props.styles.textAlign,
|
|
342
428
|
(newAlignment) => {
|
|
@@ -376,9 +462,9 @@ export const useRichTextEditor = (
|
|
|
376
462
|
|
|
377
463
|
// Update model when editor content changes
|
|
378
464
|
editor.on('update', () => {
|
|
379
|
-
const
|
|
465
|
+
const sanitizedData = sanitiseClientSideRTE(editor.getHTML());
|
|
380
466
|
|
|
381
|
-
emit('update:modelValue',
|
|
467
|
+
emit('update:modelValue', sanitizedData.sanitizedHtml);
|
|
382
468
|
});
|
|
383
469
|
|
|
384
470
|
editor.on('selectionUpdate', () => {
|
|
@@ -421,15 +507,17 @@ export const useRichTextEditor = (
|
|
|
421
507
|
}
|
|
422
508
|
|
|
423
509
|
if (textStyleAttributes && textStyleAttributes.color) {
|
|
424
|
-
|
|
510
|
+
if (!hasLogoColorVar(textStyleAttributes.color))
|
|
511
|
+
fontSettings.selectedTextColor = Color(textStyleAttributes.color).hex();
|
|
425
512
|
} else {
|
|
426
513
|
fontSettings.selectedTextColor = '#000000';
|
|
427
514
|
}
|
|
428
515
|
|
|
429
516
|
if (highlightAttributes && highlightAttributes.color) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
517
|
+
if (!hasLogoColorVar(highlightAttributes.color))
|
|
518
|
+
fontSettings.selectedBackgroundColor = Color(
|
|
519
|
+
highlightAttributes.color,
|
|
520
|
+
).hex();
|
|
433
521
|
} else {
|
|
434
522
|
fontSettings.selectedBackgroundColor = 'transparent';
|
|
435
523
|
}
|
|
@@ -490,9 +578,14 @@ export const useRichTextEditor = (
|
|
|
490
578
|
fontSettings.selectedFontSizePx = parseInt(
|
|
491
579
|
emToPx(globalStyles?.fontSize ?? '2.25em'),
|
|
492
580
|
);
|
|
493
|
-
fontSettings.selectedTextColor = globalStyles
|
|
494
|
-
|
|
495
|
-
globalStyles?.
|
|
581
|
+
fontSettings.selectedTextColor = hasLogoColorVar(globalStyles.color ?? '')
|
|
582
|
+
? '#000000'
|
|
583
|
+
: globalStyles?.color ?? '#000000';
|
|
584
|
+
fontSettings.selectedBackgroundColor = hasLogoColorVar(
|
|
585
|
+
globalStyles?.backgroundColor ?? '',
|
|
586
|
+
)
|
|
587
|
+
? 'transparent'
|
|
588
|
+
: globalStyles?.backgroundColor ?? 'transparent';
|
|
496
589
|
lineHeight.value = globalStyles?.lineHeight?.includes('em')
|
|
497
590
|
? emToPx(globalStyles?.lineHeight ?? '1em')
|
|
498
591
|
: globalStyles?.lineHeight ?? '1';
|
|
@@ -512,9 +605,16 @@ export const useRichTextEditor = (
|
|
|
512
605
|
fontSettings.selectedFontSizePx = parseInt(
|
|
513
606
|
emToPx(props.styles?.fontSize ?? '2.25em'),
|
|
514
607
|
);
|
|
515
|
-
fontSettings.selectedTextColor =
|
|
516
|
-
|
|
517
|
-
|
|
608
|
+
fontSettings.selectedTextColor = hasLogoColorVar(
|
|
609
|
+
props.styles?.color ?? '#000000',
|
|
610
|
+
)
|
|
611
|
+
? '#000000'
|
|
612
|
+
: props.styles?.color ?? '#000000';
|
|
613
|
+
fontSettings.selectedBackgroundColor = hasLogoColorVar(
|
|
614
|
+
props.styles?.backgroundColor ?? '',
|
|
615
|
+
)
|
|
616
|
+
? 'transparent'
|
|
617
|
+
: props.styles?.backgroundColor ?? 'transparent';
|
|
518
618
|
lineHeight.value = props.styles?.lineHeight?.includes('em')
|
|
519
619
|
? emToPx(props.styles?.lineHeight ?? '1em')
|
|
520
620
|
: props.styles?.lineHeight ?? '1';
|
|
@@ -543,8 +643,14 @@ export const useRichTextEditor = (
|
|
|
543
643
|
toggleStrikeAll();
|
|
544
644
|
|
|
545
645
|
if (globalStyles.color) {
|
|
546
|
-
|
|
547
|
-
|
|
646
|
+
if (!hasLogoColorVar(globalStyles.color)) {
|
|
647
|
+
toggleTextColorAll(globalStyles.color);
|
|
648
|
+
fontSettings.selectedTextColor = globalStyles.color;
|
|
649
|
+
} else {
|
|
650
|
+
// Apply logo color using CSS variable
|
|
651
|
+
toggleTextColorAll(getRTEColor(globalStyles.color, 'text'));
|
|
652
|
+
fontSettings.selectedTextColor = '#000000';
|
|
653
|
+
}
|
|
548
654
|
}
|
|
549
655
|
|
|
550
656
|
globalStyles.fontFamily && toggleFontAll(globalStyles.fontFamily);
|
|
@@ -630,6 +736,9 @@ export const useRichTextEditor = (
|
|
|
630
736
|
toggleTextAlign();
|
|
631
737
|
fontStyleChanges.textAlign = currentAlignment.value.alignment;
|
|
632
738
|
break;
|
|
739
|
+
case 'hyperlink':
|
|
740
|
+
setHyperlinkUrl(editorOption.value as string);
|
|
741
|
+
break;
|
|
633
742
|
}
|
|
634
743
|
|
|
635
744
|
syncContentSettings(fontStyleChanges);
|
|
@@ -665,6 +774,149 @@ export const useRichTextEditor = (
|
|
|
665
774
|
emit('blur');
|
|
666
775
|
};
|
|
667
776
|
|
|
777
|
+
const handleHyperlink = (
|
|
778
|
+
action: 'toggle' | 'apply' | 'remove',
|
|
779
|
+
data?: { href?: string; text?: string },
|
|
780
|
+
) => {
|
|
781
|
+
switch (action) {
|
|
782
|
+
case 'toggle':
|
|
783
|
+
isHyperlinkPopupOpen.value = !isHyperlinkPopupOpen.value;
|
|
784
|
+
|
|
785
|
+
if (isHyperlinkPopupOpen.value) {
|
|
786
|
+
if (data?.href && data?.text) {
|
|
787
|
+
setHyperlinkUrlValue(data.href);
|
|
788
|
+
markedText.value = data.text;
|
|
789
|
+
} else {
|
|
790
|
+
const linkAttrs = editor.getAttributes('link');
|
|
791
|
+
|
|
792
|
+
const selection = editor.state.selection;
|
|
793
|
+
|
|
794
|
+
if (linkAttrs.href) {
|
|
795
|
+
editor.commands.extendMarkRange('link');
|
|
796
|
+
|
|
797
|
+
const linkText = editor.state.doc.textBetween(
|
|
798
|
+
selection.from,
|
|
799
|
+
selection.to,
|
|
800
|
+
);
|
|
801
|
+
|
|
802
|
+
setHyperlinkUrlValue(linkAttrs.href);
|
|
803
|
+
|
|
804
|
+
markedText.value = linkText;
|
|
805
|
+
} else {
|
|
806
|
+
const selectedText = selection.empty
|
|
807
|
+
? ''
|
|
808
|
+
: editor.state.doc.textBetween(selection.from, selection.to);
|
|
809
|
+
|
|
810
|
+
setHyperlinkUrlValue('');
|
|
811
|
+
|
|
812
|
+
markedText.value = selectedText;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
editor.commands.focus(); // Hide bubble menu
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
break;
|
|
820
|
+
|
|
821
|
+
case 'apply':
|
|
822
|
+
const url = hyperlinkValue.value.value;
|
|
823
|
+
|
|
824
|
+
const text = markedText.value;
|
|
825
|
+
|
|
826
|
+
if (!url.trim()) {
|
|
827
|
+
isHyperlinkPopupOpen.value = false;
|
|
828
|
+
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
const selection = editor.state?.selection;
|
|
833
|
+
const selectionRange = selection
|
|
834
|
+
? { from: selection.from, to: selection.to }
|
|
835
|
+
: undefined;
|
|
836
|
+
|
|
837
|
+
applyHyperlinkToEditor(url, text, selectionRange);
|
|
838
|
+
isHyperlinkPopupOpen.value = false;
|
|
839
|
+
break;
|
|
840
|
+
|
|
841
|
+
case 'remove':
|
|
842
|
+
removeHyperlinkFromComposable();
|
|
843
|
+
isHyperlinkPopupOpen.value = false;
|
|
844
|
+
break;
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
const handleAdminColorChange = (
|
|
849
|
+
color: any,
|
|
850
|
+
colorType: 'textColor' | 'backgroundColor',
|
|
851
|
+
) => {
|
|
852
|
+
const convertor =
|
|
853
|
+
colorType === 'textColor' ? colorConvertor : backgroundColorConvertor;
|
|
854
|
+
const convertedColor = convertor.convertBack(color.value);
|
|
855
|
+
const colorValue =
|
|
856
|
+
colorType === 'textColor'
|
|
857
|
+
? convertedColor.color
|
|
858
|
+
: convertedColor.backgroundColor;
|
|
859
|
+
|
|
860
|
+
editor.commands.selectAll();
|
|
861
|
+
|
|
862
|
+
if (colorValue?.startsWith('#')) {
|
|
863
|
+
if (colorType === 'textColor') {
|
|
864
|
+
fontSettings.selectedTextColor = colorValue;
|
|
865
|
+
} else {
|
|
866
|
+
fontSettings.selectedBackgroundColor = colorValue;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
triggerEditorStyleChange({
|
|
870
|
+
type: colorType,
|
|
871
|
+
value: colorValue,
|
|
872
|
+
});
|
|
873
|
+
} else {
|
|
874
|
+
// Handle logo theme colors using getRTEColor
|
|
875
|
+
if (isLogoColor(colorValue || '')) {
|
|
876
|
+
const processedColor = getRTEColor(
|
|
877
|
+
colorValue,
|
|
878
|
+
colorType === 'textColor' ? 'text' : 'background',
|
|
879
|
+
);
|
|
880
|
+
|
|
881
|
+
if (colorType === 'textColor') {
|
|
882
|
+
editor.commands.setColor(processedColor);
|
|
883
|
+
} else {
|
|
884
|
+
editor.commands.setHighlight({
|
|
885
|
+
color: processedColor,
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
} else {
|
|
889
|
+
if (colorType === 'textColor') {
|
|
890
|
+
editor.commands.unsetColor();
|
|
891
|
+
} else {
|
|
892
|
+
editor.commands.unsetHighlight();
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
const updateValue = {
|
|
898
|
+
textStyleType: undefined,
|
|
899
|
+
...(colorType === 'textColor'
|
|
900
|
+
? { color: colorValue }
|
|
901
|
+
: { backgroundColor: colorValue }),
|
|
902
|
+
};
|
|
903
|
+
|
|
904
|
+
if (props.name === 'textItems') {
|
|
905
|
+
contentSettingStore.updateTextItemTextStyleTypeWithStyles({
|
|
906
|
+
id: props.rawId,
|
|
907
|
+
name: props.name,
|
|
908
|
+
value: updateValue,
|
|
909
|
+
index: props.textItemIndex,
|
|
910
|
+
});
|
|
911
|
+
} else {
|
|
912
|
+
contentSettingStore.updateTextStyles({
|
|
913
|
+
id: props.rawId,
|
|
914
|
+
name: props.name,
|
|
915
|
+
value: updateValue,
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
|
|
668
920
|
onBeforeUnmount(() => {
|
|
669
921
|
editor.destroy();
|
|
670
922
|
});
|
|
@@ -690,5 +942,11 @@ export const useRichTextEditor = (
|
|
|
690
942
|
setInitialStyleSettings,
|
|
691
943
|
copyGlobalStyleSettings,
|
|
692
944
|
unsetAllMarks,
|
|
945
|
+
handleHyperlink,
|
|
946
|
+
hyperlinkValue,
|
|
947
|
+
setHyperlinkUrlValue,
|
|
948
|
+
shouldShow,
|
|
949
|
+
tippyOptions,
|
|
950
|
+
handleAdminColorChange,
|
|
693
951
|
};
|
|
694
952
|
};
|
|
@@ -5,6 +5,7 @@ export interface ButtonGroupBasicOption {
|
|
|
5
5
|
label: string;
|
|
6
6
|
isSelected: boolean;
|
|
7
7
|
dataAttribute?: string;
|
|
8
|
+
disabled?: boolean;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export type ButtonGroupOption =
|
|
@@ -18,4 +19,5 @@ export type ButtonGroupOption =
|
|
|
18
19
|
iconViewBox?: string;
|
|
19
20
|
iconSize?: string;
|
|
20
21
|
dataAttribute?: string;
|
|
22
|
+
disabled?: boolean;
|
|
21
23
|
};
|