/***************************************************************************************** Script to add content to links or elements depending on when they were created v1.0 written by Mark Wilton-Jones, 07/09/2005 ****************************************************************************************** Please see http://www.howtocreate.co.uk/jslibs/ for details and a demo of this script Please see http://www.howtocreate.co.uk/tutorials/jsexamples/importingXML.html for a demo and description Please see http://www.howtocreate.co.uk/jslibs/termsOfUse.html for terms of use _________________________________________________________________________ This script can insert text or HTML inside or beside any element, depending on when the element was created. A typical use of this would be to show "New" beside links that were created within the last few days. To use this, insert the following into the head of your document: <script src="PATH TO SCRIPT/addDateText.js" type="text/javascript"></script> This header file provides one function, which can be called as many times as required, after the document has loaded: addDateText( number: startingAge, number: endingAge, mixed: elements, number: position, mixed: newContent[, optional node: documentRef[, optional string: timeZone] ); startingAge = number of days old before starting to add content endingAge = number of days old after which content should not be added elements = any of; 1. an element name string (eg. 'a') - all elements of this tag name will be tested 2. a NodeList (such as would be returned by getElementsByTagName) 3. an array of element references (eg. [document.body,document.links[1],document.forms[0]]) position = where the new content should be added: 0 = immediately before the element 1 = immediately inside the start of the element 2 = immediately before the end of the element 3 = immediately after the element newContent = either a string of new text content (not HTML), or a DOM node that will be automatically cloned - you can also use DocumentFragments, but note that they are not supported in Internet Explorer 5.x Win/Mac documentRef = reference to the document object of the target page - this will be used for both the element referencing, and for the text node creation - note that these must be in the same document - defaults to the current document (you can also use null for default) timeZone = extra information to add to the end of the titles when generating the dates (such as 'GMT+0200') - the dates are normally calculated using either the user's own local date, or GMT/UTC (this depends on the browser) - you can use this string to force all dates to be interpreted relative to a specific timezone _________________________________________________________________________ Examples: <script type="text/javascript"> window.onload = function () { addDateText(0,5,'a',0,'New '); addDateText(5,10,'li',2,'Not so new ',null,'GMT+0200'); if( !document.childNodes || !document.createElement || !document.createTextNode ) { return; } var foo = document.createElement('img'); foo.setAttribute('src','new.png'); foo.setAttribute('alt','New'); addDateText(0,5,'a',0,foo); addDateText(0,5,parent.document.getElementsByTagName('p'),0,'New ',parent.document); }; </script> Warning: some browsers will (correctly) throw an error if you try to add content where it is not allowed (for example; if your new content contains a div, and you try to put it inside a span). If this happens, this script will display an alert saying that you have violated the DOM rules - and it will try to be helpful with its error reporting (no promises). Test in multiple browsers, because they each have their own sensitivities about what invalid structures they will allow. Better still, only add content where it is allowed! _________________________________________________________________________ To tell the script when the elements were 'created', add the title attribute to the elements. The title may contain a few words (not containing numbers), followed by a date, which must start with a number, must contain the year written in 4 digit format, and must contain the month written in either full or 3 character English month names. The date may optionally contain a time as well, and a timezone offset (if the time is important). It is easier to set the timezone using the timeZone parameter. Browsers all have different responses to date formats, so test in multiple browsers to see that they all accept the format you are using. The following will all work: <a title="Added 7 Sep 2005"> <a title="Last updated; 7 September, 2005"> <a title="Created 7 Sep 2005 09:17:23 GMT+0100"> The date is processed using the JavaScript engine's inbuild date parser, so sorry about the month names and enforced structure, it is out of my control. In browsers that are not capable of running the script, the title will display as a tooltip instead, leaving an accessible alternative (note that this does not apply in Netscape 4, it does not understand titles). If the script encounters a title that it cannot convert into a date, it will silently ignore it, and continue to the next element in the list. _______________________________________________________________________________________*/ function addDateText() { if( !document.childNodes || !document.createElement || !document.createTextNode ) { return; } var dateRightNow = ( new Date() ).getTime(), j = []; //copy the arguments so the original can be used in error reporting for( var i = 0; i < arguments.length; i++ ) { j[j.length] = arguments[i]; } //get the timestamps that the element's date must fall between j[0] = dateRightNow - ( j[0] * 86400000 ); j[1] = dateRightNow - ( j[1] * 86400000 ); //the number checks prevent a problem with setTimeout passing an error correction value in Mozilla (just in case you use setTimeout) if( !j[5] || ( typeof(j[5]) == typeof(0) ) ) { j[5] = document; } if( !j[6] || ( typeof(j[6]) == typeof(0) ) ) { j[6] = ''; } if( typeof(j[2]) == 'string' ) { j[2] = j[5].getElementsByTagName(j[2]); } if( typeof(j[4]) == 'string' ) { j[4] = j[5].createTextNode(j[4]); } for( var n = 0, m, ttl, oPar, oNode; n < j[2].length; n++ ) { m = j[2][n]; ttl = m.getAttribute('title'); //check each element to see if it has a relevant title (looks for a 4 digit year) if( !ttl || !ttl.match(/\b\d{4}\b/) ) { continue; } var elDate = ( new Date( ttl.replace(/^\D*/,'') + j[6] ) ).getTime(); if( !isNaN(elDate) && ( j[0] >= elDate ) && ( j[1] < elDate ) ) { //this date is within the required range, check where to put the extra node oPar = m.parentNode; oNode = j[4].cloneNode(true); try { switch(j[3]) { case 3: //after - can't correctly use insertBefore at the end because of an IE Mac bug if( m == oPar.lastChild ) { oPar.appendChild(oNode); } else { oPar.insertBefore(oNode,m.nextSibling); } break; case 2: //end m.appendChild(oNode); break; case 1: //start - can't correctly use insertBefore at the end because of an IE Mac bug if( m.childNodes.length ) { m.insertBefore(oNode,m.firstChild); } else { m.appendChild(oNode); } break; default: //before oPar.insertBefore(oNode,m); } } catch(e) { if( !window.hasWarnedInvalOnce ) { window.hasWarnedInvalOnce = true; alert( 'addDateText script was asked to add a node where it was not allowed:\n\n' + arguments.join() ); } } } } }