Skip to content

Commit

Permalink
Migrate ExtendedRichText to ckEditor5
Browse files Browse the repository at this point in the history
  • Loading branch information
eschleb committed Dec 17, 2024
1 parent 8a60cda commit 3b8b72d
Show file tree
Hide file tree
Showing 28 changed files with 684 additions and 512 deletions.
18 changes: 18 additions & 0 deletions custom-definitions/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,22 @@
<scope>test</scope>
</dependency>
</dependencies>

<build>
<!-- default resources configuration which will filter the module descriptor -->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.js</include>
</includes>
</resource>
</resources>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.merkle.oss.magnolia.definition.custom.richtext;

import info.magnolia.ui.vaadin.ckeditor.CKEditor5TextField;
import info.magnolia.ui.vaadin.ckeditor.CKEditor5TextFieldState;

import com.vaadin.annotations.JavaScript;

/**
* Server side component for the ExtendedCKEditor 5 JavaScript rich-text editor.
*/
@JavaScript({
//a virtual path, which is redirected to an actual build specified in the microprofile.
//for developing set 'magnolia.ckeditor5.build' microprofile property.
"vaadin://ckeditor5.js",
"extended-ckeditor5-text-field-connector.js"
})
public class ExtendedCKEditor5TextField extends CKEditor5TextField {

@Override
protected State getState() {
return (State) super.getState();
}

@Override
protected State getState(final boolean markAsDirty) {
return (State) super.getState(markAsDirty);
}

public void setConfig(final ExtendedCKEditor5TextFieldConfig config) {
getState().extendedConfig = config;
getState().config = config;
}

/**
* Shared state for the {@link ExtendedCKEditor5TextField}.
*/
public static class State extends CKEditor5TextFieldState {
public ExtendedCKEditor5TextFieldConfig extendedConfig;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.merkle.oss.magnolia.definition.custom.richtext;

import info.magnolia.ui.vaadin.ckeditor.CKEditor5TextFieldConfig;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.merkle.oss.magnolia.definition.custom.richtext.toolbarbuilder.ToolbarGroup;
import com.merkle.oss.magnolia.definition.custom.richtext.toolbarbuilder.groupbuilder.FontGroupBuilder;

public class ExtendedCKEditor5TextFieldConfig extends CKEditor5TextFieldConfig {
public final Heading heading;

public ExtendedCKEditor5TextFieldConfig(
final String licenseKey,
final List<ToolbarGroup> toolbarGroups,
final List<HeadingOption> options
) {
super(licenseKey);
this.toolbar = new ExtendedToolbar(toolbarGroups, true);
this.heading = new Heading(options);
getToolbarGroup(toolbarGroups, FontGroupBuilder.FontToolbarGroup.class).ifPresent(fontToolbarGroup -> {
this.fontFamily.options = fontToolbarGroup.getFonts();
this.fontSize.options = fontToolbarGroup.getFontSizes();
this.fontColor.colors = fontToolbarGroup.getFontColors();
});
}

private <T extends ToolbarGroup> Optional<T> getToolbarGroup(final List<ToolbarGroup> toolbarGroups, final Class<T> clazz) {
return toolbarGroups.stream()
.filter(clazz::isInstance)
.findFirst()
.map(clazz::cast);
}

public static class ExtendedToolbar extends Toolbar {
public ExtendedToolbar(final List<ToolbarGroup> toolbarGroups, final boolean shouldNotGroupWhenFull) {
super.shouldNotGroupWhenFull = shouldNotGroupWhenFull;
super.items = toolbarGroups.stream().flatMap(group ->
Stream.concat(
group.getItems().stream(),
Stream.of("|")
)
).collect(Collectors.toList());
}
}

/**
* Represents a heading configuration.
*/
// See implementation here:
// https://github.com/ckeditor/ckeditor5/blob/v41.4.2/packages/ckeditor5-heading/src/utils.ts#L34
public static class Heading {
public final List<Option> options;

public Heading(final List<HeadingOption> options) {
this.options = options.stream().map(Option::new).collect(Collectors.toList());
}

/**
* Represents a heading option.
*/
// See implementation here:
// https://github.com/ckeditor/ckeditor5/blob/v41.4.2/packages/ckeditor5-heading/src/headingconfig.ts#L76
public static class Option {
public final String model;
public final String view;
public final String title;
public final String clazz;

public Option(final HeadingOption option) {
this.model = option.getModel();
this.view = option.getView().orElse(null);
this.title = option.getTitle();
this.clazz = option.getClazz();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,18 @@

import info.magnolia.dam.app.field.DamRichTextFieldDefinition;

import java.util.Collections;
import java.util.Map;
import java.util.List;
import java.util.Optional;

import javax.annotation.Nullable;

import com.merkle.oss.magnolia.definition.custom.richtext.toolbarbuilder.RichTextToolbarConfig;

public class ExtendedRichTextDefinition extends DamRichTextFieldDefinition {
@Nullable
private String formatTags;
@Nullable
private String customStyleSet;
@Nullable
private String customTemplates;
@Nullable
private String template;
@Nullable
private String extraAllowedContent;
@Nullable
private String contentCss;
@Nullable
private String enterMode;
private boolean forcePasteAsPlainText;
private boolean pasteFromWordRemoveFontStyles;
private boolean pasteFromWordPromptCleanup;
@Nullable
private String bodyClass;
@Nullable
private RichTextToolbarConfig toolbarConfig;
private Map<String, String> extraConfig = Collections.emptyMap();
private Map<String, String> externalPlugins = Collections.emptyMap();

private List<HeadingOption> headings = List.of(HeadingOption.values());

public ExtendedRichTextDefinition() {
setFactoryClass(ExtendedRichTextFactory.class);
Expand All @@ -47,107 +27,11 @@ public void setToolbarConfig(RichTextToolbarConfig toolbarConfig) {
this.toolbarConfig = toolbarConfig;
}

public Optional<String> getFormatTags() {
return Optional.ofNullable(formatTags);
}

public void setFormatTags(final String formatTags) {
this.formatTags = formatTags;
}

public Optional<String> getCustomStyleSet() {
return Optional.ofNullable(customStyleSet);
}

public void setCustomStyleSet(final String customStyleSet) {
this.customStyleSet = customStyleSet;
}

public Optional<String> getCustomTemplates() {
return Optional.ofNullable(customTemplates);
}

public void setCustomTemplates(final String customTemplates) {
this.customTemplates = customTemplates;
}

public Optional<String> getTemplate() {
return Optional.ofNullable(template);
}

public void setTemplate(final String template) {
this.template = template;
}

public Optional<String> getExtraAllowedContent() {
return Optional.ofNullable(extraAllowedContent);
}

public void setExtraAllowedContent(final String extraAllowedContent) {
this.extraAllowedContent = extraAllowedContent;
}

public Optional<String> getContentCss() {
return Optional.ofNullable(contentCss);
}

public void setContentCss(final String contentCss) {
this.contentCss = contentCss;
}

public Optional<String> getEnterMode() {
return Optional.ofNullable(enterMode);
}

public void setEnterMode(final String enterMode) {
this.enterMode = enterMode;
}

public boolean isForcePasteAsPlainText() {
return forcePasteAsPlainText;
}

public void setForcePasteAsPlainText(final boolean forcePasteAsPlainText) {
this.forcePasteAsPlainText = forcePasteAsPlainText;
}

public boolean isPasteFromWordRemoveFontStyles() {
return pasteFromWordRemoveFontStyles;
}

public void setPasteFromWordRemoveFontStyles(boolean pasteFromWordRemoveFontStyles) {
this.pasteFromWordRemoveFontStyles = pasteFromWordRemoveFontStyles;
}

public boolean isPasteFromWordPromptCleanup() {
return pasteFromWordPromptCleanup;
}

public void setPasteFromWordPromptCleanup(boolean pasteFromWordPromptCleanup) {
this.pasteFromWordPromptCleanup = pasteFromWordPromptCleanup;
}

public Optional<String> getBodyClass() {
return Optional.ofNullable(bodyClass);
}

public void setBodyClass(final String bodyClass) {
this.bodyClass = bodyClass;
}

public void setExtraConfig(final Map<String, String> extraConfig) {
this.extraConfig = extraConfig;
}

public Map<String, String> getExtraConfig() {
return extraConfig;
}

public void setExternalPlugins(final Map<String, String> externalPlugins) {
this.externalPlugins = externalPlugins;
public List<HeadingOption> getHeadings() {
return headings;
}

public Map<String, String> getExternalPlugins() {
return externalPlugins;
public void setHeadings(final List<HeadingOption> headings) {
this.headings = headings;
}
}
Loading

0 comments on commit 3b8b72d

Please sign in to comment.