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

Last change on this file since 37480 was 37480, checked in by davidb, 13 months ago

Changes to get Greenbug back up and running. Theis commit targets two areas: we now need to explicitly specify 'o=xml' in our calls to general action with 'sa' as things like 'XSLTGetTemplateListFromFile'; we now also need to set the AJAX calls explicitly so they return string-type as their response (even if fundamentally the message is XML for example), which is done with dataType: 'text' in the jquery-based AJAX call. We are now using jquery v3.x and it looks like the newer versions of the library auto-sense the return time, where as the older jquery we were using did not to this, hence the reason for the change. In the long run it would be better to keep the returned response in XML, and use browser API to access XML to get to the data we want, however the decision for now was to explicitly set things so it is handled as a string, thereby allowing all our currently written code to operate as it used to.

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