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

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

Allow visiting called templates as well as other improvements

  • Property svn:executable set to *
File size: 29.3 KB
Line 
1function DebugWidget()
2{
3 //************************
4 //Private member variables
5 //************************
6
7 //The this variable
8 var _greenbug = this;
9
10 //Template tracker class
11 var TemplateTracker = function()
12 {
13 var templates = new Array();
14 var currentIndex = -1;
15
16 this.push = function(object)
17 {
18 if(currentIndex < templates.length - 1 && templates.length > 0)
19 {
20 templates.splice(currentIndex + 1, templates.length - 1 - currentIndex);
21 }
22 templates[++currentIndex] = object;
23
24 _forwardButton.button("option", "disabled", true);
25 if(templates.length > 1)
26 {
27 _backButton.button("option", "disabled", false);
28 }
29 }
30
31 this.next = function()
32 {
33 if(currentIndex == templates.length - 1)
34 {
35 return;
36 }
37
38 if(currentIndex + 1 == templates.length - 1)
39 {
40 _forwardButton.button("option", "disabled", true);
41 }
42 _backButton.button("option", "disabled", false);
43
44 return templates[++currentIndex];
45 }
46
47 this.previous = function()
48 {
49 if(currentIndex == 0)
50 {
51 return;
52 }
53
54 if(currentIndex - 1 == 0)
55 {
56 _backButton.button("option", "disabled", true);
57 }
58 _forwardButton.button("option", "disabled", false);
59
60 return templates[--currentIndex];
61 }
62
63 this.peekPrevious = function()
64 {
65 if(currentIndex == 0)
66 {
67 return;
68 }
69
70 return templates[currentIndex - 1];
71 }
72
73 this.peekNext = function()
74 {
75 if(currentIndex == templates.length - 1)
76 {
77 return;
78 }
79
80 return templates[currentIndex + 1];
81 }
82 }
83
84 var _templateTracker = new TemplateTracker();
85
86 //Debugger state-keeping variables
87 var _debugOn = false;
88 var _pauseSelector = false;
89 var _elements = new Array();
90 var _itemSelected = false; //Used to prevent multiple elements from being highlighted
91 var _editModeText = false;
92 var _fromSelection = false;
93 var _selectedInfoContainers = new Array();
94
95 //Page elements
96 var _mainDiv;
97
98 var _textEditor;
99 var _vEditor;
100
101 var _navArea;
102 var _fileSelector;
103 var _templateSelector;
104 var _editor;
105 var _editingDiv;
106 var _xmlStatusBar;
107
108 //Buttons
109 var _backButton;
110 var _forwardButton;
111 var _currentSelectionButton;
112 var _enableSelectorButton;
113 var _closeEditorButton;
114 var _saveButton;
115 var _swapEditorButton;
116
117 //Editor state-keeping variables
118 var _currentFileName;
119 var _currentLocation;
120 var _currentNodename;
121 var _currentName;
122 var _currentMatch;
123 var _currentNamespace;
124 var _isVisualEditor = true;
125
126 var _styleFunctions = new Array();
127
128 //Used to reload the page while keeping the state of the editor
129 var partialPageReload = function(callback)
130 {
131 $.ajax(document.URL)
132 .success(function(response)
133 {
134 //Get the body text from the response
135 var bodyStartIndex = response.indexOf("<body");
136 var bodyEndIndex = response.indexOf("</body>");
137 var bodyText = response.substring(bodyStartIndex, bodyEndIndex + 7);
138
139 //Get the current top area and container
140 var topLevelTopArea = $("#topArea");
141 var topLevelContainer = $("#container");
142
143 //Create a temporary div and put the html into it
144 var tempDiv = $("<div>");
145 tempDiv.html(bodyText);
146
147 //Replace the contents of the old elements with the new elements
148 var topArea = tempDiv.find("#topArea");
149 var container = tempDiv.find("#container");
150 topLevelTopArea.html(topArea.html());
151 topLevelContainer.html(container.html());
152
153 //Update the events for the debug elements that currently don't have events associated with them
154 var debugElems = $('debug, [debug="true"]').filter(function(){return (!($.data(this, "events"))) ? true : false});
155 addMouseEventsToDebugElements(debugElems);
156 })
157 .error(function()
158 {
159 alert("There was an error reloading the page, please reload manually.");
160 });
161
162 if(callback)
163 {
164 callback();
165 }
166 }
167
168 //Some functions need to be called after an element is added to the page. So we store them and call them later.
169 var callStyleFunctions = function()
170 {
171 for(var i = 0; i < _styleFunctions.length; i++)
172 {
173 var sFunction = _styleFunctions[i];
174 sFunction();
175 }
176 }
177
178 var changeToSelectedElement = function(templateIndex, templateList)
179 {
180 _templateSelector.children("select").empty();
181
182 for(var i = 0; i < templateList.length; i++)
183 {
184 _templateSelector.children("select").append($(templateList[i]).clone(true));
185 }
186
187 if(templateIndex === undefined)
188 {
189 _templateSelector.find("option").first().trigger("change", [true]);
190 }
191 else
192 {
193 _templateSelector.find("option").filter(function(){return $(this).data("index") == templateIndex}).first().trigger("change", [true]);
194 }
195 return;
196 }
197
198 var createNavButtons = function(buttonDiv)
199 {
200 var navButtonHolder = $("<div>").css("float", "left");
201
202 var backForwardFunction = function(e)
203 {
204 var template;
205 if($(e.target).attr("id") == "veBack")
206 {
207 template = _templateTracker.previous();
208 }
209 else
210 {
211 template = _templateTracker.next();
212 }
213
214 if(!template)
215 {
216 return;
217 }
218
219 _fileSelector.find("option").filter(function(){return $(this).data("index") == template.fileIndex}).prop("selected", true);
220
221 changeToSelectedElement(template.templateIndex, template.list);
222 }
223
224 _backButton = $("<button>Back button</button>").attr("id", "veBack");
225 _backButton.click(backForwardFunction);
226 _styleFunctions.push(function(){_backButton.button({icons:{primary:"ui-icon-triangle-1-w"}, text:false, disabled:true})});
227
228 _forwardButton = $("<button>Forward button</button>").attr("id", "veForwards");
229 _forwardButton.click(backForwardFunction);
230 _styleFunctions.push(function(){_forwardButton.button({icons:{primary:"ui-icon-triangle-1-e"}, text:false, disabled:true})});
231
232 //Changes the template list to what is currently selected
233 _currentSelectionButton = $("<button>Current selection button</button>");
234 _currentSelectionButton.click(function()
235 {
236 _fileSelector.find("option").eq(0).prop("selected", true);
237 changeToSelectedElement(undefined, _selectedInfoContainers);
238
239 var selectedCopy = new Array();
240 for(var i = 0; i < _selectedInfoContainers.length; i++)
241 {
242 selectedCopy[i] = _selectedInfoContainers[i];
243 }
244
245 _templateTracker.push({fileIndex:-1, templateIndex:0, list:selectedCopy});
246 });
247 _styleFunctions.push(function(){_currentSelectionButton.button({icons:{primary:"ui-icon-pencil"}, text:false, disabled:true})});
248
249 navButtonHolder.append(_backButton);
250 navButtonHolder.append(_forwardButton);
251 navButtonHolder.append(_currentSelectionButton);
252 buttonDiv.append(navButtonHolder);
253 }
254
255 //Create the area where the buttons are stored
256 var createControlButtons = function(buttonDiv)
257 {
258 //Used to enable the selector to get the templates of a particular area of the page
259 _enableSelectorButton = $("<button>Select an element</button>");
260 _enableSelectorButton.click(function()
261 {
262 _enableSelectorButton.button("option", "label", "Select new element");
263 $("a").click(function(e)
264 {
265 e.preventDefault();
266 });
267 _debugOn = true;
268 _pauseSelector = false;
269 _enableSelectorButton.button("option", "disabled", true);
270 });
271 _styleFunctions.push(function(){_enableSelectorButton.button({icons:{primary:"ui-icon-pencil"}})});
272
273 //Used to minimise/restore the editor
274 _closeEditorButton = $("<button>Close editor</button>");
275 _closeEditorButton.click(function()
276 {
277 if(_closeEditorButton.button("option", "label") == "Close editor")
278 {
279 _closeEditorButton.button("option", "label", "Open editor");
280 _editingDiv.hide();
281 }
282 else
283 {
284 _closeEditorButton.button("option", "label", "Close editor");
285 _editingDiv.show();
286 }
287 });
288 _closeEditorButton.css("float", "right");
289 _styleFunctions.push(function(){_closeEditorButton.button({icons:{secondary:"ui-icon-newwin"}, disabled:true})});
290
291 //Used to save any changes that have been made to this template
292 _saveButton = $("<button>Save changes</button>");
293 _saveButton.click(function()
294 {
295 if(_editor)
296 {
297 var xmlString;
298 if(_isVisualEditor)
299 {
300 _vEditor.savePendingEdits();
301 xmlString = new XMLSerializer().serializeToString(_vEditor.getXML());
302 }
303 else
304 {
305 xmlString = _editor.getValue();
306 }
307 xmlString = xmlString.replace(/&/g, "&amp;");
308
309 try
310 {
311 var xml = $.parseXML('<testContainer xmlns:xslt="http://www.w3.org/1999/XSL/Transform" 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>");
312 }
313 catch(error)
314 {
315 alert("Could not save as there is a problem with the XML.");
316 return;
317 }
318
319 var url = gs.xsltParams.library_name;
320 var parameters = {"a":"g", "rt":"r", "s":"SaveXMLTemplateToFile", "s1.locationName":_currentLocation, "s1.fileName":_currentFileName, "s1.interfaceName":gs.xsltParams.interface_name, "s1.siteName":gs.xsltParams.site_name, "s1.collectionName":gs.cgiParams.c, "s1.namespace":_currentNamespace, "s1.nodename":_currentNodename, "s1.xml":xmlString};
321
322 if(_currentName && _currentName.length > 0){parameters["s1.name"] = _currentName;}
323 if(_currentMatch && _currentMatch.length > 0){parameters["s1.match"] = _currentMatch;}
324
325 _saveButton.button("option", "disabled", true);
326 $.blockUI({message:'<div class="ui-state-active">Saving, please wait...</div>'});
327
328 $.post(url, parameters)
329 .success(function()
330 {
331 $.ajax(gs.xsltParams.library_name + "?a=s&sa=c")
332 .success(function()
333 {
334 partialPageReload(function(){$.unblockUI();});
335 })
336 .error(function()
337 {
338 $.unblockUI();
339 alert("Error reloading collection.");
340 })
341 .complete(function()
342 {
343 _saveButton.button("option", "disabled", false);
344 });
345 })
346 .error(function()
347 {
348 alert("There was an error sending the request to the server, please try again.");
349 });
350 }
351 });
352 _styleFunctions.push(function(){_saveButton.button({icons:{primary:"ui-icon-disk"}, disabled:true})});
353
354 //Used to switch between the XML and Visual editors
355 _swapEditorButton = $("<button>Switch to XML editor</button>");
356 _swapEditorButton.button().click(function()
357 {
358 if(_vEditor && _textEditor)
359 {
360 if(_isVisualEditor)
361 {
362 _vEditor.savePendingEdits();
363 _vEditor.getMainDiv().hide();
364 var containerNode = _vEditor.getXML().firstChild;
365 var templateNode = containerNode.firstChild;
366 while(templateNode)
367 {
368 if(templateNode.nodeType == 1)
369 {
370 break;
371 }
372 templateNode = templateNode.nextSibling;
373 }
374 var xmlText = new XMLSerializer().serializeToString(templateNode);
375 _editor.setValue(xmlText);
376 _editor.clearSelection();
377 var UndoManager = require("ace/undomanager").UndoManager;
378 _editor.getSession().setUndoManager(new UndoManager());
379 _textEditor.show();
380 _swapEditorButton.button("option", "label", "Switch to visual editor");
381 _isVisualEditor = false;
382 _xmlStatusBar.show();
383 }
384 else
385 {
386 _textEditor.hide();
387 var xmlText = _editor.getValue();
388 _vEditor.getMainDiv().remove();
389 _vEditor = new visualXMLEditor(xmlText);
390 _editingDiv.append(_vEditor.getMainDiv());
391 _vEditor.selectRootElement();
392 _vEditor.getMainDiv().show();
393 _swapEditorButton.button("option", "label", "Switch to XML editor");
394 _isVisualEditor = true;
395 _xmlStatusBar.hide();
396 }
397 }
398 });
399 _styleFunctions.push(function(){_swapEditorButton.button({icons:{primary:"ui-icon-refresh"}})});
400
401 undoButton = $("<button>Undo</button>");
402 undoButton.click(function()
403 {
404 if(_isVisualEditor)
405 {
406 _vEditor.undo();
407 }
408 else
409 {
410 _editor.undo();
411 }
412 });
413 _styleFunctions.push(function(){undoButton.button({icons:{primary:"ui-icon-arrowreturnthick-1-w"}})});
414
415 buttonDiv.append(_enableSelectorButton);
416 buttonDiv.append(_closeEditorButton);
417 buttonDiv.append(_saveButton);
418 buttonDiv.append(_swapEditorButton);
419 buttonDiv.append(undoButton);
420 }
421
422 //Used to monitor the state of the XML in the XML editor and will notify the user if there is an error
423 var createXMLStatusBar = function(buttonDiv)
424 {
425 _xmlStatusBar = $("<span>");
426 _xmlStatusBar.css("padding", "5px");
427 _xmlStatusBar.addClass("ui-corner-all");
428 _styleFunctions.push(function(){_xmlStatusBar.hide();});
429
430 //Check the XML for errors every 2 seconds
431 setInterval(function()
432 {
433 if(_editor)
434 {
435 var xmlString = _editor.getValue();
436 try
437 {
438 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>");
439 }
440 catch(error)
441 {
442 console.log(error);
443 _xmlStatusBar.text("XML ERROR! (Mouse over for details)");
444 _xmlStatusBar.addClass("ui-state-error");
445 _xmlStatusBar.removeClass("ui-state-active");
446 _xmlStatusBar.attr("title", error);
447 _saveButton.button("option", "disabled", true);
448 _swapEditorButton.button("option", "disabled", true);
449 return;
450 }
451
452 _xmlStatusBar.text("XML OK!");
453 _xmlStatusBar.addClass("ui-state-active");
454 _xmlStatusBar.removeClass("ui-state-error");
455 _xmlStatusBar.removeAttr("title");
456 if(_saveButton.button("option", "label") == "Save changes")
457 {
458 _saveButton.button("option", "disabled", false);
459 }
460 if(_swapEditorButton.button("option", "label") == "Switch to visual editor")
461 {
462 _swapEditorButton.button("option", "disabled", false);
463 }
464 }
465 }, 2000);
466 buttonDiv.append(_xmlStatusBar);
467 }
468
469 //Create the elements that allow
470 var createFileAndTemplateSelectors = function(buttonDiv)
471 {
472 _templateSelector = $("<div>", {"id":"veTemplateSelector", "class":"ui-state-default ui-corner-all"});
473 _templateSelector.append($("<span>Templates: <span>"));
474 var templateSelectBox = $("<select>").append("<option>-- No templates --</option>");
475 templateSelectBox.change(function(e, triggered)
476 {
477 var selected = templateSelectBox.find(":selected");
478 var changeFunction = selected.data("changeFunction");
479 if(changeFunction)
480 {
481 changeFunction();
482 }
483
484 if(!triggered)
485 {
486 _templateTracker.push({fileIndex:_fileSelector.find(":selected").data("index"), templateIndex:selected.data("index"), list:templateSelectBox.children("option").clone(true)});
487 }
488 });
489 _templateSelector.append(templateSelectBox);
490 _fileSelector = $("<div>", {"id":"veFileSelector"});
491 buttonDiv.append(_fileSelector);
492 buttonDiv.append(_templateSelector);
493
494 //Populate the file selector
495 var url = gs.xsltParams.library_name + "?a=g&rt=r&s=GetXSLTFilesForCollection&s1.interfaceName=" + gs.xsltParams.interface_name + "&s1.siteName=" + gs.xsltParams.site_name + "&s1.collectionName=" + gs.cgiParams.c;
496 $.ajax(url)
497 .success(function(response)
498 {
499 var listStartIndex = response.indexOf("<fileListJSON>") + "<fileListJSON>".length;
500 var listEndIndex = response.indexOf("</fileListJSON>");
501
502 var listString = response.substring(listStartIndex, listEndIndex).replace(/&quot;/g, "\"").replace(/\\/g, "/");
503 var list = eval(listString);
504
505 var fileSelectBox = $("<select>");
506 fileSelectBox.append($("<option>-- Select a file --</option>").data("index", -1));
507 _fileSelector.addClass("ui-state-default");
508 _fileSelector.addClass("ui-corner-all");
509 _fileSelector.append("<span>Files: </span>");
510 _fileSelector.append(fileSelectBox);
511
512 for(var i = 0; i < list.length; i++)
513 {
514 var item = list[i];
515 var option = $("<option>" + item.path + " (" + item.location + ")</option>").data("index", i);
516 option.data("fileItem", item);
517 fileSelectBox.append(option);
518 }
519
520 fileSelectBox.change(function()
521 {
522 var selectedItem = fileSelectBox.find(":selected");
523
524 if(!selectedItem.data("fileItem"))
525 {
526 return;
527 }
528
529 _greenbug.populateTemplateSelectorFromFile(selectedItem.data("fileItem").path, selectedItem.data("fileItem").location, function(){_templateSelector.children("select").trigger("change")});
530 });
531 })
532 .error(function()
533 {
534 console.log("Error retrieving XSLT files");
535 });
536 }
537
538 //The function that creates all the necessary elements for Greenbug
539 var createDebugDiv = function()
540 {
541 _mainDiv = $("<div>", {"id":"debugDiv"});
542 _mainDiv.css(
543 {
544 "position":"fixed",
545 "font-size":"0.8em",
546 "bottom":"0px",
547 "width":"100%",
548 "background":"white",
549 "border":"1px black solid",
550 "padding":"5px",
551 "z-index":100
552 });
553
554 _editingDiv = $("<div>");
555 var toolBarDiv = $("<div>");
556 toolBarDiv.css({"height":"40px"});
557 toolBarDiv.append("<div>", {style:"clear:both;"});
558
559 var buttonDiv = $("<div>");
560 toolBarDiv.append(buttonDiv);
561 createNavButtons(buttonDiv);
562 createControlButtons(buttonDiv);
563 createFileAndTemplateSelectors(buttonDiv);
564 createXMLStatusBar(buttonDiv);
565
566 _styleFunctions.push(function(){$(".ui-button").css({"margin-right":"0.5em"});});
567
568 _mainDiv.append(toolBarDiv);
569 _mainDiv.append(_editingDiv);
570 _mainDiv.append(_navArea);
571 }
572
573 //Clear all selected elements on the page
574 var clearAll = function()
575 {
576 _itemSelected = false;
577 $(_elements).each(function()
578 {
579 $(this).remove();
580 });
581 }
582
583 //Put a border around the given element
584 var highlightElement = function(e)
585 {
586 var topBorderDiv = $("<div>");
587 var bottomBorderDiv = $("<div>");
588 var leftBorderDiv = $("<div>");
589 var rightBorderDiv = $("<div>");
590
591 topBorderDiv.css({"position":"absolute", "top":e.offset().top + "px", "left":e.offset().left + "px", "height":"0px", "width":e.width() + "px", "border":"1px solid red"});
592 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"});
593 leftBorderDiv.css({"position":"absolute", "top":e.offset().top + "px", "left":e.offset().left + "px", "height":e.height() + "px", "width":"0px", "border":"1px solid red"});
594 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"});
595
596 $("body").append(topBorderDiv, bottomBorderDiv, leftBorderDiv, rightBorderDiv);
597
598 _elements.push(topBorderDiv);
599 _elements.push(bottomBorderDiv);
600 _elements.push(leftBorderDiv);
601 _elements.push(rightBorderDiv);
602 }
603
604 this.populateTemplateSelectorFromFile = function(filename, location, callback)
605 {
606 var getURL = gs.xsltParams.library_name + "?a=g&rt=r&s=GetTemplateListFromFile&s1.fileName=" + filename + "&s1.locationName=" + location + "&s1.interfaceName=" + gs.xsltParams.interface_name + "&s1.siteName=" + gs.xsltParams.site_name + "&s1.collectionName=" + gs.cgiParams.c;
607 $.ajax(getURL)
608 .success(function(templateResponse)
609 {
610 var templateListStart = templateResponse.indexOf("<templateList>") + "<templateList>".length;
611 var templateListEnd = templateResponse.indexOf("</templateList>");
612 var templateListString = templateResponse.substring(templateListStart, templateListEnd).replace(/&quot;/g, "\"");
613 var templateList = eval(templateListString);
614
615 _templateSelector.children("select").empty();
616 if(templateList.length == 0)
617 {
618 _templateSelector.children("select").append($("<option>-- No templates --</option>").data("index", -1));
619 }
620
621 for(var i = 0; i < templateList.length; i++)
622 {
623 var namespace = templateList[i].namespace;
624 var nodename = "template";
625 var name = templateList[i].name;
626 var match = templateList[i].match;
627
628 if(name)
629 {
630 name = templateList[i].name.replace(/&apos;/g, "'").replace(/&quot;/g, "\"").replace(/&amp;/g, "&");
631 }
632 if(match)
633 {
634 match = templateList[i].match.replace(/&apos;/g, "'").replace(/&quot;/g, "\"").replace(/&amp;/g, "&");
635 }
636
637 var infoContainer = $("<option>");
638
639 _elements.push(infoContainer);
640
641 addChangeEventToInfoContainer(infoContainer, filename, location, nodename, namespace, name, match);
642
643 if(name && name.length > 0)
644 {
645 infoContainer.text(name);
646 }
647 if(match && match.length > 0)
648 {
649 infoContainer.text(match);
650 }
651
652 infoContainer.data("index", i);
653 _templateSelector.children("select").append(infoContainer);
654 }
655
656 if(callback)
657 {
658 callback();
659 }
660 });
661 }
662
663 //Change the current template in the XML and Visual editor
664 this.changeCurrentTemplate = function(location, filename, nodename, namespace, name, match)
665 {
666 _currentFileName = filename;
667 _currentLocation = location;
668 _currentNodename = nodename;
669 _currentNamespace = namespace;
670 _currentName = name;
671 _currentMatch = match;
672
673 var responseName = "requestedNameTemplate";
674
675 var url = gs.xsltParams.library_name + "?a=g&rt=r&s=GetXMLTemplateFromFile&s1.fileName=" + filename + "&s1.interfaceName=" + gs.xsltParams.interface_name + "&s1.siteName=" + gs.xsltParams.site_name + "&s1.collectionName=" + gs.cgiParams.c + "&s1.locationName=" + location + "&s1.namespace=" + namespace + "&s1.nodename=" + nodename;
676 if(match && match.length > 0){url += "&s1.match=" + match; responseName = "requestedMatchTemplate";}
677 if(name && name.length > 0){url += "&s1.name=" + name;}
678
679 $.ajax(url)
680 .success(function(response)
681 {
682 var template;
683 if(response.search(responseName) != -1)
684 {
685 var startIndex = response.indexOf("<" + responseName + ">") + responseName.length + 2;
686 var endIndex = response.indexOf("</" + responseName + ">");
687 template = response.substring(startIndex, endIndex);
688 }
689 else
690 {
691 return;
692 }
693
694 _textEditor = $("<div>", {"id":"textEditor"});
695 _textEditor.css({"width":"100%", "height":"300px"});
696 _textEditor.val(template);
697
698 if(_isVisualEditor)
699 {
700 _textEditor.hide();
701 }
702
703 _editingDiv.empty();
704 _editingDiv.append($("<p>Location: " + location + " <br/>Filename: " + filename + "</p>"));
705 _editingDiv.append(_textEditor);
706
707 _vEditor = new visualXMLEditor(template);
708 _editingDiv.append(_vEditor.getMainDiv());
709 _vEditor.setGreenbug(_greenbug);
710 _vEditor.selectRootElement();
711 $("#veToolboxDiv").height($("#veEditorContainer").height());
712
713 _vEditor.setFileLocation(location);
714 _vEditor.setFileName(filename);
715
716 if(!_isVisualEditor)
717 {
718 _vEditor.getMainDiv().hide();
719 }
720
721 _editor = ace.edit("textEditor");
722 _editor.getSession().setMode("ace/mode/xml");
723 _editor.getSession().setUseSoftTabs(false);
724 _editor.setValue(template);
725 _editor.clearSelection();
726 var UndoManager = require("ace/undomanager").UndoManager;
727 _editor.getSession().setUndoManager(new UndoManager());
728
729 _textEditor.css({"min-height":"200px", "border-top":"5px solid #444"});
730 _textEditor.resizable({handles: 'n', resize:function()
731 {
732 _textEditor.css({top:"0px"});
733 _editor.resize();
734 }});
735
736 _closeEditorButton.button("option", "disabled", false);
737 if(_closeEditorButton.button("option", "label") == "Open editor")
738 {
739 _closeEditorButton.button("option", "label", "Close editor");
740 _editingDiv.show();
741 }
742 })
743 .error(function()
744 {
745 console.log("Error getting the XML template from the file");
746 });
747 }
748
749 //Store the function that is called when this template is selected from the list
750 var addChangeEventToInfoContainer = function(infoContainer, filename, location, nodename, namespace, name, match)
751 {
752 infoContainer.data("changeFunction", function()
753 {
754 _greenbug.changeCurrentTemplate(location, filename, nodename, namespace, name, match);
755 });
756 }
757
758 this.getTemplateTracker = function()
759 {
760 return _templateTracker;
761 }
762
763 //Turns a filename into it's location (i.e. interface/site/collection) and name
764 this.fileNameToLocationAndName = function(filepath)
765 {
766 var location;
767 var filename;
768 //Use the filepath to work out where this file is from
769 if(filepath.search(/[\/\\]interfaces[\/\\]/) != -1)
770 {
771 location = "interface";
772 filename = filepath.replace(/.*[\/\\]transform[\/\\]/, "");
773 }
774 else if(filepath.search(/[\/\\]sites[\/\\].*[\/\\]collect[\/\\].*[\/\\]etc[\/\\]/) != -1)
775 {
776 location = "collectionConfig";
777 filename = filepath.replace(/.*[\/\\]sites[\/\\].*[\/\\]collect[\/\\].*[\/\\]etc[\/\\]/, "");
778 }
779 else if(filepath.search(/[\/\\]sites[\/\\].*[\/\\]collect[\/\\].*[\/\\]transform[\/\\]/) != -1)
780 {
781 location = "collection";
782 filename = filepath.replace(/.*[\/\\]sites[\/\\].*[\/\\]collect[\/\\].*[\/\\]transform[\/\\]/, "");
783 }
784 else if(filepath.search(/[\/\\]sites[\/\\].*[\/\\]transform[\/\\]/) != -1)
785 {
786 location = "site";
787 filename = filepath.replace(/.*[\/\\]sites[\/\\].*[\/\\]transform[\/\\]/, "");
788 }
789
790 filename = filename.replace(/\\/g, "/");
791
792 return {location:location, filename:filename};
793 }
794
795 //Add the mouse events to the <debug> elemetns that are called when the selector is anabled
796 var addMouseEventsToDebugElements = function(debugElems)
797 {
798 debugElems.click(function(e)
799 {
800 if(_debugOn)
801 {
802 e.stopPropagation();
803 $("a").off("click");
804 _debugOn = false;
805 _pauseSelector = true;
806 _enableSelectorButton.button("option", "disabled", false);
807 _templateSelector.children("select").trigger("change", [true]);
808 _fileSelector.children("select").val("none");
809
810 var selectedCopy = new Array();
811 for(var i = 0; i < _selectedInfoContainers.length; i++)
812 {
813 selectedCopy[i] = _selectedInfoContainers[i];
814 }
815
816 _currentSelectionButton.button("option", "disabled", false);
817
818 _templateTracker.push({fileIndex:-1, list:selectedCopy, templateIndex:0});
819 }
820 });
821
822 debugElems.mouseover(function()
823 {
824 if(_debugOn && !_pauseSelector)
825 {
826 _fileSelector.find("select").val("none");
827
828 var nodes = new Array();
829 if($(this).is("table, tr"))
830 {
831 var size = parseInt($(this).attr("debugSize"));
832 for(var i = 0; i < size; i++)
833 {
834 var tempNode = $("<div>");
835 tempNode.tempAttrs = new Array();
836 $(this.attributes).each(function()
837 {
838 if(this.value.charAt(0) == '[')
839 {
840 var values = eval(this.value);
841 if(values[i] == "")
842 {
843 return;
844 }
845 tempNode.attr(this.name, values[i]);
846 tempNode.tempAttrs.push({name:this.name, value:values[i]});
847 }
848 });
849 nodes.push(tempNode);
850 }
851 }
852 else
853 {
854 nodes.push(this);
855 }
856
857 $(nodes).each(function()
858 {
859 var filepath = $(this).attr("filename");
860 var fullNodename = $(this).attr("nodename");
861 var colonIndex = fullNodename.indexOf(":");
862 var namespace = fullNodename.substring(0, colonIndex);
863 var nodename = fullNodename.substring(colonIndex + 1);
864 var name = $(this).attr("name");
865 var match = $(this).attr("match");
866
867 var file = _greenbug.fileNameToLocationAndName(filepath);
868
869 var infoContainer = $("<option>");
870
871 _elements.push(infoContainer);
872
873 addChangeEventToInfoContainer(infoContainer, file.filename, file.location, nodename, namespace, name, match);
874
875 if(name && name.length > 0)
876 {
877 infoContainer.text(name);
878 }
879 if(match && match.length > 0)
880 {
881 infoContainer.text(match);
882 }
883
884 _templateSelector.children("select").append(infoContainer);
885 infoContainer.data("index", infoContainer.index());
886 _selectedInfoContainers.push(infoContainer.clone(true));
887 });
888
889 if(!_itemSelected)
890 {
891 _itemSelected = true;
892 highlightElement($(this));
893 }
894 }
895 });
896
897 debugElems.mouseout(function()
898 {
899 if(_debugOn && !_pauseSelector)
900 {
901 clearAll();
902 _templateSelector.children("select").empty();
903 _selectedInfoContainers = new Array();
904 }
905 });
906 }
907
908 //Remove <debug> elements from the title
909 var fixTitle = function()
910 {
911 $("title").text($("title").text().replace(/<[^>]*>/g, ""));
912 }
913
914 //Initialise Greenbug
915 this.init = function()
916 {
917 //We only want this on if we have debug elements in the page
918 var debugElems = $('debug, [debug="true"]');
919 if(!debugElems.length)
920 {
921 var enableGBButtonHolder = $("<div>", {"title":"Enable Greenbug", "id":"gbEnableButton", "class":"ui-state-default ui-corner-all"});
922 enableGBButtonHolder.append($("<img>", {"src":gs.imageURLs.greenBug}));
923 enableGBButtonHolder.click(function()
924 {
925 var url = document.URL;
926 url = url.replace(/[\?&]debug=0/g, "").replace(/[\?&]debug=1/g, "");
927
928 if(url.indexOf("?") == url.length - 1)
929 {
930 document.location.href = url += "debug=1";
931 }
932 else if(url.indexOf("?") != -1)
933 {
934 document.location.href = url += "&debug=1";
935 }
936 else
937 {
938 document.location.href = url += "?debug=1";
939 }
940 });
941 $("body").append(enableGBButtonHolder);
942 return;
943 }
944
945 createDebugDiv();
946 $("body").append(_mainDiv);
947
948 callStyleFunctions();
949
950 addMouseEventsToDebugElements(debugElems);
951 fixTitle();
952 }
953}
954
955//The code entry point
956$(window).load(function()
957{
958 var debugWidget = new DebugWidget();
959 debugWidget.init();
960});
Note: See TracBrowser for help on using the repository browser.