1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.form.field.factory;
35
36 import static info.magnolia.ui.field.factory.RichTextFieldFactory.PLUGIN_NAME_MAGNOLIALINK;
37 import static info.magnolia.ui.field.factory.RichTextFieldFactory.PLUGIN_PATH_MAGNOLIALINK;
38 import static info.magnolia.ui.vaadin.ckeditor.MagnoliaCKEditorConfig.*;
39 import static info.magnolia.ui.vaadin.ckeditor.MagnoliaCKEditorTextFieldEvents.*;
40
41 import info.magnolia.i18nsystem.SimpleTranslator;
42 import info.magnolia.repository.RepositoryConstants;
43 import info.magnolia.ui.api.app.AppController;
44 import info.magnolia.ui.api.app.ChooseDialogCallback;
45 import info.magnolia.ui.api.context.UiContext;
46 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
47 import info.magnolia.ui.form.field.definition.RichTextFieldDefinition;
48 import info.magnolia.ui.field.factory.RichTextFieldFactory.MagnoliaLink;
49 import info.magnolia.ui.field.factory.RichTextFieldFactory.PluginData;
50 import info.magnolia.ui.vaadin.integration.jcr.JcrItemId;
51 import info.magnolia.ui.vaadin.integration.jcr.JcrItemUtil;
52 import info.magnolia.ui.vaadin.richtext.MagnoliaRichTextField;
53 import info.magnolia.ui.vaadin.richtext.MagnoliaRichTextFieldConfig;
54
55 import java.util.List;
56
57 import javax.inject.Inject;
58 import javax.jcr.Node;
59
60 import org.apache.commons.lang3.StringUtils;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64 import com.google.gson.Gson;
65 import com.vaadin.server.Sizeable.Unit;
66 import com.vaadin.server.VaadinService;
67 import com.vaadin.v7.data.Item;
68 import com.vaadin.v7.ui.Field;
69
70
71
72
73 public class RichTextFieldFactory extends AbstractFieldFactory<RichTextFieldDefinition, String> {
74
75 private static final Logger log = LoggerFactory.getLogger(RichTextFieldFactory.class);
76
77 protected final AppController appController;
78 protected final UiContext uiContext;
79 protected final SimpleTranslator i18n;
80 protected MagnoliaRichTextField richTextEditor;
81
82 @Inject
83 public RichTextFieldFactory(RichTextFieldDefinition definition, Item relatedFieldItem, UiContext uiContext, I18NAuthoringSupport i18NAuthoringSupport, AppController appController, SimpleTranslator i18n) {
84 super(definition, relatedFieldItem, uiContext, i18NAuthoringSupport);
85 this.appController = appController;
86 this.uiContext = uiContext;
87 this.i18n = i18n;
88 }
89
90 @Override
91 protected Field<String> createFieldComponent() {
92
93 MagnoliaRichTextFieldConfig config = initializeCKEditorConfig();
94 richTextEditor = new MagnoliaRichTextField(config);
95 if (definition.getHeight() > 0) {
96 richTextEditor.setHeight(definition.getHeight(), Unit.PIXELS);
97 }
98
99 richTextEditor.addListener(new MagnoliaRichTextField.PluginListener() {
100 @Override
101 public void onPluginEvent(String eventName, String value) {
102 if (eventName.equals(EVENT_GET_MAGNOLIA_LINK)) {
103 try {
104 Gson gson = new Gson();
105 PluginData pluginData = gson.fromJson(value, PluginData.class);
106 openLinkDialog(pluginData.path, pluginData.workspace);
107 } catch (Exception e) {
108 log.error("openLinkDialog failed", e);
109 richTextEditor.firePluginEvent(EVENT_CANCEL_LINK, i18n.translate("ui-form.richtexteditorexception.opentargetappfailure"));
110 }
111 }
112 }
113 });
114
115 return richTextEditor;
116 }
117
118 protected MagnoliaRichTextFieldConfig initializeCKEditorConfig() {
119
120 MagnoliaRichTextFieldConfig config = new MagnoliaRichTextFieldConfig();
121 String path = VaadinService.getCurrentRequest().getContextPath();
122
123
124 config.addExternalPlugin(PLUGIN_NAME_MAGNOLIALINK, path + PLUGIN_PATH_MAGNOLIALINK);
125 config.addListenedEvent(EVENT_GET_MAGNOLIA_LINK);
126
127
128 if (StringUtils.isNotBlank(definition.getConfigJsFile())) {
129 config.addExtraConfig("customConfig", "'" + path + definition.getConfigJsFile() + "'");
130 return config;
131 }
132
133
134 if (!definition.isAlignment()) {
135 config.addToRemovePlugins("justify");
136 }
137 if (!definition.isImages()) {
138 config.addToRemovePlugins("image");
139 }
140 if (!definition.isLists()) {
141
142 config.addToRemovePlugins("enterkey");
143 config.addToRemovePlugins("indent");
144 config.addToRemovePlugins("list");
145 }
146 if (!definition.isSource()) {
147 config.addToRemovePlugins("sourcearea");
148 }
149 if (!definition.isTables()) {
150 config.addToRemovePlugins("table");
151 config.addToRemovePlugins("tabletools");
152 config.addToRemovePlugins("tableselection");
153 }
154
155 if (definition.getColors() != null) {
156 config.addExtraConfig("colorButton_colors", "'" + definition.getColors() + "'");
157 config.addExtraConfig("colorButton_enableMore", "false");
158 config.addToRemovePlugins("colordialog");
159 } else {
160 config.addToRemovePlugins("colorbutton");
161 config.addToRemovePlugins("colordialog");
162 }
163 if (definition.getFonts() != null) {
164 config.addExtraConfig("font_names", "'" + definition.getFonts() + "'");
165 } else {
166 config.addExtraConfig("removeButtons", "'Font'");
167 }
168 if (definition.getFontSizes() != null) {
169 config.addExtraConfig("fontSize_sizes", "'" + definition.getFontSizes() + "'");
170 } else {
171 config.addExtraConfig("removeButtons", "'FontSize'");
172 }
173 if (definition.getFonts() == null && definition.getFontSizes() == null) {
174 config.addToRemovePlugins("font");
175 config.addToRemovePlugins("fontSize");
176 }
177
178
179 List<ToolbarGroup> toolbars = initializeToolbarConfig();
180 config.addToolbarLine(toolbars);
181
182 config.addToExtraPlugins(PLUGIN_NAME_MAGNOLIALINK);
183 config.addToRemovePlugins("elementspath");
184 config.setBaseFloatZIndex(150);
185 config.setResizeEnabled(false);
186
187 return config;
188 }
189
190 protected List<ToolbarGroup> initializeToolbarConfig() {
191 return defaultToolbar();
192 }
193
194 private String mapWorkSpaceToApp(String workspace) {
195 if (workspace.equalsIgnoreCase("dam")) {
196 return "assets";
197 } else if (workspace.equalsIgnoreCase(RepositoryConstants.WEBSITE)) {
198 return "pages";
199 }
200
201 return "";
202 }
203
204 private void openLinkDialog(String path, String workspace) {
205 appController.openChooseDialog(mapWorkSpaceToApp(workspace), uiContext, path, new ChooseDialogCallback() {
206 @Override
207 public void onItemChosen(String actionName, Object chosenValue) {
208 if (!(chosenValue instanceof JcrItemId)) {
209 richTextEditor.firePluginEvent(EVENT_CANCEL_LINK);
210 return;
211 }
212 try {
213 javax.jcr.Item jcrItem = JcrItemUtil.getJcrItem((JcrItemId) chosenValue);
214 if (!jcrItem.isNode()) {
215 return;
216 }
217 final Node selected = (Node) jcrItem;
218 Gson gson = new Gson();
219 MagnoliaLink mlink = new MagnoliaLink();
220 mlink.identifier = selected.getIdentifier();
221 mlink.repository = selected.getSession().getWorkspace().getName();
222 mlink.path = selected.getPath();
223 if (selected.hasProperty("title")) {
224 mlink.caption = selected.getProperty("title").getString();
225 } else {
226 mlink.caption = selected.getName();
227 }
228
229 richTextEditor.firePluginEvent(EVENT_SEND_MAGNOLIA_LINK, gson.toJson(mlink));
230 } catch (Exception e) {
231 String error = i18n.translate("ui-form.richtexteditorexception.cannotaccessselecteditem");
232 log.error(error, e);
233 richTextEditor.firePluginEvent(EVENT_CANCEL_LINK, error);
234 }
235 }
236
237 @Override
238 public void onCancel() {
239 richTextEditor.firePluginEvent(EVENT_CANCEL_LINK);
240 }
241 });
242 }
243 }