1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.primefaces.extensions.component.monacoeditor;
23
24 import java.io.IOException;
25
26 import javax.faces.component.UIComponent;
27 import javax.faces.context.FacesContext;
28 import javax.faces.context.ResponseWriter;
29
30 import org.primefaces.context.PrimeRequestContext;
31 import org.primefaces.renderkit.InputRenderer;
32 import org.primefaces.shaded.json.JSONWriter;
33 import org.primefaces.shaded.owasp.encoder.Encode;
34 import org.primefaces.util.Constants;
35 import org.primefaces.util.WidgetBuilder;
36
37
38
39
40
41
42 abstract class MonacoEditorCommonRenderer<TEditor extends MonacoEditorCommon<TEditorOpts>, TEditorOpts> extends InputRenderer {
43
44 protected static final String CALLBACK_SIGNATURE = "function()";
45
46 protected final Class<TEditor> componentClass;
47
48 protected MonacoEditorCommonRenderer(Class<TEditor> clazz) {
49 this.componentClass = clazz;
50 }
51
52 protected abstract void addBaseWidgetProperties(FacesContext context, WidgetBuilder wb, TEditor monacoEditor) throws IOException;
53
54 protected final void array(WidgetBuilder wb, String key, Iterable<String> values) throws IOException {
55 final StringBuilder builder = new StringBuilder();
56 builder.append('[');
57 for (final String item : values) {
58 builder.append('"');
59 builder.append(Encode.forJavaScript(item));
60 builder.append('"');
61 builder.append(',');
62 }
63 if (builder.length() > 1) {
64 builder.setLength(builder.length() - 1);
65 }
66 builder.append(']');
67 wb.nativeAttr(key, builder.toString());
68 }
69
70 @Override
71 public final void encodeEnd(final FacesContext context, final UIComponent component) throws IOException {
72 boolean hideResourceVersion = PrimeRequestContext.getCurrentInstance(context).isHideResourceVersion();
73 if (hideResourceVersion) {
74 logDevelopmentWarning(context, "Monaco Editor requires a resource version to work properly and '" +
75 Constants.ContextParams.HIDE_RESOURCE_VERSION + "' is currently configured.");
76 }
77 final TEditor monacoEditor = componentClass.cast(component);
78 encodeMarkup(context, monacoEditor);
79 encodeScript(context, monacoEditor);
80 }
81
82 protected final void encodeMarkup(final FacesContext context, final TEditor monacoEditor) throws IOException {
83 final ResponseWriter writer = context.getResponseWriter();
84 final String clientId = monacoEditor.getClientId();
85
86 String style = monacoEditor.getStyle() != null ? monacoEditor.getStyle() : "";
87 style = style.concat(";");
88 if (monacoEditor.getWidth() != null && !monacoEditor.getWidth().isEmpty()) {
89 style = style.concat("width:" + monacoEditor.getWidth() + ";");
90 }
91 if (monacoEditor.getHeight() != null && !monacoEditor.getHeight().isEmpty()) {
92 style = style.concat("height:" + monacoEditor.getHeight() + ";");
93 }
94 final StringBuilder styleClass = new StringBuilder();
95 styleClass.append(getMainStyleClass() + " ui-hidden-container ");
96 if (isEntireEditorDisabled(monacoEditor)) {
97 styleClass.append("ui-state-disabled ");
98 }
99 if (monacoEditor.getStyleClass() != null) {
100 styleClass.append(monacoEditor.getStyleClass());
101 }
102
103 writer.startElement("div", null);
104 writer.writeAttribute("id", clientId, null);
105 writer.writeAttribute("data-widget-var", monacoEditor.resolveWidgetVar(), null);
106 writer.writeAttribute("class", styleClass.toString(), null);
107 writer.writeAttribute("style", style, null);
108
109 encodeHiddenInput(context, monacoEditor);
110 encodeMonacoEditor(context, monacoEditor);
111
112 writer.endElement("div");
113 }
114
115 protected abstract boolean isEntireEditorDisabled(TEditor monacoEditor);
116
117 protected abstract void encodeHiddenInput(FacesContext context, TEditor monacoEditor) throws IOException;
118
119 protected abstract void encodeMonacoEditor(final FacesContext context, final TEditor monacoEditor) throws IOException;
120
121 protected final void encodeScript(final FacesContext context, final TEditor monacoEditor) throws IOException {
122 final WidgetBuilder wb = PrimeRequestContext.getCurrentInstance(context).getWidgetBuilder();
123
124 wb.init(getWidgetName(), monacoEditor);
125
126 array(wb, "availableEvents", monacoEditor.getEventNames());
127
128 if (monacoEditor.getCustomThemes() != null && !monacoEditor.getCustomThemes().isEmpty()) {
129 wb.nativeAttr("customThemes", JSONWriter.valueToString(monacoEditor.getCustomThemes()));
130 }
131
132 wb.attr("autoResize", monacoEditor.isAutoResize(), MonacoEditorCommon.DEFAULT_AUTO_RESIZE);
133 wb.attr("basename", monacoEditor.getBasename(), MonacoEditorCommon.DEFAULT_BASENAME);
134 wb.attr("directory", monacoEditor.getDirectory(), MonacoEditorCommon.DEFAULT_DIRECTORY);
135 wb.attr("disabled", monacoEditor.isDisabled(), MonacoEditorCommon.DEFAULT_DISABLED);
136 wb.attr("editorOptions", monacoEditor.getEditorOptions().toString());
137 wb.attr("extension", monacoEditor.getExtension(), MonacoEditorCommon.DEFAULT_EXTENSION);
138 wb.attr("language", getLanguage(monacoEditor), MonacoEditorCommon.DEFAULT_LANGUAGE);
139 wb.attr("locale", monacoEditor.calculateLocale().toString());
140 wb.attr("localeUrl", monacoEditor.getLocaleUrl());
141 wb.attr("readonly", monacoEditor.isReadonly(), MonacoEditorCommon.DEFAULT_READONLY);
142 wb.attr("placeholder", monacoEditor.getPlaceholder(), MonacoEditorCommon.DEFAULT_PLACEHOLDER);
143 wb.attr("scheme", monacoEditor.getScheme(), MonacoEditorCommon.DEFAULT_SCHEME);
144 wb.attr("tabIndex", monacoEditor.getTabindex(), MonacoEditorCommon.DEFAULT_TABINDEX);
145 wb.attr("height", monacoEditor.getHeight(), MonacoEditorCommon.DEFAULT_HEIGHT);
146 wb.attr("width", monacoEditor.getWidth(), MonacoEditorCommon.DEFAULT_WIDTH);
147
148 wb.callback("onblur", CALLBACK_SIGNATURE, monacoEditor.getOnblur());
149 wb.callback("onchange", CALLBACK_SIGNATURE, monacoEditor.getOnchange());
150 wb.callback("onfocus", CALLBACK_SIGNATURE, monacoEditor.getOnfocus());
151 wb.callback("oninitialized", CALLBACK_SIGNATURE, monacoEditor.getOninitialized());
152 wb.callback("onkeyup", CALLBACK_SIGNATURE, monacoEditor.getOnkeyup());
153 wb.callback("onmousedown", CALLBACK_SIGNATURE, monacoEditor.getOnmousedown());
154 wb.callback("onmousemove", CALLBACK_SIGNATURE, monacoEditor.getOnmousemove());
155 wb.callback("onmouseup", CALLBACK_SIGNATURE, monacoEditor.getOnmouseup());
156 wb.callback("onkeydown", CALLBACK_SIGNATURE, monacoEditor.getOnkeydown());
157 wb.callback("onpaste", CALLBACK_SIGNATURE, monacoEditor.getOnpaste());
158
159 addBaseWidgetProperties(context, wb, monacoEditor);
160
161 encodeClientBehaviors(context, monacoEditor);
162 wb.finish();
163 }
164
165 protected abstract String getLanguage(TEditor monacoEditor);
166
167 protected abstract String getMainStyleClass();
168
169 protected abstract String getWidgetName();
170 }