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

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

Fixing a mistake

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