/****************
 * sitepoint-ref-links.js
 * ------------------
 * Add links to words marked up using the <code> tag to the SitePoint Reference
 * Supports HTML elements, HTML tags, HTML core attributes, CSS properties and Microformats.
 * ------------------
 * Copyright (c) 2008 SitePoint Pty. Ltd. http://www.sitepoint.com/
 *
 * Uses Simon Willison's addLoadEvent - http://simonwillison.net/2004/May/26/addLoadEvent/
 * Version 1.0, May 2008: Matthew Magain mjm@sitepoint.com
 */

var RefLinks =
{
	init: function()
	{
		// Element must be marked up with <code>
		var all_code_elements = document.getElementsByTagName('code');
		for (var j=0; j < all_code_elements.length; j++) 
		{
			if(/sitepoint-ref-link-ignore/i.test(all_code_elements[j].className) == false)
			{
				if(all_code_elements[j].firstChild && all_code_elements[j].firstChild.nodeValue)
				{
				if (RefLinks.IsHTMLElement(all_code_elements[j].firstChild.nodeValue)) {
				RefLinks.InsertAnchor('html', all_code_elements[j], 'element');
				} else if (RefLinks.IsMicroformat(all_code_elements[j].firstChild.nodeValue)) {
				RefLinks.InsertAnchor('html', all_code_elements[j], 'microformat');		
				} else if (RefLinks.IsHTMLTag(RefLinks.StripHyphensAndBrackets(all_code_elements[j].firstChild.nodeValue))) {
				RefLinks.InsertAnchor('html', all_code_elements[j], 'tag');
				} else if (RefLinks.IsHTMLCoreAttribute(all_code_elements[j].firstChild.nodeValue)) {
				RefLinks.InsertAnchor('html', all_code_elements[j], 'attribute');
				} else if (RefLinks.IsCSSProperty(all_code_elements[j].firstChild.nodeValue)) {
				RefLinks.InsertAnchor('css', all_code_elements[j], 'property');
				} else if (RefLinks.IsNonStandardCSSProperty(RefLinks.StripHyphensAndBrackets(all_code_elements[j].firstChild.nodeValue))) {
				RefLinks.InsertAnchor('css', all_code_elements[j], 'property');
				}
			}
		}
			
		}
	},

	// Replace current text with appropriate link to the SitePoint Reference
	InsertAnchor: function(sLanguage, aNode, sType) 
	{
		var refURL='http://reference.sitepoint.com/' + sLanguage + '/';
	if (sType == 'attribute') 
		refURL += 'core-attributes/';
		var aLink = document.createElement('a');
		aLink.href = refURL + RefLinks.StripHyphensAndBrackets(aNode.firstChild.nodeValue.toLowerCase());
	aLink.title = 'Look up the ' + aNode.firstChild.nodeValue + ' ' + sType 
		+ ' in the SitePoint ' + sLanguage.toUpperCase() + ' Reference.';
		var aTextNode = document.createTextNode(aNode.firstChild.nodeValue);
		aLink.appendChild(aTextNode);
	aNode.removeChild(aNode.firstChild);
		aNode.appendChild(aLink);
		aNode.className = "ref-term"; // Blow away any existing classes. A little heavy-handed, perhaps.
	},
	
	// Checks whether the keyword matches an HTML Element
	IsHTMLElement: function(aString) 
	{
		// font tag is missing; the CSS font property gets precedence
		var htmlElements = ['blockquote', 'cite', 'body', 'br', 'center', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'p', 'base', 'link', 'meta', 'script', 'style', 'title', 'dd', 'dir', 'dl', 'dt', 'li', 'menu', 'ol', 'ul', 'a', 'abbr', 'acronym', 'address', 'b', 'basefont', 'bdo', 'big', 'blink', 'code', 'comment', 'del', 'dfn', 'em', 'i', 'ins', 'kbd', 'marquee', 'nobr', 'noscript', 'plaintext', 'pre', 'q', 'rb', 'rbc', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'tt', 'u', 'var', 'wbr', 'xmp', 'button', 'fieldset', 'form', 'input', 'isindex', 'label', 'legend', 'optgroup', 'option', 'select', 'textarea', 'applet', 'area', 'bgsound', 'embed', 'img', 'map', 'noembed', 'object', 'param', 'caption', 'col', 'colgroup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'frame', 'frameset', 'noframes', 'iframe']; 
	for (var i=0; i < htmlElements.length; i++) {
		if (aString == htmlElements[i])
					return true;
	}
	return false;	
	},

	// Checks whether the keyword matches an HTML element, 
	// once the angle brackets are stripped out
	IsHTMLTag: function(aString) 
	{
		return RefLinks.StripHyphensAndBrackets(RefLinks.IsHTMLElement(aString));
	},
	
	// Checks whether the keyword matches an HTML core attribute
	IsHTMLCoreAttribute: function(aString) 
	{
		var htmlCoreAttributes = ['id', 'class', 'dir', 'lang', 'style'];
	for (var i=0; i < htmlCoreAttributes.length; i++) {
		if (aString == htmlCoreAttributes[i])
					return true;
	}
	return false;	
	},
	
	// Checks whether the keyword matches a CSS property
	IsCSSProperty: function(aString) 
	{
		var cssProperties = ['height', 'min-height', 'max-height', 'width', 'min-width', 'max-width', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'margin', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left', 'padding', 'border-top-color', 'border-top-style', 'border-top-width', 'border-top', 'border-right-color', 'border-right-style', 'border-right-width' ,'border-right', 'border-bottom-color', 'border-bottom-style', 'border-bottom-width', 'border-bottom', 'border-left-color', 'border-left-style', 'border-left-width', 'border-left', 'border-color', 'border-style', 'border-width', 'border', 'outline-color', 'outline-style', 'outline-width', 'outline', 'display', 'position', 'float', 'clear', 'visibility', 'top', 'right', 'bottom', 'left', 'z-index', 'overflow', 'clip', 'list-style-type', 'list-style-position', 'list-style-image', 'list-style', 'table-layout', 'border-collapse', 'border-spacing', 'empty-cells', 'caption-side', 'background-color', 'background-image', 'background-repeat', 'background-position', 'background-attachment', 'background', 'color', 'font-family', 'font-size', 'font-weight', 'font-style', 'font-variant', 'font', 'letter-spacing', 'word-spacing', 'line-height', 'text-align', 'text-decoration', 'text-indent', 'text-transform', 'text-shadow', 'vertical-align', 'white-space', 'direction', 'unicode-bidi', 'content', 'counter-increment', 'counter-reset', 'quotes', 'cursor', 'page-break-before', 'page-break-inside', 'page-break-after', 'orphans', 'widows', 'zoom', 'filter', 'behavior', 'expression',];
	for (var i=0; i < cssProperties.length; i++) {
		if (aString == cssProperties[i])
					return true;
	}
	return false;
	},

	// Checks whether the keyword matches a CSS property
	IsNonStandardCSSProperty: function(aString) 
	{
		var nonStandardCSSProperties = ['moz-border-radius', 'moz-box-sizing'];
	for (var i=0; i < nonStandardCSSProperties.length; i++) {
		if (aString == nonStandardCSSProperties[i])
					return true;
	}
	return false;
	},
	
	// Checks whether the keyword matches one of the microformats listed on the SitePoint Reference	
	IsMicroformat: function(aString)
	{
		var microformats = ['hCalendar', 'hCard', 'hReview'];
	for (var i=0; i < microformats.length; i++) {
		if (aString == microformats[i])
					return true;
	}
	return false;
	},

	// Convert a tag to its corresponding HTML element
	// e.g. <ul> becomes ul.
	StripHyphensAndBrackets: function(aString)
	{
		var resultString = aString;
		var pattern1 = /\<*\>/;
	var pattern2 = /^-/;
		if (pattern1.test(aString))
		{
		resultString = aString.substring(1, aString.length-1);
		} else if (pattern2.test(aString))
		{
		resultString = aString.substring(1, aString.length);
		}
	return resultString;
	}
};

// addLoadEvent is already added by another script, so we remove it 
// here to prevent it from being added again.
/* function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload = function() {
			if (oldonload) {
				oldonload();
			}
			func();
		}
	}
} */

addLoadEvent(RefLinks.init); 