- /
setup: function
{
if(this.isEditPage)
{
if(this.loadVisible && this.isSupportedPage)
{
this.load;
}  
this.setupButton;
}
},  
/**
- Loads dependencies and creates GUI
- /
load: function
{
$(function
{
var dependencies = ['jquery.ui', 'jquery.textSelection'];
var preference = proveit.getDatePreference;  
proveit.dateFormatter = new proveit.DateFormatter(preference);  
mw.loader.using(dependencies, function
{
try
{
proveit.createGUI;
if(proveit.loadMaximized)
{
proveit.toggleViewAddVisibility;
}
}
catch(ex)
{
proveit.logException(ex);
}
}, function(ex, errorDependencies)
{
proveit.log('Failed to load one of: ', errorDependencies);
});
});
},  
/**
- Clears the refBox of refBoxRows, except for dummy rows.
- @return {Boolean} false if refBox wasn't found
- /  
clearRefBox: function
{
var box = this.getRefBox;
if(box == null)
{
this.log("Ref box is not loaded yet.");
return false;
}
$("tr:not('tr#dummyRef')", box).remove;
return true;
},  
/** Inserts ref text into MW edit box.
- @param {String} ref Reference text to insert
- @param {Boolean} full Insert the full reference text if true, citation otherwise.
- @return {Boolean} false if errors
- /
insertRefIntoMWEditBox: function(ref, full)
{
var txtarea = this.getMWEditBox;
if(!txtarea)
{
this.log("insertRefIntoMWEditBox: txtarea is null");
return false;
}
txtarea = $(txtarea);
var insertionText = ref.getInsertionText(full);
// Replace existing selection (if any), then scroll
txtarea.textSelection('encapsulateSelection',
{
peri: insertionText,
replace: true
});
var caretPos = txtarea.textSelection('getCaretPosition', {startAndEnd: true});  
// This is slightly redundant. It is called primarily for the scrollig workaround
this.highlightLengthAtIndex(caretPos[0], caretPos[1] - caretPos[0]);  
this.includeProveItEditSummary;
},  
/**
- Modifies reference object from user-edited GUI. The reference object is mutated in place, so the return value is only for convenience.
-
- @param {Node} editPane the raw element of the editPane
- @param {AbstractReference} ref the original citation object we're modifying
-
- @return {AbstractReference} same ref that was passed in
- /
changeRefFromEditPane: function(ref, editPane)
{
var paramBoxes = $("div.input-row", editPane);  
var refName = $('#editrefname').val;
ref.name = refName != "" ? refName : null; // Save blank names as null  
// Clear old params
ref.params = {};  
var paramName, paramVal;
for (var i = 0; i < paramBoxes.length; i++)
{
var paramRow = paramBoxes[i];
var valueTextbox = $(".paramvalue", paramRow)[0];
if($(paramRow).hasClass("addedrow")) // Added with "Add another field"
{
paramName = $.trim($(".paramdesc", paramRow)[0].value);
}
else
{
paramName = valueTextbox.id.substring(this.EDIT_PARAM_PREFIX.length);
}
this.log("paramName: " + paramName);
paramVal = $.trim(valueTextbox.value);  
this.log("paramVal: " + paramVal);  
if (paramName != "" && paramVal != "")
{
ref.params[paramName] = paramVal;
}
}
if (ref.toString != ref.orig)
{
ref.save = false;
}
ref.update;
return ref;
},  
/**
- Creates refBoxRow, updates numbering for all refBoxRows, replaces old refBoxRow with new one, and updates ref text in MWEditBox.
- @param {AbstractReference} ref the ref we want to save.
- /
saveRefFromEdit: function(ref)
{
if(!ref.save)
{
var newRichItem = this.makeRefBoxRow(ref, true);
var oldRichItem = $('.selected', this.getRefBox).get(0);
var oldNumber = $('td.number',oldRichItem).text;
$('td.number',newRichItem).text(oldNumber); // preserve old numbering
oldRichItem.parentNode.replaceChild(newRichItem, oldRichItem);
$(newRichItem).addClass('selected');  
ref.updateInText;
this.includeProveItEditSummary;
}
},  
/**
- Updates the edit pane when you choose a reference to edit.
- @param {AbstractReference} ref the ref that was chosen.
- /
updateEditPane: function(ref)
{
$('#editrefname').val(ref.name || "");  
// Don't contaminate actual object with junk params.
var tempParams = {};
for(var param in ref.params)
{
tempParams[param] = ref.params[param];
}  
// Add default params with blank values.
var defaults = ref.getDefaultParams;
for(var i = 0; i < defaults.length; i++)
{
if(!tempParams[defaults[i]])
{
tempParams[defaults[i]] = "";
}
}  
var required = ref.getRequiredParams;  
var paramNames = new Array;  
for(var item in tempParams) //First run through just to get names.
{
paramNames.push(item);
}  
var sorter = ref.getSorter;
if(sorter)
{
paramNames.sort(sorter);
}
else
{
paramNames.sort;
}
/* Sort them to provide consistent interface. Uses custom sort order (which is easily tweaked)
where possible.  
Javascript does destructive sorting, which in this case, is convenient...
- /  
$('#edit-fields').children('.paramlist').children.remove('div:not(.hidden)'); // clear all fields in the edit box (except the hidden ones)  
for(var j = 0; j < paramNames.length; j++)
{
this.addPaneRow($("#edit-pane").get, tempParams, this.getDescriptions, paramNames[j], required[paramNames[j]], true);
}  
var acceptButton = $('#edit-buttons .accept');
var acceptEdit = function
{
proveit.changeRefFromEditPane(ref, $("#edit-pane").get);
proveit.saveRefFromEdit(ref);
$("#edit-pane").hide;
$("#view-pane").show;
};  
// Without setTimeout, scoll reset doesn't work in Firefox.
setTimeout(function
{
// Reset scroll
$('#edit-fields').scrollTop(0);
}, 0);  
acceptButton.off('click.proveit').on('click.proveit', acceptEdit);
},  
/**
- Add a row to an editPane or addPane.
- @param {Node} root root element for pane
- @param {Object} params the param object from the reference, or null for added rows.
- @param {Object} descs description object to use, or null for no description
- @param {String} item the current param name
- @param {Boolean} req true if current param name is required, otherwise not required.
- @param {Boolean} fieldType true for label, false for textbox.
- /
addPaneRow: function(root, params, descs, item, req, fieldType)
{
var id = fieldType ? "preloadedparamrow" : "addedparamrow";
var newline = $('#'+id).clone; // clone the hidden row
$(newline).attr('id',''); // clear the ID (can't have two elements with same ID)
//this.activateRemoveField(newline);
var paramName = $('.paramdesc', newline).eq(0);
var paramValue = $('.paramvalue', newline).eq(0);  
$('.paramlist', root).append(newline);  
if(req) // if field is required...
{
$(paramName).addClass('required'); // visual indicator that label is required
$('.delete-field', newline).remove; // don't let people remove required fields
}
else
{
this.activateRemoveField(newline);
}  
if(fieldType) // the description/name is a label (not a textbox)
{
paramName.attr("for", this.EDIT_PARAM_PREFIX + item);
paramValue.attr('id',this.EDIT_PARAM_PREFIX + item);  
var desc = descs[item];
if(!desc)
{
this.log("Undefined description for param: " + item + ". Using directly as description.");
desc = item;
}
$(paramName).text(desc);
$(paramName).attr('title',item);
$(paramValue).val(params[item]);  
$(newline).show;
}
else
{
// added a new row, so make it fancy
$(newline).show('highlight',{},'slow');
$('.inputs', root).scrollTop(100000);
}
},  
/*
- these are the current style and insert values to denote which one is
- currently active
- /  
/**
- true signifies cite-style references, citation-style otherwise. Used when creating a reference.
- @type Boolean
- /
togglestyle: true,  
// TODO: This should be eliminated if only name only inserts are allowed.
/** true signifies full references, name-only otherwise. Used when inserting.
- Note that new references are always inserted in full.
-
- @type Boolean
- /
toggleinsert: false,  
/* Cross-Browser Split 1.0.1
(c) Steven Levithan <stevenlevithan.com>; MIT License
http://blog.stevenlevithan.com/archives/cross-browser-split
An ECMA-compliant, uniform cross-browser split method
- /
/**
- Cross-browser implementation of ECMAScript String.prototype.split function.
-
- @param {String} str input string to split
- @param separator separator to split on, as RegExp or String