1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
21
22 import org.apache.myfaces.tobago.component.Attributes;
23 import org.apache.myfaces.tobago.component.Facets;
24 import org.apache.myfaces.tobago.component.RendererTypes;
25 import org.apache.myfaces.tobago.component.UICommand;
26 import org.apache.myfaces.tobago.component.UIIn;
27 import org.apache.myfaces.tobago.component.UISelectBooleanCommand;
28 import org.apache.myfaces.tobago.component.UIToolBar;
29 import org.apache.myfaces.tobago.context.ResourceManagerUtils;
30 import org.apache.myfaces.tobago.renderkit.HtmlUtils;
31 import org.apache.myfaces.tobago.renderkit.InputRendererBase;
32 import org.apache.myfaces.tobago.renderkit.css.Classes;
33 import org.apache.myfaces.tobago.renderkit.css.Style;
34 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
35 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
36 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
37 import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
38 import org.apache.myfaces.tobago.renderkit.util.RenderUtils;
39 import org.apache.myfaces.tobago.util.ComponentUtils;
40 import org.apache.myfaces.tobago.util.CreateComponentUtils;
41 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import javax.faces.component.EditableValueHolder;
46 import javax.faces.component.UIComponent;
47 import javax.faces.component.UIPanel;
48 import javax.faces.context.FacesContext;
49 import java.io.IOException;
50
51
52 public class RichTextEditorRenderer extends InputRendererBase {
53
54 private static final Logger LOG = LoggerFactory.getLogger(RichTextEditorRenderer.class);
55
56 public static final String CHANGE_BUTTON = "togleState";
57
58 @Override
59 public void decode(FacesContext facesContext, UIComponent component) {
60 if (ComponentUtils.isOutputOnly(component)) {
61 return;
62 }
63
64 super.decode(facesContext, component);
65 String actionId = ComponentUtils.findPage(facesContext, component).getActionId();
66 if (actionId != null
67 && actionId.equals(component.getClientId(facesContext) + CHANGE_BUTTON)) {
68 boolean state
69 = ComponentUtils.getBooleanAttribute(component, Attributes.STATE_PREVIEW);
70 component.getAttributes().put(Attributes.STATE_PREVIEW, !state);
71 facesContext.renderResponse();
72
73 }
74 ((EditableValueHolder) component).setValid(true);
75 }
76
77 public static String contentToHtml(String content) {
78 try {
79 LOG.warn("richtext switched off, because of dependencies");
80 return content;
81
82
83 } catch (Exception e) {
84 LOG.error("failed to parser wiki markup", e);
85 }
86 return content;
87 }
88
89 @Override
90 public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
91
92 UIIn input = (UIIn) component;
93
94 boolean previewState
95 = ComponentUtils.getBooleanAttribute(input, Attributes.STATE_PREVIEW);
96
97
98 String clientId = input.getClientId(facesContext);
99
100 TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
101
102 writer.startElement(HtmlElements.DIV, input);
103 writer.writeClassAttribute(Classes.create(input, "container"));
104 HtmlRendererUtils.writeDataAttributes(facesContext, writer, input);
105 Style style = new Style(facesContext, input);
106 writer.writeStyleAttribute(style);
107
108 UIComponent toolbar = input.getFacet(Facets.TOOL_BAR);
109 if (toolbar == null) {
110 toolbar = createToolbar(facesContext, input);
111 }
112
113 facesContext.getExternalContext().getRequestMap().put(
114 "tobagoRichtextPreviewState", previewState ? Boolean.TRUE : Boolean.FALSE);
115
116 RenderUtils.encode(facesContext, toolbar);
117
118
119 String content = getCurrentValue(facesContext, input);
120
121 if (previewState) {
122 writer.startElement(HtmlElements.INPUT, input);
123 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
124 writer.writeNameAttribute(clientId);
125 writer.writeAttribute(HtmlAttributes.VALUE, content, true);
126 writer.endElement(HtmlElements.INPUT);
127
128 writer.startElement(HtmlElements.DIV, input);
129 writer.writeClassAttribute(Classes.create(input, "body"));
130 writer.writeIdAttribute(clientId);
131
132 writer.writeStyleAttribute(style);
133 writer.flush();
134 writer.write(RichTextEditorRenderer.contentToHtml(content));
135
136 writer.endElement(HtmlElements.DIV);
137 } else {
138 writer.startElement(HtmlElements.TEXTAREA, input);
139 writer.writeClassAttribute(Classes.create(input, "body"));
140 writer.writeNameAttribute(clientId);
141 writer.writeIdAttribute(clientId);
142 writer.writeStyleAttribute(style);
143 String onchange = HtmlUtils.generateOnchange(input, facesContext);
144 if (null != onchange) {
145 writer.writeAttribute(HtmlAttributes.ONCHANGE, onchange, null);
146 }
147
148 if (content != null) {
149 writer.writeText(content);
150 }
151
152 writer.endElement(HtmlElements.TEXTAREA);
153 }
154 writer.endElement(HtmlElements.DIV);
155 }
156
157 private UIComponent createToolbar(FacesContext facesContext, UIIn component) {
158 UIPanel toolbar = (UIPanel) CreateComponentUtils.createComponent(
159 facesContext, UIPanel.COMPONENT_TYPE, RendererTypes.TOOL_BAR);
160 String clientId = component.getClientId(facesContext);
161
162 component.getFacets().put(Facets.TOOL_BAR, toolbar);
163 toolbar.getAttributes().put(Attributes.ICON_SIZE, UIToolBar.ICON_SMALL);
164 toolbar.getAttributes().put(Attributes.LABEL_POSITION, UIToolBar.LABEL_OFF);
165
166 UICommand
167
168
169
170 command = (UICommand) CreateComponentUtils.createComponent(
171 facesContext, UISelectBooleanCommand.COMPONENT_TYPE, RendererTypes.MENU_COMMAND);
172 toolbar.getChildren().add(command);
173
174 command.getAttributes().put(Attributes.IMAGE, "image/tobago-richtext-edit.gif");
175 command.setValueBinding(Attributes.DISABLED, ComponentUtils.createValueBinding("#{! tobagoRichtextPreviewState}"));
176 command.setValueBinding(Attributes.VALUE, ComponentUtils.createValueBinding("#{!tobagoRichtextPreviewState}"));
177
178 String title = ResourceManagerUtils.getPropertyNotNull(
179 facesContext, "tobago", "tobago.richtexteditor.edit.title");
180 command.getAttributes().put(Attributes.TIP, title);
181
182 String onClick
183 = HtmlRendererUtils.createSubmitAction(clientId + RichTextEditorRenderer.CHANGE_BUTTON, true, null, null);
184 command.getAttributes().put(Attributes.ONCLICK, onClick);
185
186 command = (UICommand) CreateComponentUtils.createComponent(
187 facesContext, UISelectBooleanCommand.COMPONENT_TYPE, RendererTypes.MENU_COMMAND);
188 toolbar.getChildren().add(command);
189
190 command.getAttributes().put(Attributes.IMAGE, "image/tobago-richtext-preview.gif");
191 command.setValueBinding(Attributes.DISABLED, ComponentUtils.createValueBinding("#{tobagoRichtextPreviewState}"));
192 command.setValueBinding(Attributes.VALUE, ComponentUtils.createValueBinding("#{tobagoRichtextPreviewState}"));
193
194 title = ResourceManagerUtils.getPropertyNotNull(
195 facesContext, "tobago", "tobago.richtexteditor.preview.title");
196 command.getAttributes().put(Attributes.TIP, title);
197 command.getAttributes().put(Attributes.ONCLICK, onClick);
198
199 command = (UICommand) CreateComponentUtils.createComponent(
200 facesContext, UICommand.COMPONENT_TYPE, RendererTypes.MENU_COMMAND);
201 toolbar.getChildren().add(command);
202 command.getAttributes().put(Attributes.IMAGE, "image/config.gif");
203 command.getAttributes().put(Attributes.ONCLICK, "Tobago.doEditorCommand(this);");
204
205 return toolbar;
206 }
207
208 }