/******************************************************************************
**
* FILE: 	sitemenu.js
* PRODUCT:	website
* AUTHOR: 	Ingo Karkat <ingo@karkat.de>
* DATE CREATED:	01-Jan-2008
*
*******************************************************************************
* CONTENTS: 
*
* REMARKS: 
*
* REVISION	DATE		REMARKS 
*	004	22-Feb-2008	Implemented menu messages that indicate the
*				fetching of the sitemenu and possible failures. 
*				Menu messages can be localized via a passed
*				message catalog. 
*	003	09-Feb-2008	Implemented fixRelativeLinksInHtml() to be used
*				as a preprocessing hook, because the
*				postprocessing done by fixRelativeLinksInDom()
*				doesn't work in IE6 and IE7. 
*	002	05-Jan-2008	Implemented fixRelativeLinks() via DOM. 
*	001	01-Jan-2008	file creation
******************************************************************************/

function installSiteMenu(elementId, menuUrl, menuMessageTemplate, messageCatalog, preprocessing, postprocessing) {
    function menuMessage(message, details) {
	$(elementId).update(menuMessageTemplate.interpolate({ message: message, menuUrl: menuUrl, messageDetails: details }));
    }

    function _(internationalString) {
	if (messageCatalog && messageCatalog[internationalString]) {
	    return messageCatalog[internationalString];
	} else {
	    return internationalString;
	}
    }

    menuMessage(_("Fetching sitemenu... "));
    $(elementId).show();

    // new Ajax.Updater(elementId, menuUrl, { method: 'get' });
    new Ajax.Request(menuUrl, {
	method: 'get', 
	onSuccess: function(response) {
	    var menuPage = response.responseText;
	    if (preprocessing) menuPage = preprocessing(menuPage);
	    var menuBody = menuPage.replace(new RegExp('^[\\S\\s]*<body[^>]*>([\\S\\s]*?)<\/body>[\\S\\s]*$', 'ig'), '$1');
	    // alert(menuBody);
	    $(elementId).update(menuBody);
	    if (postprocessing) postprocessing();
	}, 
	on404: function(response) {
	    menuMessage(_("No sitemenu available. "));
	    window.setTimeout(function() { $(elementId).hide(); }, 10000);
	}, 
	onFailure: function(response) {
	    menuMessage(_("Failed to fetch sitemenu. "),  response.status + ": " + response.statusText);
	}
    });
}

function isRelativeHref(href) {
    // Relative hypertext references do not have a protocol and do not
    // start with '/', '#' (local anchor), '?' (local CGI parameter). 
    return href !== null && ! new RegExp("^[^:/#?.]+:(?://)?.|^[/#?]").test(href);
}

function fixRelativeLinksInHtml(html) {
    return html.replace(/\b(href|src)=(["']?)(.*?)\2(?=\s|>|\/>)/ig, function(match, s1, s2, s3) {
	if (isRelativeHref(s3)) {
	    return s1 + '=' + s2 + '/' + s3.replace(/^\.\//,'') + s2;
	} else {
	    return match;
	}
    });
}

function fixRelativeLinksInDom(elementId) {
    function fixRelativeLink(menuLink) {
	['href', 'src'].each(function(linkAttribute) {
	    var linkTarget = menuLink.getAttribute(linkAttribute);
	    if (isRelativeHref(linkTarget)) {
		menuLink.setAttribute(linkAttribute, '/' + linkTarget.replace(/^\.\//,''));
	    }
	});
    }

    var menuLinks = $A($(elementId).getElementsByTagName('*'));
    menuLinks.each(fixRelativeLink);
}


