Post by Bob on Sept 26, 2010 4:40:35 GMT -8
Display Name History
This script stores your member's display names as they change them. And then when you view their profile an additional section at the bottom is included which displays their recent display names. Most everything in this script is modifiable; from the number of names to remember to the max length of each history entry to the standard boilerplate text that this script puts on your forum.
Modifying
The script posted below is ready to go without any modifications. And it is recommended that unless you want to tinker around with settings, you just use the script as-is. But should you change anything be sure to read the comment blocks. A comment block looks like the following:
/**
* This is a comment block.
* It commonly spans many lines.
* Read what's inside it before editing what is below it.
*/
All modifiable variables are declared at the top of the script. Specifically, everything above the comment line that states Do not touch anything below this line. Everything above that line is safe to be modified suggesting you keep in mind what I've stated in the comments.
Compatibility
This script has been tested against all major layout engines (Trident, Gecko, Presto and Webkit). Specifically, the following browsers have been vetted:
- Firefox 3.6
- Chrome 6.0
- Opera 10.53
- Internet Explorer 9
- Internet Explorer 8*
- Internet Explorer 7*
- Internet Explorer 6
- Internet Explorer 8*
* These engines were tested with IE9's compatibility view. I'm not 100% positive how accurate that may be.
The Script (Global Footer) - Pastebin Copy
<script type="text/javascript">
// <![CDATA[
/**
* Display Name History - Global Footer
*
* Written by Bobby Hensley
*
* The script may be redistributed and modified so long as this original
* header remains in tact at all times. The author of this script does not
* endorse or promote any modifications that may be made.
*/
function DisplayNameHistory ()
{
/**
* The below are some standard labels that you can expect to find being
* outputted.
*
* this.historyTitle is the title of the profile field we create.
*
* this.noHistoryFound is the text displayed if there exists no display
* name history for the viewed user.
*/
this.historyTitle = "Display Name History";
this.noHistoryFound = "No display name history found for this user.";
/**
* You have 150 characters total for the location field. Remember that 30
* of those characters belong to your member. And this script automatically
* uses up a total of ten on its own. Thus the remaining 110 can be used by
* the following variables. Factor in the size of your seperator and how it
* will be present (rememberNum - 1) times.
*
* With factory settings the amount of characters used looks like this:
* - Remember: 5 at a max of 18 characters per name (90 characters)
* - Seperator is 5 characters and will occur 4 times. (20 characters)
* - Total: 110 characters of 110 possible characters used.
*/
this.rememberNum = 5;
this.maxLength = 18;
this.seperator = "[{D}]";
/**
* Do not touch anything below this line unless you're sure of what you're
* doing. Even then, think again.
*/
this.dnHistory = new Array ();
this.dnString = "";
this.curName = "";
this.dnPattern = /(\[DNH:.+?\/DNH\])/g;
this.dnStart = "[DNH:";
this.dnEnd = "/DNH]";
this.font = document.createElement ("font");
this.strong = document.createElement ("strong");
this.li = document.createElement ("li");
}
DisplayNameHistory.prototype = {
/**
* Reads the location field for the DNH pattern. If it's found it's saved to
* dnString and then removed from the profile field. The display name is also
* saved for later comparison and the profile save button is rigged.
*
* return void
*/
prepare: function ()
{
this.curName = pb_displayname;
this.dnString = document.modifyForm.location.value.match (this.dnPattern) ? RegExp.$1 : "";
document.modifyForm.location.value = document.modifyForm.location.value.replace (this.dnString, "");
document.modifyForm.onsubmit = function ()
{
dnh.save ();
}
},
/**
* Handles all leg work necessary to build the client end of the viewprofile
* action. Creates the necessary rows in the table, applies the text, create
* the history output, etc.
*
* return void
*/
buildProfile: function ()
{
var profTable = document.getElementsByTagName ("table");
for (var i = 0, len = profTable.length; i < len; i++)
{
if (profTable.cellPadding == "4" && profTable.rows[0].cells[0].innerHTML.match (/Member's Bio/))
{
// Parse the location field of the table for pertinent data
var history = this.parseLocation (profTable);
// Build the heading.
var nRow = profTable.insertRow (profTable.rows.length);
var nCell = nRow.insertCell (0); nCell.colSpan = 2;
var heading = this.pbText (this.historyTitle, 2, true);
var hr = document.createElement ("hr"); hr.size = 1;
nCell.appendChild (heading);
nCell.appendChild (hr);
// Now build the output
var nRow = profTable.insertRow (profTable.rows.length);
var nCell = nRow.insertCell (0); nCell.colSpan = 2;
if (history)
{
var histList = document.createElement ("ol");
for (var i = 0, len = this.dnHistory.length; i < len; i++)
{
var li = this.li.cloneNode (false);
li.appendChild (this.pbText (this.dnHistory, 2, false));
histList.appendChild (li);
}
nCell.appendChild (histList);
}
else
{
var noHistory = this.pbText (this.noHistoryFound, 2, false);
nCell.appendChild (noHistory);
}
}
}
},
/**
* Remove all occurences of the DNH pattern from the document.
*
* return void
*/
clean: function ()
{
document.body.innerHTML = document.body.innerHTML.replace (this.dnPattern, "");
},
/**
* This method's only job is to build the new location field string. If the
* display name has changed and hasn't been changed to something stupid such
* nothing, then it builds the DNH pattern based on the new display name and
* contents of the dnHistory array. The result is then saved to the form.
*
* return void
*/
save: function ()
{
this.load ();
// Don't need people faking DNH data
this.curName = this.curName.replace (this.dnStart, "").replace (this.dnEnd, "");
document.modifyForm.name.value = document.modifyForm.name.value.replace (this.dnStart, "").replace (this.dnEnd, "");
var name = document.modifyForm.name.value;
var locString = document.modifyForm.location.value;
// Shut Opera up when saving the profile form
document.modifyForm.location.setAttribute ("maxlength", 150);
if (name != this.curName && name != "" && this.curName != "")
{
var friendlyName = this.formatName (this.curName);
locString += this.dnStart + friendlyName + this.seperator;
for (var i = 0, len = this.dnHistory.length; i < len; i++)
{
locString += this.dnHistory + this.seperator;
}
locString += this.dnEnd;
locString = locString.replace (this.seperator + this.dnEnd, this.dnEnd);
}
else
{
locString += this.dnString;
}
document.modifyForm.location.value = locString;
},
/**
* Read the given location field from the viewprofile action and delegate
* it to the appropriate property and method.
*
* param HTMLTableElement Profile table
* return bool True if pattern found
*/
parseLocation: function (profTable)
{
for (var i = 0, len = profTable.rows.length; i < len; i++)
{
if (profTable.rows.cells[0].innerHTML.match (/Location:/))
{
if (profTable.rows.cells[1].innerHTML.match (this.dnPattern))
{
this.dnString = RegExp.$1;
this.load (null);
return true;
}
break;
}
}
return false;
},
/**
* Cleans and splits the dnString property. The split names are then
* saved to the dnHistory property in array format. If this method
* is given an argument then it will bypass the length check on
* dnHistory; by default dnHistory is popped down to (rememberNum - 1).
*
* param null
* return void
*/
load: function ()
{
if (this.dnString.length == 0)
{
return null;
}
var names = this.dnString.replace (this.dnStart, "").replace (this.dnEnd, "");
var dnSplit = names.split (this.seperator);
this.dnHistory = dnSplit;
if (arguments.length == 0)
{
while (this.dnHistory.length >= this.rememberNum)
{
this.dnHistory.pop ();
}
}
},
/**
* Check the length of the given name. If it's longer than the maxLength
* property says it should be: shorten it and toss ellipsis onto it.
* Otherwise just return the given name.
*
* param string Name to be checked.
* return string Properly formatted name.
*/
formatName: function (name)
{
if (name.length > this.maxLength)
{
var newName = name.substring (0, (this.maxLength - 3));
newName += "...";
return newName;
}
return name;
},
/**
* Simple helper method used to quickly create a document fragment containing
* the given text. The text node is created, font element copied and given
* the specified size, and bold text is supported through a boolean parameter.
*
* param string String content of the text node.
* param int Size of the font element.
* param bool Bold element to be applied?
* return void
*/
pbText: function (text, fSize, isBold)
{
var font = this.font.cloneNode (false);
var text = document.createTextNode (text);
font.size = fSize;
if (isBold === true)
{
var bold = this.strong.cloneNode (true);
bold.appendChild (text);
font.appendChild (bold);
}
else
{
font.appendChild (text);
}
var docFrag = document.createDocumentFragment ();
docFrag.appendChild (font);
return docFrag;
}
};
var dnh = new DisplayNameHistory ();
switch (pb_action)
{
case "modifyprofile":
dnh.prepare ();
break;
case "viewprofile":
dnh.buildProfile ();
dnh.clean ();
break;
case "display" :
dnh.clean ();
break;
case "pmview" :
dnh.clean ();
break;
}
// ]]>
</script>