function DebugWidget()
{
//************************
//Private member variables
//************************
//The this variable
var _greenbug = this;
//Template tracker class
var TemplateTracker = function()
{
var templates = new Array();
var currentIndex = -1;
this.push = function(object)
{
if(currentIndex < templates.length - 1 && templates.length > 0)
{
templates.splice(currentIndex + 1, templates.length - 1 - currentIndex);
}
templates[++currentIndex] = object;
_forwardButton.button("option", "disabled", true);
if(templates.length > 1)
{
_backButton.button("option", "disabled", false);
}
}
this.next = function()
{
if(currentIndex == templates.length - 1)
{
return;
}
if(currentIndex + 1 == templates.length - 1)
{
_forwardButton.button("option", "disabled", true);
}
_backButton.button("option", "disabled", false);
return templates[++currentIndex];
}
this.previous = function()
{
if(currentIndex == 0)
{
return;
}
if(currentIndex - 1 == 0)
{
_backButton.button("option", "disabled", true);
}
_forwardButton.button("option", "disabled", false);
return templates[--currentIndex];
}
this.peekPrevious = function()
{
if(currentIndex == 0)
{
return;
}
return templates[currentIndex - 1];
}
this.peekNext = function()
{
if(currentIndex == templates.length - 1)
{
return;
}
return templates[currentIndex + 1];
}
}
var _templateTracker = new TemplateTracker();
//Debugger state-keeping variables
var _debugOn = false;
var _pauseSelector = false;
var _elements = new Array();
var _itemSelected = false; //Used to prevent multiple elements from being highlighted
var _editModeText = false;
var _fromSelection = false;
var _selectedInfoContainers = new Array();
//Page elements
var _mainDiv;
var _textEditor;
var _vEditor;
var _navArea;
var _fileSelector;
var _templateSelector;
var _editor;
var _editingDiv;
var _xmlStatusBar;
//Buttons
var _backButton;
var _forwardButton;
var _currentSelectionButton;
var _enableSelectorButton;
var _closeEditorButton;
var _saveButton;
var _swapEditorButton;
//Editor state-keeping variables
var _currentFileName;
var _currentLocation;
var _currentNodename;
var _currentName;
var _currentMatch;
var _currentNamespace;
var _currentXPath;
var _isVisualEditor = true;
var _styleFunctions = new Array();
//Used to reload the page while keeping the state of the editor
var partialPageReload = function(callback)
{
$.ajax(document.URL)
.success(function(response)
{
//Get the body text from the response
var bodyStartIndex = response.indexOf("
");
var bodyText = response.substring(bodyStartIndex, bodyEndIndex + 7);
//Get the current top area and container
var topLevelTopArea = $("#topArea");
var topLevelContainer = $("#container");
//Create a temporary div and put the html into it
var tempDiv = $("
");
tempDiv.html(bodyText);
//Replace the contents of the old elements with the new elements
var topArea = tempDiv.find("#topArea");
var container = tempDiv.find("#container");
topLevelTopArea.html(topArea.html());
topLevelContainer.html(container.html());
//Update the events for the debug elements that currently don't have events associated with them
var debugElems = $('debug, [debug="true"]').filter(function(){return (!($.data(this, "events"))) ? true : false});
addMouseEventsToDebugElements(debugElems);
})
.error(function()
{
alert("There was an error reloading the page, please reload manually.");
});
if(callback)
{
callback();
}
}
//Some functions need to be called after an element is added to the page. So we store them and call them later.
var callStyleFunctions = function()
{
for(var i = 0; i < _styleFunctions.length; i++)
{
var sFunction = _styleFunctions[i];
sFunction();
}
}
var changeToSelectedElement = function(templateIndex, templateList)
{
_templateSelector.children("select").empty();
for(var i = 0; i < templateList.length; i++)
{
_templateSelector.children("select").append($(templateList[i]).clone(true));
}
if(templateIndex === undefined)
{
_templateSelector.find("option").first().trigger("change", [true]);
}
else
{
_templateSelector.find("option").filter(function(){return $(this).data("index") == templateIndex}).first().trigger("change", [true]);
}
return;
}
var createNavButtons = function(buttonDiv)
{
var navButtonHolder = $("
").css("float", "left");
var backForwardFunction = function(e)
{
var template;
if($(e.target).attr("id") == "veBack")
{
template = _templateTracker.previous();
}
else
{
template = _templateTracker.next();
}
if(!template)
{
return;
}
_fileSelector.find("option").filter(function(){return $(this).data("index") == template.fileIndex}).prop("selected", true);
changeToSelectedElement(template.templateIndex, template.list);
}
_backButton = $("").attr("id", "veBack");
_backButton.click(backForwardFunction);
_styleFunctions.push(function(){_backButton.button({icons:{primary:"ui-icon-triangle-1-w"}, text:false, disabled:true})});
_forwardButton = $("").attr("id", "veForwards");
_forwardButton.click(backForwardFunction);
_styleFunctions.push(function(){_forwardButton.button({icons:{primary:"ui-icon-triangle-1-e"}, text:false, disabled:true})});
//Changes the template list to what is currently selected
_currentSelectionButton = $("");
_currentSelectionButton.click(function()
{
_fileSelector.find("option").eq(0).prop("selected", true);
changeToSelectedElement(undefined, _selectedInfoContainers);
var selectedCopy = new Array();
for(var i = 0; i < _selectedInfoContainers.length; i++)
{
selectedCopy[i] = _selectedInfoContainers[i];
}
_templateTracker.push({fileIndex:-1, templateIndex:0, list:selectedCopy});
});
_styleFunctions.push(function(){_currentSelectionButton.button({icons:{primary:"ui-icon-pencil"}, text:false, disabled:true})});
navButtonHolder.append(_backButton);
navButtonHolder.append(_forwardButton);
navButtonHolder.append(_currentSelectionButton);
buttonDiv.append(navButtonHolder);
}
//Create the area where the buttons are stored
var createControlButtons = function(buttonDiv)
{
//Used to enable the selector to get the templates of a particular area of the page
_enableSelectorButton = $("");
_enableSelectorButton.click(function()
{
_enableSelectorButton.button("option", "label", "Select new element");
$("a").click(function(e)
{
e.preventDefault();
});
_debugOn = true;
_pauseSelector = false;
_enableSelectorButton.button("option", "disabled", true);
});
_styleFunctions.push(function(){_enableSelectorButton.button({icons:{primary:"ui-icon-pencil"}})});
//Used to minimise/restore the editor
_closeEditorButton = $("");
_closeEditorButton.click(function()
{
if(_closeEditorButton.button("option", "label") == "Close editor")
{
_closeEditorButton.button("option", "label", "Open editor");
_editingDiv.hide();
}
else
{
_closeEditorButton.button("option", "label", "Close editor");
_editingDiv.show();
}
});
_closeEditorButton.css("float", "right");
_styleFunctions.push(function(){_closeEditorButton.button({icons:{secondary:"ui-icon-newwin"}, disabled:true})});
//Used to save any changes that have been made to this template
_saveButton = $("");
_saveButton.click(function()
{
if(_editor)
{
var xmlString;
if(_isVisualEditor)
{
_vEditor.savePendingEdits();
xmlString = new XMLSerializer().serializeToString(_vEditor.getXML());
}
else
{
xmlString = _editor.getValue();
}
xmlString = xmlString.replace(/&/g, "&");
try
{
var xml = $.parseXML('' + xmlString + "");
}
catch(error)
{
alert("Could not save as there is a problem with the XML.");
return;
}
var url = gs.xsltParams.library_name;
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};
if(_currentName && _currentName.length > 0){parameters["s1.name"] = _currentName;}
if(_currentMatch && _currentMatch.length > 0){parameters["s1.match"] = _currentMatch;}
if(_currentXPath && _currentXPath.length > 0){parameters["s1.xpath"] = _currentXPath}
_saveButton.button("option", "disabled", true);
$.blockUI({message:'
Saving, please wait...
'});
$.post(url, parameters)
.success(function()
{
$.ajax(gs.xsltParams.library_name + "?a=s&sa=c")
.success(function()
{
partialPageReload(function(){$.unblockUI();});
})
.error(function()
{
$.unblockUI();
alert("Error reloading collection.");
})
.complete(function()
{
_saveButton.button("option", "disabled", false);
});
})
.error(function()
{
alert("There was an error sending the request to the server, please try again.");
});
}
});
_styleFunctions.push(function(){_saveButton.button({icons:{primary:"ui-icon-disk"}, disabled:true})});
//Used to switch between the XML and Visual editors
_swapEditorButton = $("");
_swapEditorButton.button().click(function()
{
if(_vEditor && _textEditor)
{
if(_isVisualEditor)
{
_vEditor.savePendingEdits();
_vEditor.getMainDiv().hide();
var containerNode = _vEditor.getXML().firstChild;
var templateNode = containerNode.firstChild;
while(templateNode)
{
if(templateNode.nodeType == 1)
{
break;
}
templateNode = templateNode.nextSibling;
}
var xmlText = new XMLSerializer().serializeToString(templateNode);
_editor.setValue(xmlText);
_editor.clearSelection();
var UndoManager = require("ace/undomanager").UndoManager;
_editor.getSession().setUndoManager(new UndoManager());
_textEditor.show();
_swapEditorButton.button("option", "label", "Switch to visual editor");
_isVisualEditor = false;
_xmlStatusBar.show();
}
else
{
_textEditor.hide();
var xmlText = _editor.getValue();
_vEditor.getMainDiv().remove();
_vEditor = new visualXMLEditor(xmlText);
_editingDiv.append(_vEditor.getMainDiv());
_vEditor.selectRootElement();
_vEditor.getMainDiv().show();
_swapEditorButton.button("option", "label", "Switch to XML editor");
_isVisualEditor = true;
_xmlStatusBar.hide();
}
}
});
_styleFunctions.push(function(){_swapEditorButton.button({icons:{primary:"ui-icon-refresh"}})});
undoButton = $("");
undoButton.click(function()
{
if(_isVisualEditor)
{
_vEditor.undo();
}
else
{
_editor.undo();
}
});
_styleFunctions.push(function(){undoButton.button({icons:{primary:"ui-icon-arrowreturnthick-1-w"}})});
buttonDiv.append(_enableSelectorButton);
buttonDiv.append(_closeEditorButton);
buttonDiv.append(_saveButton);
buttonDiv.append(_swapEditorButton);
buttonDiv.append(undoButton);
}
//Used to monitor the state of the XML in the XML editor and will notify the user if there is an error
var createXMLStatusBar = function(buttonDiv)
{
_xmlStatusBar = $("");
_xmlStatusBar.css("padding", "5px");
_xmlStatusBar.addClass("ui-corner-all");
_styleFunctions.push(function(){_xmlStatusBar.hide();});
//Check the XML for errors every 2 seconds
setInterval(function()
{
if(_editor)
{
var xmlString = _editor.getValue();
try
{
var xml = $.parseXML('' + xmlString + "");
}
catch(error)
{
console.log(error);
_xmlStatusBar.text("XML ERROR! (Mouse over for details)");
_xmlStatusBar.addClass("ui-state-error");
_xmlStatusBar.removeClass("ui-state-active");
_xmlStatusBar.attr("title", error);
_saveButton.button("option", "disabled", true);
_swapEditorButton.button("option", "disabled", true);
return;
}
_xmlStatusBar.text("XML OK!");
_xmlStatusBar.addClass("ui-state-active");
_xmlStatusBar.removeClass("ui-state-error");
_xmlStatusBar.removeAttr("title");
if(_saveButton.button("option", "label") == "Save changes")
{
_saveButton.button("option", "disabled", false);
}
if(_swapEditorButton.button("option", "label") == "Switch to visual editor")
{
_swapEditorButton.button("option", "disabled", false);
}
}
}, 2000);
buttonDiv.append(_xmlStatusBar);
}
//Create the elements that allow
var createFileAndTemplateSelectors = function(buttonDiv)
{
_templateSelector = $("
", {"id":"veTemplateSelector", "class":"ui-state-default ui-corner-all"});
_templateSelector.append($("Templates: "));
var templateSelectBox = $("