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.templating.editor.client;
35
36
37 import java.util.Iterator;
38 import java.util.LinkedList;
39 import java.util.List;
40
41 import info.magnolia.templating.editor.client.dom.CMSComment;
42 import info.magnolia.templating.editor.client.dom.Comment;
43 import info.magnolia.templating.editor.client.dom.MgnlElement;
44 import info.magnolia.templating.editor.client.jsni.LegacyJavascript;
45 import info.magnolia.templating.editor.client.model.ModelStorage;
46
47 import com.google.gwt.core.client.EntryPoint;
48 import com.google.gwt.core.client.GWT;
49 import com.google.gwt.core.client.Scheduler;
50 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
51 import com.google.gwt.dom.client.Document;
52 import com.google.gwt.dom.client.Element;
53 import com.google.gwt.dom.client.MetaElement;
54 import com.google.gwt.dom.client.Node;
55 import com.google.gwt.dom.client.NodeList;
56 import com.google.gwt.event.dom.client.MouseUpEvent;
57 import com.google.gwt.event.dom.client.MouseUpHandler;
58 import com.google.gwt.http.client.Request;
59 import com.google.gwt.http.client.RequestBuilder;
60 import com.google.gwt.http.client.RequestCallback;
61 import com.google.gwt.http.client.RequestException;
62 import com.google.gwt.http.client.Response;
63 import com.google.gwt.http.client.URL;
64 import com.google.gwt.http.client.UrlBuilder;
65 import com.google.gwt.i18n.client.Dictionary;
66 import com.google.gwt.user.client.Event;
67 import com.google.gwt.user.client.EventListener;
68 import com.google.gwt.user.client.Window;
69 import com.google.gwt.user.client.ui.HTML;
70 import com.google.gwt.user.client.ui.RootPanel;
71
72
73
74
75
76
77 public class PageEditor extends HTML implements EventListener, EntryPoint {
78
79 private boolean pageEditBarAlreadyProcessed = false;
80 private String locale;
81 private static Dictionary dictionary;
82 private static ModelStorage storage = ModelStorage.getInstance();
83
84 private LinkedList<MgnlElement> mgnlElements = new LinkedList<MgnlElement>();
85
86 @Override
87 public void onModuleLoad() {
88 Element documentElement = Document.get().getDocumentElement();
89
90 locale = detectCurrentLocale(documentElement);
91
92 LegacyJavascript.exposeMgnlMessagesToGwtDictionary("info.magnolia.module.admininterface.messages");
93 dictionary = Dictionary.getDictionary("mgnlGwtMessages");
94
95
96
97 Scheduler.get().scheduleDeferred(new ScheduledCommand() {
98 @Override
99 public void execute() {
100 long stime = System.currentTimeMillis();
101 processCmsComments(Document.get().getDocumentElement(), null);
102 long etime= System.currentTimeMillis();
103 GWT.log("Time: " + String.valueOf(etime -stime));
104 cleanRootElements();
105 storage.getFocusModel().reset();
106
107 }
108 });
109
110 RootPanel.get().addDomHandler(new MouseUpHandler() {
111 @Override
112 public void onMouseUp(MouseUpEvent event) {
113
114 storage.getFocusModel().handleClick((Element)event.getNativeEvent().getEventTarget().cast());
115 event.stopPropagation();
116 }
117 }, MouseUpEvent.getType());
118
119 }
120
121 @Override
122 public void onBrowserEvent(Event event) {
123 super.onBrowserEvent(event);
124 }
125
126
127
128
129 public void openDialog(String dialog, String workspace, String path, String collectionName, String nodeName) {
130 if (collectionName == null) {
131 collectionName = "";
132 }
133 if (nodeName == null) {
134 nodeName = "";
135 }
136
137 LegacyJavascript.mgnlOpenDialog(path, collectionName, nodeName, dialog, workspace, "", "", "", locale);
138 }
139
140 public void moveComponentStart(String id) {
141 LegacyJavascript.mgnlMoveNodeStart(id);
142 }
143
144 public void moveComponentEnd(AbstractBarWidget source, String path) {
145 LegacyJavascript.mgnlMoveNodeEnd(source.getElement(), path);
146 }
147
148 public void moveComponentOver(AbstractBarWidget source) {
149 LegacyJavascript.mgnlMoveNodeHigh(source.getElement());
150 }
151
152 public void moveComponentOut(AbstractBarWidget source) {
153 LegacyJavascript.mgnlMoveNodeReset(source.getElement());
154 }
155
156 public void deleteComponent(String path) {
157 LegacyJavascript.mgnlDeleteNode(path);
158 }
159
160 public void addComponent(String workspace, String path, String collectionName, String nodeName, String availableComponents) {
161 if (collectionName == null) {
162 collectionName = "";
163 }
164 if (nodeName == null) {
165 nodeName = "mgnlNew";
166 }
167 if (availableComponents == null) {
168 availableComponents = "";
169 }
170 LegacyJavascript.mgnlOpenDialog(path, collectionName, nodeName, availableComponents, workspace, ".magnolia/dialogs/selectParagraph.html", "", "", locale);
171 }
172
173 public void preview(boolean isPreview) {
174 LegacyJavascript.mgnlPreview(isPreview);
175 }
176
177 public void showTree(String workspace, String path) {
178 LegacyJavascript.showTree(workspace, path);
179
180 }
181
182 public void createComponent(String workspace, String parent, String relPath, String itemType) {
183 GWT.log("Creating [" + itemType + "] in workspace [" + workspace + "] at path [" + parent + "/" + relPath + "]");
184
185 final StringBuilder url = new StringBuilder();
186 url.append(LegacyJavascript.getContextPath() + ".magnolia/pageeditor/PageEditorServlet");
187 url.append("?action=create");
188 url.append("&workspace=" + workspace);
189 url.append("&parent=" + parent);
190 url.append("&relPath=" + relPath);
191 url.append("&itemType=" + itemType);
192
193 RequestBuilder req = new RequestBuilder(RequestBuilder.GET, URL.encode(url.toString()));
194 req.setCallback(new RequestCallback() {
195
196 @Override
197 public void onResponseReceived(Request request, Response response) {
198 int status = response.getStatusCode();
199 String responseText = "";
200 boolean reload = false;
201
202 switch (status) {
203 case Response.SC_OK:
204 reload = true;
205 break;
206 case Response.SC_UNAUTHORIZED:
207 responseText = "Is your session expired? Please, try to login again.";
208 break;
209 default:
210 responseText = "See logs for more details.";
211 }
212
213 if (reload) {
214 UrlBuilder urlBuilder = Window.Location.createUrlBuilder();
215
216 urlBuilder.removeParameter("mgnlIntercept");
217 urlBuilder.removeParameter("mgnlPath");
218
219 Window.Location.replace(urlBuilder.buildString());
220 } else {
221 Window.alert("An error occurred on the server: response status code is " + status + "\n" + responseText);
222 }
223 }
224
225 @Override
226 public void onError(Request request, Throwable exception) {
227 Window.alert(exception.getMessage());
228 }
229 });
230 try {
231 req.send();
232 } catch (RequestException e) {
233 Window.alert("An error occurred while trying to send a request to the server: " + e.getMessage());
234 }
235
236 }
237
238
239
240
241 public static Dictionary getDictionary() {
242 return dictionary;
243 }
244
245
246
247
248
249 private String detectCurrentLocale(Element element) {
250 final NodeList<Element> meta = element.getOwnerDocument().getElementsByTagName("meta");
251 for (int i = 0; i < meta.getLength(); i++) {
252 MetaElement metaTag = ((MetaElement) meta.getItem(i));
253 if ("gwt:property".equals(metaTag.getName()) && metaTag.getContent().contains("locale")) {
254 String[] split = metaTag.getContent().split("=");
255 locale = split.length == 2 ? split[1] : "en";
256 GWT.log("Detected Locale " + locale);
257 break;
258 }
259 }
260 return locale;
261 }
262
263 private void processCmsComments(Node node, MgnlElement mgnlElement) {
264 for (int i = 0; i < node.getChildCount(); i++) {
265 Node childNode = node.getChild(i);
266 if (childNode.getNodeType() == Comment.COMMENT_NODE) {
267
268 try {
269 CMSComment comment = new CMSComment(((Comment)childNode.cast()).getData());
270
271
272
273 if (comment.getTagName().equals("cms:edit") && !comment.isClosing()) {
274
275 GWT.log("processing comment " + comment);
276
277 if (!pageEditBarAlreadyProcessed) {
278 GWT.log("element was detected as page edit bar. Injecting it...");
279 PageBarWidget pageBarWidget = new PageBarWidget(this, comment);
280 pageBarWidget.attach(childNode);
281 pageEditBarAlreadyProcessed = true;
282
283 storage.addEditBar(mgnlElement, pageBarWidget);
284
285
286 if (pageBarWidget.isPreviewMode()) {
287
288 GWT.log("We're in preview mode, stop processing DOM.");
289 break;
290 }
291 }
292 else if (mgnlElement != null && mgnlElement.isComponent()) {
293 GWT.log("element is a plain edit bar. Injecting it...");
294 EditBarWidget editBarWidget = new EditBarWidget(mgnlElement, comment, this);
295
296 editBarWidget.attach(childNode);
297 storage.addEditBar(mgnlElement, editBarWidget);
298
299 }
300 else if (mgnlElement != null && mgnlElement.isArea()) {
301 GWT.log("element was detected as area edit bar. Injecting it...");
302
303 AreaBarWidget areaBarWidget = new AreaBarWidget(mgnlElement, comment, this);
304 if (areaBarWidget.hasControls) {
305 areaBarWidget.attach(childNode);
306 storage.addEditBar(mgnlElement, areaBarWidget);
307 }
308 AbstractOverlayWidget overlay = new AreaOverlayWidget(mgnlElement);
309 overlay.attach();
310 storage.addOverlay(mgnlElement, overlay);
311
312 }
313 }
314 else if (mgnlElement != null && comment.isClosing() && !comment.getTagName().equals("cms:edit")) {
315
316 mgnlElement = mgnlElement.getParent();
317 }
318 else {
319 try {
320 mgnlElement = new MgnlElement(comment, mgnlElement);
321
322 if (mgnlElement.getParent() == null) {
323 storage.addRoot(mgnlElement);
324 }
325 else {
326 mgnlElement.getParent().getChildren().add(mgnlElement);
327 }
328
329 }
330 catch (IllegalArgumentException e) {
331 GWT.log("Not MgnlElement, skipping: " + e.toString());
332 }
333 }
334 }
335 catch (IllegalArgumentException e) {
336 GWT.log("Not CMSComment element, skipping: " + e.toString());
337
338 }
339 }
340 else if (childNode.getNodeType() == Element.ELEMENT_NODE && mgnlElement != null) {
341
342 Element element = childNode.cast();
343 if (element.hasTagName("A")) {
344 disableLink(element);
345 }
346 storage.addElement(mgnlElement, element);
347
348 if (!element.getClassName().equals("mgnlAreaEditBar") && !element.getClassName().equals("mgnlEditBar")) {
349 MgnlElement area = mgnlElement;
350 if (mgnlElement.isComponent()) {
351 area = mgnlElement.getParentArea();
352 }
353 if (area != null) {
354 if (area.getFirstElement() == null) {
355 area.setFirstElement(element);
356 }
357 if (area.getLastElement() == null || !area.getLastElement().isOrHasChild(element)) {
358 area.setLastElement(element);
359 }
360 }
361 }
362
363 }
364
365 processCmsComments(childNode, mgnlElement);
366 }
367
368 }
369
370 public native void disableLink(Element element)
371
372
373
374
375
376 ;
377
378 private void cleanRootElements() {
379
380
381 List<MgnlElement> newRoots = new LinkedList<MgnlElement>();
382 GWT.log(String.valueOf(storage.rootElements.size()));
383 Iterator<MgnlElement> it = storage.rootElements.iterator();
384 while (it.hasNext()) {
385 MgnlElement root = it.next();
386 if (storage.getEditBar(root) == null) {
387 for (MgnlElement child : root.getChildren()) {
388 child.setParent(null);
389 newRoots.add(child);
390 }
391 it.remove();
392 }
393 }
394 GWT.log(String.valueOf(storage.rootElements.size()));
395
396 storage.rootElements.addAll(newRoots);
397 GWT.log(String.valueOf(storage.rootElements.size()));
398
399 }
400
401 }