source: main/trunk/greenstone3/web/interfaces/default/js/debug_scripts.js@ 27013

Last change on this file since 27013 was 27013, checked in by sjm84, 11 years ago

Using jquery ui buttons instead of regular buttons

  • Property svn:executable set to *
File size: 17.7 KB
Line 
1function DebugWidget()
2{
3 //************************
4 //Private member variables
5 //************************
6
7 //Debugger state-keeping variables
8 var _debugOn = false;
9 var _pauseSelector = false;
10 var _elements = new Array();
11 var _itemSelected = false; //Used to prevent multiple elements from being highlighted
12 var _editModeText = false;
13 var _selectedTemplate;
14
15 //Page elements
16 var _mainDiv;
17
18 var _textEditor;
19 var _vEditor;
20
21 var _templateSelector;
22 var _editor;
23 var _editingDiv;
24 var _unpauseButton;
25 var _closeEditorButton;
26 var _xmlStatusBar;
27 var _saveButton;
28 var _swapEditorButton;
29
30 //Editor state-keeping variables
31 var _currentFilepath;
32 var _currentNodename;
33 var _currentName;
34 var _currentMatch;
35 var _currentNamespace;
36 var _isVisualEditor = true;
37
38 var _styleFunctions = new Array();
39
40 var partialPageReload = function()
41 {
42 $.ajax(document.URL)
43 .success(function(response)
44 {
45 //Get the body text from the response
46 var bodyStartIndex = response.indexOf("<body");
47 var bodyEndIndex = response.indexOf("</body>");
48 var bodyText = response.substring(bodyStartIndex, bodyEndIndex + 7);
49
50 //Get the current top area and container
51 var topLevelTopArea = $("#topArea");
52 var topLevelContainer = $("#container");
53
54 //Create a temporary div and put the html into it
55 var tempDiv = $("<div>");
56 tempDiv.html(bodyText);
57
58 //Replace the contents of the old elements with the new elements
59 var topArea = tempDiv.find("#topArea");
60 var container = tempDiv.find("#container");
61 topLevelTopArea.html(topArea.html());
62 topLevelContainer.html(container.html());
63
64 //Update the events for the debug elements that currently don't have events associated with them
65 var debugElems = $('debug, [debug="true"]').filter(function(){return (!($.data(this, "events"))) ? true : false});
66 addMouseEventsToDebugElements(debugElems);
67 })
68 .error(function()
69 {
70 alert("There was an error reloading the page, please reload manually.");
71 });
72 }
73
74 var callStyleFunctions = function()
75 {
76 for(var i = 0; i < _styleFunctions.length; i++)
77 {
78 var sFunction = _styleFunctions[i];
79 sFunction();
80 }
81 }
82
83 var createDebugDiv = function()
84 {
85 _mainDiv = $("<div>", {"id":"debugDiv"});
86 _mainDiv.css(
87 {
88 "position":"fixed",
89 "font-size":"0.8em",
90 "bottom":"0px",
91 "width":"100%",
92 "background":"white",
93 "border":"1px black solid",
94 "padding":"5px",
95 "z-index":100
96 });
97
98 _editingDiv = $("<div>");
99 var toolBarDiv = $("<div>");
100 toolBarDiv.css({"height":"40px"});
101
102 var buttonDiv = $("<div>");
103 buttonDiv.css("float", "left");
104 toolBarDiv.append(buttonDiv);
105
106 _templateSelector = $("<div>", {"id":"templateSelector"});
107 _templateSelector.css({"overflow":"auto", "width":"100%"});
108
109 var pickElementButton = $("<button>Enable debugging</button>");
110 pickElementButton.click(function()
111 {
112 if(!_debugOn)
113 {
114 pickElementButton.button("option", "label", "Disable debugging");
115 $("a").click(function(e)
116 {
117 e.preventDefault();
118 });
119 _debugOn = true;
120 }
121 else
122 {
123 pickElementButton.button("option", "label", "Enable debugging");
124 $("a").off("click");
125 clearAll();
126 _unpauseButton.button("option", "disabled", true);
127 _pauseSelector = false;
128 _debugOn = false;
129 }
130 });
131 _styleFunctions.push(function(){pickElementButton.button({icons:{primary:"ui-icon-power"}})});
132
133 _unpauseButton = $("<button>Select new element</button>");
134 _unpauseButton.click(function()
135 {
136 if(_pauseSelector)
137 {
138 _pauseSelector = false;
139 _unpauseButton.button("option", "disabled", true);
140 }
141 });
142 _styleFunctions.push(function(){_unpauseButton.button({icons:{primary:"ui-icon-pencil"}, disabled:true})});
143
144 _closeEditorButton = $("<button>Close editor</button>");
145 _closeEditorButton.click(function()
146 {
147 if(_closeEditorButton.button("option", "label") == "Close editor")
148 {
149 _closeEditorButton.button("option", "label", "Open editor");
150 _editingDiv.hide();
151 }
152 else
153 {
154 _closeEditorButton.button("option", "label", "Close editor");
155 _editingDiv.show();
156 }
157 });
158 _styleFunctions.push(function(){_closeEditorButton.button({icons:{primary:"ui-icon-newwin"}, disabled:true})});
159
160 _saveButton = $("<button>Save changes</button>");
161 _saveButton.click(function()
162 {
163 if(_editor)
164 {
165 var xmlString;
166 if(_isVisualEditor)
167 {
168 xmlString = new XMLSerializer().serializeToString(_vEditor.getXML());
169 }
170 else
171 {
172 xmlString = _editor.getValue();
173 }
174 xmlString = xmlString.replace(/&/g, "&amp;");
175
176 try
177 {
178 var xml = $.parseXML('<testContainer xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java" xmlns:util="xalan://org.greenstone.gsdl3.util.XSLTUtil" xmlns:gslib="http://www.greenstone.org/skinning" xmlns:gsf="http://www.greenstone.org/greenstone3/schema/ConfigFormat">' + xmlString + "</testContainer>");
179 }
180 catch(error)
181 {
182 alert("Could not save as there is a problem with the XML.");
183 return;
184 }
185
186 var url = gs.xsltParams.library_name;
187 var parameters = {"a":"g", "rt":"r", "s":"SaveXMLTemplateToFile", "s1.filePath":_currentFilepath, "s1.namespace":_currentNamespace, "s1.nodename":_currentNodename, "s1.xml":xmlString};
188
189 if(_currentName && _currentName.length > 0){parameters["s1.name"] = _currentName;}
190 if(_currentMatch && _currentMatch.length > 0){parameters["s1.match"] = _currentMatch;}
191
192 _saveButton.button("option", "label", "Saving...");
193 _saveButton.button("option", "disabled", true);
194
195 $.post(url, parameters)
196 .success(function()
197 {
198 $.ajax(gs.xsltParams.library_name + "?a=s&sa=c")
199 .success(function()
200 {
201 alert("The template has been saved successfully.");
202 })
203 .error(function()
204 {
205 alert("Error reloading collection.");
206 })
207 .complete(function()
208 {
209 _saveButton.button("option", "label", "Save changes");
210 _saveButton.button("option", "disabled", false);
211 partialPageReload();
212 });
213 })
214 .error(function()
215 {
216 alert("There was an error sending the request to the server, please try again.");
217 });
218 }
219 });
220 _styleFunctions.push(function(){_saveButton.button({icons:{primary:"ui-icon-disk"}, disabled:true})});
221
222 _swapEditorButton = $("<button>Switch to XML Editor</button>");
223 _swapEditorButton.button().click(function()
224 {
225 if(_vEditor && _textEditor)
226 {
227 if(_isVisualEditor)
228 {
229 _vEditor.getMainDiv().hide();
230 var containerNode = _vEditor.getXML().firstChild;
231 var templateNode = containerNode.firstChild;
232 while(templateNode)
233 {
234 if(templateNode.nodeType == 1)
235 {
236 break;
237 }
238 templateNode = templateNode.nextSibling;
239 }
240 var xmlText = new XMLSerializer().serializeToString(templateNode);
241 _editor.setValue(xmlText);
242 _editor.clearSelection();
243 _textEditor.show();
244 _swapEditorButton.button("option", "label", "Switch to Visual Editor");
245 _isVisualEditor = false;
246 }
247 else
248 {
249 _textEditor.hide();
250 var xmlText = _editor.getValue();
251 _vEditor.getMainDiv().remove();
252 _vEditor = new visualXMLEditor(xmlText);
253 _editingDiv.append(_vEditor.getMainDiv());
254 _vEditor.selectRootElement();
255 _vEditor.getMainDiv().show();
256 _swapEditorButton.button("option", "label", "Switch to XML Editor");
257 _isVisualEditor = true;
258 }
259 }
260 });
261 _styleFunctions.push(function(){_swapEditorButton.button({icons:{primary:"ui-icon-refresh"}})});
262
263 undoButton = $("<button>Undo</button>");
264 undoButton.click(function()
265 {
266 if(_isVisualEditor)
267 {
268 _vEditor.undo();
269 }
270 else
271 {
272 _editor.undo();
273 }
274 });
275 _styleFunctions.push(function(){undoButton.button({icons:{primary:"ui-icon-arrowreturnthick-1-w"}})});
276
277 _xmlStatusBar = $("<span>");
278 _xmlStatusBar.css("padding", "5px");
279 _xmlStatusBar.addClass("ui-corner-all");
280
281 //Check the XML for errors every 2 seconds
282 setInterval(function()
283 {
284 if(_editor)
285 {
286 var xmlString = _editor.getValue();
287 try
288 {
289 var xml = $.parseXML('<testContainer xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java" xmlns:util="xalan://org.greenstone.gsdl3.util.XSLTUtil" xmlns:gslib="http://www.greenstone.org/skinning" xmlns:gsf="http://www.greenstone.org/greenstone3/schema/ConfigFormat">' + xmlString + "</testContainer>");
290 }
291 catch(error)
292 {
293 console.log(error);
294 _xmlStatusBar.text("XML ERROR! (Mouse over for details)");
295 _xmlStatusBar.addClass("ui-state-error");
296 _xmlStatusBar.removeClass("ui-state-active");
297 _xmlStatusBar.attr("title", error);
298 _saveButton.button("option", "disabled", true);
299 _swapEditorButton.button("option", "disabled", true);
300 return;
301 }
302
303 _xmlStatusBar.text("XML OK!");
304 _xmlStatusBar.addClass("ui-state-active");
305 _xmlStatusBar.removeClass("ui-state-error");
306 _xmlStatusBar.removeAttr("title");
307 if(_saveButton.button("option", "label") == "Save changes")
308 {
309 _saveButton.button("option", "disabled", false);
310 }
311 if(_swapEditorButton.button("option", "label") == "Switch to Visual Editor")
312 {
313 _swapEditorButton.button("option", "disabled", false);
314 }
315 }
316
317 }, 2000);
318
319 var clear = $("<span>");
320 clear.css("clear", "both");
321 toolBarDiv.append(clear);
322
323 buttonDiv.append(pickElementButton);
324 buttonDiv.append(_unpauseButton);
325 buttonDiv.append(_closeEditorButton);
326 buttonDiv.append(_saveButton);
327 buttonDiv.append(_swapEditorButton);
328 buttonDiv.append(undoButton);
329 buttonDiv.append(_xmlStatusBar);
330
331 _styleFunctions.push(function(){$(".ui-button").css({"margin-right":"0.5em"});});
332
333 _mainDiv.append(toolBarDiv);
334 _mainDiv.append(_editingDiv);
335 _mainDiv.append("<div>Templates:</div>");
336 _mainDiv.append(_templateSelector);
337 }
338
339 var clearAll = function()
340 {
341 _itemSelected = false;
342 $(_elements).each(function()
343 {
344 $(this).remove();
345 });
346 }
347
348 var highlightElement = function(e)
349 {
350 var topBorderDiv = $("<div>");
351 var bottomBorderDiv = $("<div>");
352 var leftBorderDiv = $("<div>");
353 var rightBorderDiv = $("<div>");
354
355 topBorderDiv.css({"position":"absolute", "top":e.offset().top + "px", "left":e.offset().left + "px", "height":"0px", "width":e.width() + "px", "border":"1px solid red"});
356 bottomBorderDiv.css({"position":"absolute", "top":(e.offset().top + e.height()) + "px", "left":e.offset().left + "px", "height":"0px", "width":e.width() + "px", "border":"1px solid red"});
357 leftBorderDiv.css({"position":"absolute", "top":e.offset().top + "px", "left":e.offset().left + "px", "height":e.height() + "px", "width":"0px", "border":"1px solid red"});
358 rightBorderDiv.css({"position":"absolute", "top":e.offset().top + "px", "left":(e.offset().left + e.width()) + "px", "height":e.height() + "px", "width":"0px", "border":"1px solid red"});
359
360 $("body").append(topBorderDiv, bottomBorderDiv, leftBorderDiv, rightBorderDiv);
361
362 _elements.push(topBorderDiv);
363 _elements.push(bottomBorderDiv);
364 _elements.push(leftBorderDiv);
365 _elements.push(rightBorderDiv);
366 }
367
368 var addMouseEventsToInfoContainer = function(infoContainer, filepath, nodename, namespace, name, match)
369 {
370 infoContainer.click(function()
371 {
372 if(_selectedTemplate)
373 {
374 _selectedTemplate.css("border", _selectedTemplate.prevBorder);
375 }
376 _selectedTemplate = infoContainer;
377 _selectedTemplate.prevBorder = _selectedTemplate.css("border");
378 _selectedTemplate.css("border", "red 1px solid");
379
380 _currentFilepath = filepath;
381 _currentNodename = nodename;
382 _currentNamespace = namespace;
383 _currentName = name;
384 _currentMatch = match;
385
386 var responseName = "requestedNameTemplate";
387
388 var url = gs.xsltParams.library_name + "?a=g&rt=r&s=RetrieveXMLTemplateFromFile&s1.filePath=" + _currentFilepath + "&s1.namespace=" + _currentNamespace + "&s1.nodename=" + _currentNodename;
389 if(_currentMatch && _currentMatch.length > 0){url += "&s1.match=" + _currentMatch; responseName = "requestedMatchTemplate";}
390 if(_currentName && _currentName.length > 0){url += "&s1.name=" + _currentName;}
391 $.ajax(url)
392 .success(function(response)
393 {
394 var template;
395 if(response.search(responseName) != -1)
396 {
397 var startIndex = response.indexOf("<" + responseName + ">") + responseName.length + 2;
398 var endIndex = response.indexOf("</" + responseName + ">");
399 template = response.substring(startIndex, endIndex);
400 }
401 else
402 {
403 return;
404 }
405
406 _textEditor = $("<div>", {"id":"textEditor"});
407 _textEditor.css({"width":"100%", "height":"300px"});
408 _textEditor.val(template);
409
410 if(_isVisualEditor)
411 {
412 _textEditor.hide();
413 }
414
415 _editingDiv.empty();
416 _editingDiv.append($("<p>" + filepath + "</p>"));
417 _editingDiv.append(_textEditor);
418
419 _vEditor = new visualXMLEditor(template);
420 _editingDiv.append(_vEditor.getMainDiv());
421 _vEditor.selectRootElement();
422
423 if(!_isVisualEditor)
424 {
425 _vEditor.getMainDiv().hide();
426 }
427
428 _editor = ace.edit("textEditor");
429 _editor.getSession().setMode("ace/mode/xml");
430 _editor.getSession().setUseSoftTabs(false);
431 _editor.setValue(template);
432 _editor.clearSelection();
433
434 _textEditor.css({"min-height":"200px", "border-top":"5px solid #444"});
435 _textEditor.resizable({handles: 'n', resize:function()
436 {
437 _textEditor.css({top:"0px"});
438 _editor.resize();
439 }});
440
441 _closeEditorButton.button("option", "disabled", true);
442 })
443 .error(function()
444 {
445 console.log("ERROR");
446 });
447 });
448 infoContainer.mouseover(function()
449 {
450 $(this).data("background", $(this).css("background"));
451 $(this).css("background", "yellow");
452 });
453 infoContainer.mouseout(function()
454 {
455 $(this).css("background", $(this).data("background"));
456 });
457 }
458
459 var addMouseEventsToDebugElements = function(debugElems)
460 {
461 debugElems.click(function()
462 {
463 if(_debugOn)
464 {
465 _pauseSelector = true;
466 _unpauseButton.button("option", "disabled", false);
467 }
468 });
469
470 debugElems.mouseover(function()
471 {
472 if(_debugOn && !_pauseSelector)
473 {
474 var nodes = new Array();
475 if($(this).is("table, tr"))
476 {
477 var size = parseInt($(this).attr("debugSize"));
478 for(var i = 0; i < size; i++)
479 {
480 var tempNode = $("<div>");
481 tempNode.tempAttrs = new Array();
482 $(this.attributes).each(function()
483 {
484 if(this.value.charAt(0) == '[')
485 {
486 var values = eval(this.value);
487 if(values[i] == "")
488 {
489 return;
490 }
491 tempNode.attr(this.name, values[i]);
492 tempNode.tempAttrs.push({name:this.name, value:values[i]});
493 }
494 });
495 nodes.push(tempNode);
496 }
497 }
498 else
499 {
500 nodes.push(this);
501 }
502
503 $(nodes).each(function()
504 {
505 var filepath = $(this).attr("filename");
506 var fullNodename = $(this).attr("nodename");
507 var colonIndex = fullNodename.indexOf(":");
508 var namespace = fullNodename.substring(0, colonIndex);
509 var nodename = fullNodename.substring(colonIndex + 1);
510 var name = $(this).attr("name");
511 var match = $(this).attr("match");
512
513 var infoContainer = $("<div>");
514 infoContainer.addClass("gbTemplateContainer");
515
516 _elements.push(infoContainer);
517
518 addMouseEventsToInfoContainer(infoContainer, filepath, nodename, namespace, name, match);
519
520 /*
521 var attrstr = "";
522 var illegalNames = ["nodename", "filename", "style", "debug", "id", "class"];
523
524 var attributes = ((this.tempAttrs) ? this.tempAttrs : this.attributes);
525
526 $(attributes).each(function()
527 {
528 for(var i = 0; i < illegalNames.length; i++)
529 {
530 if(this.name == illegalNames[i]){return;}
531 }
532 attrstr += this.name + "=\"" + this.value + "\" ";
533 });
534
535 infoContainer.text("<" + fullNodename + " " + attrstr + ">");
536 */
537
538 if(name && name.length > 0)
539 {
540 infoContainer.text(name);
541 }
542 if(match && match.length > 0)
543 {
544 infoContainer.text(match);
545 }
546
547 if(_templateSelector.children("div").length > 0)
548 {
549 var spacer = $("<div>&gt;&gt;</div>");
550 spacer.addClass("gbSpacer");
551
552 _templateSelector.prepend(spacer);
553 _elements.push(spacer);
554 }
555
556 _templateSelector.prepend(infoContainer);
557
558 resizeContainers();
559 });
560
561 if(!_itemSelected)
562 {
563 _itemSelected = true;
564 highlightElement($(this));
565 }
566 }
567 });
568
569 debugElems.mouseout(function()
570 {
571 if(_debugOn && !_pauseSelector)
572 {
573 clearAll();
574 }
575 });
576 }
577
578 var resizeContainers = function()
579 {
580 var templates = _templateSelector.children(".gbTemplateContainer");
581 var spacers = _templateSelector.children(".gbSpacer");
582
583 var templateWidth = (79/templates.length) + "%";
584 templates.css("width", templateWidth);
585
586 if(spacers.length > 0)
587 {
588 var spacersWidth = (19/spacers.length) + "%";
589 spacers.css("width", spacersWidth);
590 }
591 }
592
593 this.init = function()
594 {
595 //We only want this on if we have debug elements in the page
596 var debugElems = $('debug, [debug="true"]');
597 if(!debugElems.length)
598 {
599 console.log("No debug tags present, debugging disabled.");
600 return;
601 }
602
603 createDebugDiv();
604 $("body").append(_mainDiv);
605
606 callStyleFunctions();
607
608 addMouseEventsToDebugElements(debugElems);
609 }
610
611}
612
613$(window).load(function()
614{
615 var debugWidget = new DebugWidget();
616 debugWidget.init();
617});
Note: See TracBrowser for help on using the repository browser.